The most common method for finding the intersection of two straight lines is to list the equations of two straight lines and solve them simultaneously.
However, this method has many drawbacks:
1) The algorithm is related to the coordinate system. It is necessary to consider whether the straight line is horizontal or vertical, write many judgment conditions, and increase the instability of the program.
2) even if the two straight lines are oblique, as long as they are close to the horizontal or vertical lines, it will lead to a large error and cause the calculation to fail.
The core of this problem is that simultaneous equations cannot be unrelated to the coordinate system, and the geometric problem of the intersection is always bound to the coordinate system.
Essentially, the intersection of two straight lines is the internal nature of the ry and does not depend on the coordinate system. Using Vector transformation to calculate the intersection point can avoid solving the linear equation, and does not need to judge whether the straight line is horizontal and vertical, can truly achieve coordinate system independence. Similar algorithms can also be used to calculate the intersection of a straight line and a circle, the intersection of a circle and a circle, and the intersection of a straight line and an elliptic.
The following is a program written in Delphi to calculate the intersection of two straight lines using vector transformation.
This program can not only obtain the intersection coordinate, but also determine whether a straight line passes through the intersection, because sometimes the intersection is on the extension line.
Unit unit1;
Interface
Uses
Windows, messages, sysutils, variants, classes, graphics, controls, forms,
Dialogs, stdctrls, buttons;
Type
Tform1 = Class (tform)
Bitbtn1: tbitbtn;
Procedure bitbtn1click (Sender: tobject );
Private
{Private Declarations}
Public
{Public declarations}
Calinterpoint (x1, Y1, X2, Y2, X3, Y3, X4, Y4: Double;
VaR XJ, YJ: Double): integer;
Calpro (vx1, vy1, VX2, vy2: Double): Double;
End;
VaR
Form1: tform1;
Implementation
{$ R *. DFM}
{Tform1}
Tform1.calinterpoint (x1, Y1, X2, Y2, X3, Y3, X4, Y4: Double;
VaR XJ, YJ: Double): integer;
{-----------------------------------------------------------------------------
Function Name: calinterpoint
Author: Chen xinzhong
Time: 2002-8-28
Parameter: (x1, Y1, X2, Y2) is a straight line.
(X3, Y3, X4, Y4) is another line
Return Value:> = 0 intersection 1 represents the intersection of 12 contains 2 represents the intersection of 34
Four combinations
0 two straight lines do not pass the intersection
1 straight line 12 pass, straight line 34 do not pass
2 straight line 34 pass, straight line 12 does not pass
3 lines 12 and 34 pass
-1 parallel
Function: calculates the intersection of a straight line.
-----------------------------------------------------------------------------}
VaR
Px12, py12, // The direction vector of line 12
Px34, py34, // direction vector of line 34
Length of T12, t34, // 12, and 34
Nx12, ny12, // unit vector of line 12
Nx34, ny34, // unit vector of line 34
PX13, py13, // 13 link Vector
Ty, // 13 projection of the line vector on line 12
Tysx, tysy, // projection vector of the line vector on line 12
Czsx, czsy, // vertical vector from 3 to 12
Cossit, // cosine of the angle between the vertical vector and the 34-direction vector of the straight line
Sux, Suy, // link vector from 3 to Intersection
Czl, // vertical line length
GENE: // Transformation Factor
Double;
Begin
Px12: = x2-x1; // 12 link Vector
Py12: = Y2-Y1;
Px34: = X4-X3; // 34 link Vector
Py34: = Y4-Y3;
// If the vector product is 0, it indicates parallel. Set the parallel sign and return
If px12 * py34-px34 * py12 = 0 then
Begin
Result: =-1;
Exit;
End;
If (X3-X1) * (Y3-Y2) + (X3-X2) * (Y3-Y1) = 0 then
Begin // If 3 falls on line 12, the intersection is (X3, X4)
XJ: = X3;
YJ: = Y3;
End
Else
Begin
T12: = SQRT (px12 * px12 + py12 * py12); // 12 Length
T34: = SQRT (px34 * px34 + py34 * py34); // 34 Length
Nx12: = px12/T12; // 12 unit vector
Ny12: = py12/T12;
Nx34: = px34/t34; // 34 unit vector
Ny34: = py34/t34;
PX13: = X3-x1; // 13 link Vector
Py13: = Y3-Y1;
Ty: = PX13 * nx12 + py13 * ny12; // projection
Tysx: = ty * nx12; // projection Vector
Tysy: = ty * ny12;
Czsx: = tysx-PX13; // vertical Vector
Czsy: = tysy-py13;
Czl: = SQRT (czsx * czsx + czsy * czsy); // vertical line length
GENE: = czl/calpro (X4-X3, Y4-Y3, czsx, czsy); // Transform Factor
XJ: = X3 + px34 * gene;
YJ: = Y3 + py34 * gene;
End;
Result: = 0;
If (x1-XJ) * (x2-XJ) + (Y1-YJ) * (Y2-YJ) <0 then
Result: = Result + 1; // determines whether the line is on line 12.
If (X3-XJ) * (X4-XJ) + (Y3-YJ) * (Y4-YJ) <0 then
Result: = Result + 2; // determine whether the line is above 34
End;
Procedure tform1.bitbtn1click (Sender: tobject );
VaR
X1, Y1, X2, Y2, X3, Y3, X4, Y4: Double;
XO, yo: Double;
RET: integer;
Info: string;
Begin
X1: = 150;
Y1: = 150;
X2: = 200;
Y2: = 200;
X3: = 200;
Y3: = 100;
X4: = 0;
Y4: = 150;
Form1.canvas. moveTo (round (X1), round (Y1 ));
Form1.canvas. lineto (round (X2), round (Y2 ));
Form1.canvas. moveTo (round (X3), round (Y3 ));
Form1.canvas. lineto (round (X4), round (Y4 ));
RET: = calinterpoint (x1, Y1, X2, Y2, X3, Y3, X4, Y4, XO, yo );
Form1.canvas. ellipse (round (XO-10), round (yo-10), round (XO + 10), round (Yo + 10 ));
Info: = '';
If (RET and 1)> 0 then
Begin
Info: = info + 'intersection on line 12 ';
End
Else
Begin
Info: = info + 'intersection is not on line 12 ';
End;
If (RET and 2)> 0 then
Begin
Info: = info + 'intersection on line 34 ';
End
Else
Begin
Info: = info + 'intersection is not above line 34 ';
End;
Showmessage (Info );
End;
Tform1.calpro (vx1, vy1, VX, vy2: Double): Double;
// Calculate the projection vector V1 projection on V2 (vx1, vy1) is the vector V1 (VX2, vy2) is the vector v2
Begin
Result: = (vx1 * VX2 + vy1 * vy2)/SQRT (VX2 * VX2 + vy2 * vy2 );
End;
End.