2

I am looking for an equation for a basic version of the bresenham line algorithm that would allow me to calculate the position of the Y value if the X value is known.

The X is always positive and always larger then the Y. The loop just adds 1 to the X until the end is reached.

Here is my code:

int err = (Y << 1) - X;
for(i=0; i<=X; i++)
{
    if(err > 0)
    {
        step++;
        err = (err - (X << 1)) + (Y << 1);
    }
    else
    {
        err = err + (Y << 1);
    }
    printf("X=%d  Y=%d\n", i, step);
}

What I am looking for is a way to figure out what the value of step(Y axis) is at a specific X value with out running the algorithm and with only integer math.

The reason for this is that I have a system that I can pause, but only returns the current X value (Not the Y) and I need to figure out the Y value when this happens.

Dave

Dave3891
  • 63
  • 1
  • 3

1 Answers1

0

I'm assuming that step is initially 0. From your code, we can derive inductively the equation

step * (X << 1) + err - (i + 1) * (Y << 1) == (Y << 1) - X,

which applies at the time of the printf statement. Solve for step.

step == ((Y << 1) - X + (i + 1) * (Y << 1) - err) / (X << 1)

The division here is exact. Since X > Y, we know inductively that -err is between -(Y << 1) inclusive and (X << 1) - (Y << 1) exclusive, so we should add the maximum of that range and let floor division do its thing.

step == ((Y << 1) - X + (i + 1) * (Y << 1) + (X << 1) - (Y << 1) - 1) / (X << 1),

or, simplifying,

step == ((i + 1) * (Y << 1) + X - 1) / (X << 1).

We can get an equation for err as well.

((Y << 1) - X + (i + 1) * (Y << 1) - err) % (X << 1) == 0
err ==   ((Y << 1) - X + (i + 1) * (Y << 1) + (X << 1) - (Y << 1) - 1) % (X << 1)
       - (X << 1) + (Y << 1) + 1
err == ((i + 1) * (Y << 1) + X - 1) % (X << 1) - (X << 1) + (Y << 1) + 1
David Eisenstat
  • 64,237
  • 7
  • 60
  • 120
  • step == ((i + 1) * (Y << 1) + X - 1) / (X << 1) Works perfect. Thanks – Dave3891 Aug 25 '14 at 16:21
  • Can you explain how you got the first equation? – Nico Schertler Aug 25 '14 at 16:53
  • @NicoSchertler It might be easier to see it as `err - ((Y << 1) - X) == step * -(X << 1) + (i + 1) * (Y << 1)`. The left-hand side is the difference between `err` and its initial value. The first term of the right-hand side accounts for the decreases by `X << 1`. The second term of the right-hand side accounts for the increases by `Y << 1`. (The body of the loop could be refactored as `if (err > 0) { step++; err -= X << 1; } step += Y << 1;` .) – David Eisenstat Aug 25 '14 at 17:00
  • One more question. Is it possible to do without the divide? My processor has a hardware 32bit multiply, but no divide... Just wanted to see if it could be optimized a little. – Dave3891 Aug 25 '14 at 17:12
  • @user3641850 How often do `X` and `Y` change? – David Eisenstat Aug 25 '14 at 17:22
  • Each block will have a life of around a half second. The formula will have to update the Step value around 100Hz to get the step position based on the X count. I hope this makes sense – Dave3891 Aug 25 '14 at 17:35
  • @user3641850 In that case, you might be able to get away with computing the constants for [reciprocal multiplication](http://homepage.cs.uiowa.edu/~jones/bcd/divide.html) every half second for a more efficient divide operation at a finer timestep. – David Eisenstat Aug 25 '14 at 17:40