Find the intersection of two lines: Difference between revisions

Added Easylang
m (→‎{{header|Ruby}}: no more + -20)
(Added Easylang)
 
(10 intermediate revisions by 7 users not shown)
Line 556:
print "ycd = "; (yc-xc*((yd-yc)/(xd-xc))+x*((yd-yc)/(xd-xc)))
print "intersection: ("; x; ", "; y ; ")"</syntaxhighlight>
 
==={{header|Craft Basic}}===
<syntaxhighlight lang="basic">define xa = 4, xb = 6, xc = 0, xd = 10
define ya = 0, yb = 10, yc = 3, yd = 7
 
print "The two lines are:"
print "yab = ", (ya - xa * ((yb - ya) / (xb - xa))), " + x * ", ((yb - ya) / (xb - xa))
print "ycd = ", (yc - xc * ((yd - yc) / (xd - xc))), " + x * ", ((yd - yc) / (xd - xc))
let x = ((yc - xc * ((yd - yc) / (xd - xc))) - (ya - xa * ((yb - ya) / (xb - xa)))) / (((yb - ya) / (xb - xa)) - ((yd - yc) / (xd - xc)))
print "x = ", x
let y = ya - xa * ((yb - ya) / (xb - xa)) + x * ((yb - ya) / (xb - xa))
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
ycd = 3 + x * 0.4000
x = 5
yab = 5
ycd = 5
intersection: (5, 5)</pre>
 
==={{header|Run BASIC}}===
Line 939 ⟶ 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}}==
<syntaxhighlight lang="lisp">
;; y = a*x + b
(let ()
(defun line-prop (p1 p2)
(let* ((prop-a (/ (- (plist-get p2 'y) (plist-get p1 'y))
(- (plist-get p2 'x) (plist-get p1 'x))))
(prop-b (- (plist-get p1 'y) (* prop-a (plist-get p1 'x)))))
 
(list 'a prop-a 'b prop-b) ) )
 
(defun calculate-intersection (line1 line2)
(if (= (plist-get line1 'a) (plist-get line2 'a))
(progn (error "The two lines don't have any intersection.") nil)
(progn
(let (int-x int-y)
(setq int-x (/ (- (plist-get line2 'b) (plist-get line1 'b))
(- (plist-get line1 'a) (plist-get line2 'a))))
(setq int-y (+ (* (plist-get line1 'a) int-x) (plist-get line1 'b)))
(list 'x int-x 'y int-y) ) ) ) )
 
(let ((p1 '(x 4.0 y 0.0)) (p2 '(x 6.0 y 10.0))
(p3 '(x 0.0 y 3.0)) (p4 '(x 10.0 y 7.0)))
(let ((line1 (line-prop p1 p2))
(line2 (line-prop p3 p4)))
(message "%s" (calculate-intersection line1 line2)) ) )
 
)
</syntaxhighlight>
 
{{out}}
<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>
 
=={{header|F_Sharp|F#}}==
Line 1,531 ⟶ 1,768:
{-Infinity, -Infinity}
</pre>
 
=={{header|Lambdatalk}}==
{{trans|Python}}
<syntaxhighlight lang="scheme">
{def line_intersect
{def line_intersect.sub
{lambda {:111 :121 :112 :122 :211 :221 :212 :222}
{let { {:x :111} {:y :121}
{:z {- {* {- :222 :221} {- :112 :111}}
{* {- :212 :211} {- :122 :121}} } }
{:a {- :112 :111}} {:b {- :122 :121}}
{:c {- :212 :211}} {:d {- :222 :221}}
{:e {- :121 :221}} {:f {- :111 :211}}
{:g {- :121 :211}} {:h {- :122 :121}}
} {if {> :z 0}
then {A.new ∞ ∞}
else {let { {:x :x} {:y :y} {:a :a} {:b :b}
{:t1 {/ {- {* :c :e} {* :d :f}} :z} }
{:t2 {/ {- {* :a :g} {* :h :f}} :z} }
} {if {and {>= :t1 0} {<= :t1 1} {>= :t2 0} {<= :t2 1}}
then {A.new {+ :x {* :t1 :a}} {+ :y {* :t1 :b}} }
else {A.new ∞ ∞}} }}}}}
{lambda {:1 :2}
{line_intersect.sub
{A.first {A.first :1}} {A.last {A.first :1}}
{A.first {A.last :1}} {A.last {A.last :1}}
{A.first {A.first :2}} {A.last {A.first :2}}
{A.first {A.last :2}} {A.last {A.last :2}} }}}
-> line_intersect
 
{line_intersect {A.new {A.new 4 0} {A.new 6 10}}
{A.new {A.new 0 3} {A.new 10 7}}}
-> [5,5]
{line_intersect {A.new {A.new 4 0} {A.new 6 10}}
{A.new {A.new 0 3} {A.new 10 7.1}}}
-> [5.010893246187364,5.05446623093682]
{line_intersect {A.new {A.new 1 -1} {A.new 4 4}}
{A.new {A.new 2 5} {A.new 3 -2}}}
-> [2.5,1.5]
{line_intersect {A.new {A.new 0 0} {A.new 0 0}}
{A.new {A.new 0 3} {A.new 10 7}}}
-> [∞,∞]
{line_intersect {A.new {A.new 0 0} {A.new 1 1}}
{A.new {A.new 1 2} {A.new 4 5}}}
-> [∞,∞]
</syntaxhighlight>
 
=={{header|Lua}}==
Line 2,249 ⟶ 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,628 ⟶ 2,934:
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="ecmascriptwren">class Point {
construct new(x, y) {
_x = x
1,983

edits