Find the intersection of two lines: Difference between revisions

Added Easylang
(Added Easylang)
 
(5 intermediate revisions by 5 users not shown)
Line 569:
print "yab = ", y
print "ycd = ", (yc - xc * ((yd - yc) / (xd - xc)) + x * ((yd - yc) / (xd - xc)))
print "intersection: (", x, comma, " ", y, ")"</syntaxhighlight>
{{out| Output}}<pre>The two lines are:
 
yab = -20 + x * 5
end</syntaxhighlight>
ycd = 3 + x * 0.4000
x = 5
yab = 5
ycd = 5
intersection: (5, 5)</pre>
 
==={{header|Run BASIC}}===
Line 955 ⟶ 960:
<pre>{5.000000, 5.000000}
{-inf, -inf}</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
This subroutine not only finds the intersection, it test for various degenerate condition where the intersection can fail.
 
<syntaxhighlight lang="Delphi">
{Vector structs and operations - these would normally be in}
{a library, but are produced here so everything is explicit}
 
type T2DVector=packed record
X,Y: double;
end;
 
type T2DLine = packed record
P1,P2: T2DVector;
end;
 
 
function MakeVector2D(const X,Y: double): T2DVector;
begin
Result.X:=X;
Result.Y:=Y;
end;
 
function MakeLine2D(X1,Y1,X2,Y2: double): T2DLine;
begin
Result.P1:=MakeVector2D(X1,Y1);
Result.P2:=MakeVector2D(X2,Y2);
end;
 
 
function DoLinesIntersect2D(L1,L2: T2DLine; var Point: T2DVector): boolean;
{Finds intersect point only if the lines actually intersect}
var distAB, theCos, theSin, newX, ABpos: double;
begin
Result:=False;
{ Fail if either line segment is zero-length.}
if (L1.P1.X=L1.P2.X) and (L1.P1.Y=L1.P2.Y) or
(L2.P1.X=L2.P2.X) and (L2.P1.Y=L2.P2.Y) then exit;
 
{ Fail if the segments share an end-point.}
if (L1.P1.X=L2.P1.X) and (L1.P1.Y=L2.P1.Y) or
(L1.P2.X=L2.P1.X) and (L1.P2.Y=L2.P1.Y) or
(L1.P1.X=L2.P2.X) and (L1.P1.Y=L2.P2.Y) or
(L1.P2.X=L2.P2.X) and (L1.P2.Y=L2.P2.Y) then exit;
 
{ (1) Translate the system so that point A is on the origin.}
L1.P2.X:=L1.P2.X-L1.P1.X; L1.P2.Y:=L1.P2.Y-L1.P1.Y;
L2.P1.X:=L2.P1.X-L1.P1.X; L2.P1.Y:=L2.P1.Y-L1.P1.Y;
L2.P2.X:=L2.P2.X-L1.P1.X; L2.P2.Y:=L2.P2.Y-L1.P1.Y;
 
{ Discover the length of segment A-B.}
distAB:=sqrt(L1.P2.X*L1.P2.X+L1.P2.Y*L1.P2.Y);
 
{ (2) Rotate the system so that point B is on the positive X L1.P1.Xis.}
theCos:=L1.P2.X/distAB;
theSin:=L1.P2.Y/distAB;
newX:=L2.P1.X*theCos+L2.P1.Y*theSin;
L2.P1.Y :=L2.P1.Y*theCos-L2.P1.X*theSin; L2.P1.X:=newX;
newX:=L2.P2.X*theCos+L2.P2.Y*theSin;
L2.P2.Y :=L2.P2.Y*theCos-L2.P2.X*theSin; L2.P2.X:=newX;
 
{ Fail if segment C-D doesn't cross line A-B.}
if (L2.P1.Y<0) and (L2.P2.Y<0) or (L2.P1.Y>=0) and (L2.P2.Y>=0) then exit;
 
{ (3) Discover the position of the intersection point along line A-B.}
ABpos:=L2.P2.X+(L2.P1.X-L2.P2.X)*L2.P2.Y/(L2.P2.Y-L2.P1.Y);
 
{ Fail if segment C-D crosses line A-B outside of segment A-B.}
if (ABpos<0) or (ABpos>distAB) then exit;
 
{ (4) Apply the discovered position to line A-B in the original coordinate system.}
Point.X:=L1.P1.X+ABpos*theCos;
Point.Y:=L1.P1.Y+ABpos*theSin;
Result:=True;
end;
 
procedure TestIntersect(Memo: TMemo; L1,L2: T2DLine);
var Int: T2DVector;
var S: string;
begin
Memo.Lines.Add('Line-1: '+Format('(%1.0f,%1.0f)->(%1.0f,%1.0f)',[L1.P1.X,L1.P1.Y,L1.P2.X,L1.P2.Y]));
Memo.Lines.Add('Line-2: '+Format('(%1.0f,%1.0f)->(%1.0f,%1.0f)',[L2.P1.X,L2.P1.Y,L2.P2.X,L2.P2.Y]));
if DoLinesIntersect2D(L1,L2,Int) then Memo.Lines.Add(Format('Intersect = %2.1f %2.1f',[Int.X,Int.Y]))
else Memo.Lines.Add('No Intersect.');
end;
 
procedure TestLineIntersect(Memo: TMemo);
var L1,L2: T2DLine;
var S: string;
begin
L1:=MakeLine2D(4,0,6,10);
L2:=MakeLine2D(0,3,10,7);
TestIntersect(Memo,L1,L2);
Memo.Lines.Add('');
L1:=MakeLine2D(0,0,1,1);
L2:=MakeLine2D(1,2,4,5);
TestIntersect(Memo,L1,L2);
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
Line-1: (4,0)->(6,10)
Line-2: (0,3)->(10,7)
Intersect = 5.0 5.0
 
Line-1: (0,0)->(1,1)
Line-2: (1,2)->(4,5)
No Intersect.
</pre>
 
 
=={{header|EasyLang}}==
{{trans|Python}}
<syntaxhighlight>
proc intersect ax1 ay1 ax2 ay2 bx1 by1 bx2 by2 . rx ry .
rx = 1 / 0
ry = 1 / 0
d = (by2 - by1) * (ax2 - ax1) - (bx2 - bx1) * (ay2 - ay1)
if d = 0
return
.
ua = ((bx2 - bx1) * (ay1 - by1) - (by2 - by1) * (ax1 - bx1)) / d
ub = ((ax2 - ax1) * (ay1 - by1) - (by2 - by1) * (ax1 - bx1)) / d
if abs ua > 1 or abs ub > 1
return
.
rx = ax1 + ua * (ax2 - ax1)
ry = ay1 + ua * (ay2 - ay1)
.
intersect 4 0 6 10 0 3 10 7 rx ry
print rx & " " & ry
intersect 4 0 6 10 0 3 10 7.1 rx ry
print rx & " " & ry
intersect 0 0 1 1 1 2 4 5 rx ry
print rx & " " & ry
</syntaxhighlight>
 
=={{header|Emacs Lisp}}==
Line 989 ⟶ 1,134:
<pre>
(x 5.0 y 5.0)
</pre>
 
=={{header|EMal}}==
<syntaxhighlight lang="emal">
type Intersection
model
Point point
fun asText = <|when(me.point == null, "No intersection", me.point.asText())
end
type Point
model
real x, y
fun asText = <|"(" + me.x + "," + me.y + ")"
end
type Line
model
Point s,e
end
type Main
fun getIntersectionByLines = Intersection by Line n1, Line n2
real a1 = n1.e.y - n1.s.y
real b1 = n1.s.x - n1.e.x
real c1 = a1 * n1.s.x + b1 * n1.s.y
real a2 = n2.e.y - n2.s.y
real b2 = n2.s.x - n2.e.x
real c2 = a2 * n2.s.x + b2 * n2.s.y
real delta = a1 * b2 - a2 * b1
if delta == 0 do return Intersection() end
return Intersection(Point((b2 * c1 - b1 * c2) / delta, (a1 * c2 - a2 * c1) / delta))
end
Line n1 = Line(Point(4, 0), Point(6, 10))
Line n2 = Line(Point(0, 3), Point(10, 7))
writeLine(getIntersectionByLines(n1, n2))
n1 = Line(Point(0, 0), Point(1, 1))
n2 = Line(Point(1, 2), Point(4, 5))
writeLine(getIntersectionByLines(n1, n2))
</syntaxhighlight>
{{out}}
<pre>
(5.0,5.0)
No intersection
</pre>
 
Line 2,346 ⟶ 2,532:
ycd=5
intersection: 5,5
</pre>
 
=={{header|RPL}}==
{{works with|HP|48}}
« C→R ROT C→R ROT →V2
SWAP 1 4 ROLL 1 { 2 2 } →ARRY /
» '<span style="color:blue">→LINECOEFF</span>' STO
« <span style="color:blue">→LINECOEFF</span> ROT ROT <span style="color:blue">→LINECOEFF</span> OVER -
ARRY→ DROP NEG SWAP /
DUP2 * 1 GET ROT 2 GET + R→C
» '<span style="color:blue">INTERSECT</span>' STO
Latest versions of RPL have powerful equation handling and solving functions:
{{works with|HP|49}}
« DROITE UNROT DROITE OVER -
'X' SOLVE DUP EQ→ NIP
UNROT SUBST EQ→ NIP COLLECT R→C
» '<span style="color:blue">INTERSECT</span>' STO
 
(4,0) (6,10) (0,3) (10,7) <span style="color:blue">INTERSECT</span>
{{out}}
<pre>
1: (5,5)
</pre>
 
Line 2,725 ⟶ 2,934:
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="ecmascriptwren">class Point {
construct new(x, y) {
_x = x
1,983

edits