0

Let say we have (x1,y1) and (x2,y2) which might be faraway

Can we calculate the point in line that has N distance from (x1,y1)?

My simple idea is add count in for loop but this will be expensive if distance is very large

*note: floating point can't be use

3 Answers3

0

A = (x1, y1)
B = (x2, y2)

C = B - A = (x2 - x1, y2 - y1) = (xc, yc)
C2 = C . C = xc2 + yc2
|C| = sqrt(C2)
k = C/|C| = (xc/|C|, yc/|C|)

The point you're looking for is D = A + Nk

Beta
  • 96,650
  • 16
  • 149
  • 150
0

In the first octant (0 <= y2-y1 <= x2-x1), the formula is:

y(x) = y1 + round( (x-x1)(y2-y1) / (x2-x1) )

If you can't use floating point, then you probably need to user flooring division. You can do the rounding like this:

y(x) = y1 + floor( ( 2(x-x1)(y2-y1) + (x2-x1) ) / 2(x2-x1) )

The whole point of Bresenham's algorithm is to calculate this formula incrementally to avoid the multiplication and division, which were a lot more expensive at the time than they usually are now.

NOTE: I'm assuming you want a distance along x or y, because you want to clip the line. If you really want a Euclidean distance, then see @Beta answer

Matt Timmermans
  • 53,709
  • 3
  • 46
  • 87
0

I'm having the same issue, Bresenham's algorithm is drawing a nice line, but I just can't pick any point without iterating through the coordinates, because of its nature, to avoid the rounding and other "glitches" it decides to place a pixel on-the-fly, which is very handy during rendering, but it makes geometric calculations quite expensive (line crossing/intersection finding for example).

I can't use floating point types either, because I'm developing to an MCU right now which doesn't have FPU, but the following code from my project works quite well, very fast, and I haven't noticed any faults yet.

inline static int16_t GetYOfLineAtX(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x) {
    return (y1 - y0) * (x - x0) / (x1 - x0) + y0;
}

inline static int16_t GetXOfLineAtY(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t y) {
    return (x1 - x0) * (y - y0) / (y1 - y0) + x0;
}

It is straightforward: x0, y0 is your line starting point, x1, y1 is the ending point (slope may be negative or positive, direction doesn't matter), the x or y parameter on the two functions are the required coordinate, it returns the other axis value.

Dharman
  • 30,962
  • 25
  • 85
  • 135
beatcoder
  • 683
  • 1
  • 5
  • 19