This is a task that has come up for me many times when creating algorithms for images analysis. Searching the web will invariably turn up the y = Mx + C solution. This is sub-optimal in two ways. First, it has big problems with vertical lines. As the line tends to vertical then m will tend to infinity. This Is Not Good. Secondly, getting any sort of accuracy is impossible without using floating point or large scaling factors.
The code I was modifying at the time was using the y = Mx + C method. It was fairly complex and had to check for lines that were nearly vertical, and flip the axes. It had bugs. I had this gut feeling that must be a better way to solve this, without all of the messing about with edge cases.
Finally after a bit of Googling I came across the lesser used form for describing lines, C = Ax + By. Having lines described in this slightly different form allows a method to find crossing points that is much more code friendly.
Most image processing algorithms I have created work perfectly fine when pixel coordinates are restricted to integral values, allowing integer maths for the following example.
Take two lines, L1 = x1,y1 to x2,y2 and L2 = x3,y3 to x4,y4.
Calculate the values of A, B and C for each line.
A1 = y2 – y1
B1 = x1 – x2
C1 = (A1 * x1) + (B1 * y1)
And similarly for L2:
A2 = y4 – y3
B2 = x3 – x4
C2 = (A2 * x3) + (B2 * y3)
Next, work out the determinant.
D = (A1 * B2) – (A2 * B1)
If D is zero then the lines are parallel and there is no crossing point to be found.
If D is not zero then the coordinates of the crossing point may be found thus:
X = ((B2 * C1) – (B1 * C2)) / D
Y = ((A1 * C2) – (A2 * C1)) / D
The two lines do not have to actually cross for this to work. This makes it a great way to find all of the crossing points relative to a reference line.
Next time I will show you how this technique can allow you to scan a rectangular region that is at an arbitrary angle.
Sometimes in graphical applications there is a need to know the relative position of a point with respect to a line from a reference point.
Where is the target in relation to the reference and its direction?
Dot and cross products can make this an easy task.
Let’s start with a reminder of what dot and cross products are.
Take two vectors x1 , y1 and x2 , y2
The dot product is (x1 * x2) + (y1 * y2) and the cross product is (x1 * y2) – (x2 * y1)
Take the example above. We have a reference object at Xr,Yr facing in the direction of the arrow.
The target is at point Xt,Yt
A arbitrary point on the line from the reference in the specified direction is Xw,Yw
First, find the relative coordinates of the target and waypoint relative to the reference.
dXw = Xw – Xr
dYw = Yw – Yr
dXt = Xt – Xr
dYt = Yt – Yr
Now find the dot and cross products of these vectors.
Dot = (dXw * dXt) + (dYw * dYt)
Cross = (dXw * dYt) – (dXt * dYw)
Assuming the coordinate system is as below.
Dot > 0, Cross < 0 : The target is forward of the reference and to the right.
Dot > 0, Cross > 0 : The target is forward of the reference and to the left.
Dot < 0, Cross < 0 : The target is behind the reference and to the right.
Dot < 0, Cross > 0 : The target is behind the reference and to the left.
‘Forward’, ‘Behind’, ‘Left’ and ‘Right’ are relative to the reference’s direction. This calculation will be correct for any direction.
This technique can also be used to determine if a point is within a closed convex hull.
A closed convex hull defined by the lines L1, L2, L3, L4 L5.
Point P1 is inside the hull, point P2 is outside.
For P1, the cross product for all of the lines will indicate that the it is to the right and therefore, must be inside.
For P2, the cross product for L1 will put it on the left hand side and therefore it cannot be inside the hull.
Why does this work?
The dot product of vectors A and B is |A||B|cos(Ø)
The cross product of vectors A and B is |A||B|sin(Ø)
Where Ø is the angle between the vectors A and B. Range +-180°
Therefore the sign of the result indicates the quadrant that target occupies in the circle around the reference, relative to the reference’s direction.