[Math] Compute position of next point on a line

algorithmsanalytic geometrygeometry

I'm writing a program in which it is possible to draw a horizontal, vertical or an oblique line.

So the line can be described as follows : $f(x) = y = mx + q$
But my problem is that given the first point, the last point and a point on the line I have to compute the next point.

With "next point" I mean the point that is $1$ further (in my program $1$ pixel further).

For horizontal and vertical lines that is very easy, I compute the difference of the first point and the last point so I can check if it is a horizontal or vertical line and the direction (for example : horizontal line with direction from left to right, then all i have to do is add 1 to the x coordinate).

Dependent on what I computed I add/subtract one of the x respectively y coordinate of the current point.

For oblique lines I don't know how to compute the next position.
If I compute it using : $f(x) = y = mx + q$

Then I give for example the next x coordinate. Suppose that $m = 1$

Then my y coordinate is also $1$ bigger then the previous one. But this is not $1$ pixel further, because we moved one horizontally and one vertically so in fact we moved :

$$
a^2 = b^2 + c^2 \rightarrow a^2 = 1^2 + 1^2 \rightarrow a = \sqrt{ 2} \ne 1
$$

So if the line is horizontally or vertically I just move 1 pixel but when it is oblique we moved a bit more. When we move 1 pixel that is not a big problem but when we move for example 100 pixels, it really is a problem because we aren't at the right place at all.

So given the start position, end position and the position of a point on the line, how can I compute the coordinates of the "next point", with "next point" being the point $1$ (pixel or centimeter or …) further on the line.

Thanks for your help!

Best Answer

The next point will be at coordinates $$ x_{new} = x_{old} + \cos(t)\\ y_{new} = y_{old} + \sin(t) $$ where $$ t = \arctan(m). $$

This can be simplified slightly, by noting that $$ \cos(t) = \frac{1}{\sqrt{1 + m^2}}\\ \sin(t) = \frac{m}{\sqrt{1 + m^2}} $$ so that you get $$ x_{new} = x_{old} + \frac{1}{\sqrt{1 + m^2}}\\ y_{new} = y_{old} + \frac{m}{\sqrt{1 + m^2}}. $$

By the way, the choice to represent the line in $y = mx + b$ form is generally a bad one in graphics. It leads to special-casing for vertical lines, which cannot be represented this way, and it means that in cases like yours, you cannot tell the difference between a line headed up-and-to-the-right and one headed down-and-to-the-left. A form like

$$ Ax + By + C = 0 $$

turns out to be far more general and effective, even though $A,B,C$ are not uniquely determined (you can multiply them by a nonzero constant and get the same line).

Related Question