<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: Only connect!</title>
	<atom:link href="http://bit-player.org/2006/only-connect/feed/" rel="self" type="application/rss+xml" />
	<link>http://bit-player.org/2006/only-connect</link>
	<description>An amateur's outlook on computation and mathematics.</description>
	<pubDate>Mon, 01 Dec 2008 19:56:27 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
		<item>
		<title>By: brian</title>
		<link>http://bit-player.org/2006/only-connect#comment-1522</link>
		<dc:creator>brian</dc:creator>
		<pubDate>Sun, 21 Oct 2007 18:39:28 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-1522</guid>
		<description>David: Thanks for the suggestion. I'll see if I can learn anything from that author. (I'm an autodidact, but I had a very good teacher.)</description>
		<content:encoded><![CDATA[<p>David: Thanks for the suggestion. I&#8217;ll see if I can learn anything from that author. (I&#8217;m an autodidact, but I had a very good teacher.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David</title>
		<link>http://bit-player.org/2006/only-connect#comment-1521</link>
		<dc:creator>David</dc:creator>
		<pubDate>Sun, 21 Oct 2007 17:29:07 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-1521</guid>
		<description>You might also be interested in the final chapter of the recent O'Reilly book &lt;a href="http://www.oreilly.com/catalog/9780596510046/" rel="nofollow"&gt;Beautiful Code: Leading Programmers Explain How They Think&lt;/a&gt;, which focuses on the related problem of determining whether three points are collinear.  The description of both the problem and the development of the eventual solution is lucid, engaging, and insightful.  Still, I doubt there's much you could learn from the author.</description>
		<content:encoded><![CDATA[<p>You might also be interested in the final chapter of the recent O&#8217;Reilly book <a href="http://www.oreilly.com/catalog/9780596510046/" rel="nofollow">Beautiful Code: Leading Programmers Explain How They Think</a>, which focuses on the related problem of determining whether three points are collinear.  The description of both the problem and the development of the eventual solution is lucid, engaging, and insightful.  Still, I doubt there&#8217;s much you could learn from the author.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonathan Shewchuk</title>
		<link>http://bit-player.org/2006/only-connect#comment-957</link>
		<dc:creator>Jonathan Shewchuk</dc:creator>
		<pubDate>Fri, 22 Sep 2006 06:47:07 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-957</guid>
		<description>(Oops, my last reply got corrupted by less-than-signs reinterpreted as HTML.  Here's a repost.)

I wrote some lecture notes that include the line intersection formula, as well as a bunch of other geometric constructors.  You can download it from

http://www.cs.berkeley.edu/~jrs/meshpapers/robnotes.ps.gz

(in gzipped PostScript form; see Section 3.6).  I believe this is the simplest possible formula.  The notes also contain some tips on getting a numerically stable answer despite floating-point roundoff.

The notes don't address how to tell &lt;i&gt;whether&lt;/i&gt; the segments intersect, so I'll address that here (and I should add it to the notes next week).  If your segments are ab and cd, and they're not parallel (see the notes for how to tell that), then they intersect if and only if

Orient2D(c,d,a) x Orient2D(c,d,b) &#60;= 0 AND
Orient2D(a,b,c) x Orient2D(a,b,d) &#60;= 0.

The function Orient2D() is described in the notes, and I have C code for computing it &lt;i&gt;exactly&lt;/i&gt; from floating-point input at

http://www.cs.cmu.edu/~quake/robust.html

If the lines are identical, then you determine the segment intersection by comparing x-coordinates (y-coordinates if the lines are vertical).</description>
		<content:encoded><![CDATA[<p>(Oops, my last reply got corrupted by less-than-signs reinterpreted as HTML.  Here&#8217;s a repost.)</p>
<p>I wrote some lecture notes that include the line intersection formula, as well as a bunch of other geometric constructors.  You can download it from</p>
<p><a href="http://www.cs.berkeley.edu/~jrs/meshpapers/robnotes.ps.gz" rel="nofollow">http://www.cs.berkeley.edu/~jrs/meshpapers/robnotes.ps.gz</a></p>
<p>(in gzipped PostScript form; see Section 3.6).  I believe this is the simplest possible formula.  The notes also contain some tips on getting a numerically stable answer despite floating-point roundoff.</p>
<p>The notes don&#8217;t address how to tell <i>whether</i> the segments intersect, so I&#8217;ll address that here (and I should add it to the notes next week).  If your segments are ab and cd, and they&#8217;re not parallel (see the notes for how to tell that), then they intersect if and only if</p>
<p>Orient2D(c,d,a) x Orient2D(c,d,b) &lt;= 0 AND<br />
Orient2D(a,b,c) x Orient2D(a,b,d) &lt;= 0.</p>
<p>The function Orient2D() is described in the notes, and I have C code for computing it <i>exactly</i> from floating-point input at</p>
<p><a href="http://www.cs.cmu.edu/~quake/robust.html" rel="nofollow">http://www.cs.cmu.edu/~quake/robust.html</a></p>
<p>If the lines are identical, then you determine the segment intersection by comparing x-coordinates (y-coordinates if the lines are vertical).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: D. Eppstein</title>
		<link>http://bit-player.org/2006/only-connect#comment-937</link>
		<dc:creator>D. Eppstein</dc:creator>
		<pubDate>Fri, 15 Sep 2006 16:26:08 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-937</guid>
		<description>To elaborate a little on my answer, so that it applies to line segment intersection and not just line intersection (and yes, line segments are perfectly well defined in projective geometry, only there are two of them between every pair of points so you have to be clear which one you mean):

- If the calculation for the line between one of the pairs of endpoints comes up (0,0,0), the two points are equal.  In this case, there is only an intersection if one of these points lies on the line through the other two points, which can be tested by taking the dot product of the point's coordinates with the line's.

- If the calculation for the point where the two lines meet comes up (0,0,0), the two lines are coincident.  In this case you can test for an intersection by comparing the order of the points' coordinates.

- As I said in my original comment, if you get a divide by zero converting back to Cartesian coordinates, the lines are parallel. In this case there can be no intersection.

- Finally, once you have the intersection point in Cartesian coordinates, you can test the ordering of its coordinates against the original points to determine whether it lies between them.

But, if you want to perform exact comparisons such as this (do you really have (0,0,0) or just a vector very close to it?) you probably need to be using multiprecision integers, and avoiding floating point, or your results will not be reliable. Or, to put it another way: if you think approximate calculation with floating point is good enough, why are you worrying about cases like two coincident lines that only make sense for exactly defined numbers?</description>
		<content:encoded><![CDATA[<p>To elaborate a little on my answer, so that it applies to line segment intersection and not just line intersection (and yes, line segments are perfectly well defined in projective geometry, only there are two of them between every pair of points so you have to be clear which one you mean):</p>
<p>- If the calculation for the line between one of the pairs of endpoints comes up (0,0,0), the two points are equal.  In this case, there is only an intersection if one of these points lies on the line through the other two points, which can be tested by taking the dot product of the point&#8217;s coordinates with the line&#8217;s.</p>
<p>- If the calculation for the point where the two lines meet comes up (0,0,0), the two lines are coincident.  In this case you can test for an intersection by comparing the order of the points&#8217; coordinates.</p>
<p>- As I said in my original comment, if you get a divide by zero converting back to Cartesian coordinates, the lines are parallel. In this case there can be no intersection.</p>
<p>- Finally, once you have the intersection point in Cartesian coordinates, you can test the ordering of its coordinates against the original points to determine whether it lies between them.</p>
<p>But, if you want to perform exact comparisons such as this (do you really have (0,0,0) or just a vector very close to it?) you probably need to be using multiprecision integers, and avoiding floating point, or your results will not be reliable. Or, to put it another way: if you think approximate calculation with floating point is good enough, why are you worrying about cases like two coincident lines that only make sense for exactly defined numbers?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michi</title>
		<link>http://bit-player.org/2006/only-connect#comment-936</link>
		<dc:creator>Michi</dc:creator>
		<pubDate>Fri, 15 Sep 2006 09:04:28 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-936</guid>
		<description>For one thing: what Eppstein said.

For another. Why not go parametric? You represent your lines as a pair of functions R-&#62;R. To make it work with being segments, let them be represented as functions [0,1]-&#62;R .Thus, if a line goes from (x1,y1) to (x2,y2), then this is represented by the pair
x: t -&#62; x1+t*(x2-x1)
y: t -&#62; y1+t*(y2-y1)
Now, the vertical line has t -&#62; x1, a constant function. The point has both functions constant. And finding the intersection of the lines described by (x1(t),y1(t)), (x2(t),y2(t)), respectively, is the matter of finding t1 and t2 such that x1(t1)=x2(t2) and y1(t1)=y2(t2). This yields a system of linear equations, easily solved, and with a final check for whether the solution stays within the constraints given.

The method is not hard to adapt to rays and lines - just adjust permissible solutions to be positive or all of them, respectively.</description>
		<content:encoded><![CDATA[<p>For one thing: what Eppstein said.</p>
<p>For another. Why not go parametric? You represent your lines as a pair of functions R-&gt;R. To make it work with being segments, let them be represented as functions [0,1]-&gt;R .Thus, if a line goes from (x1,y1) to (x2,y2), then this is represented by the pair<br />
x: t -&gt; x1+t*(x2-x1)<br />
y: t -&gt; y1+t*(y2-y1)<br />
Now, the vertical line has t -&gt; x1, a constant function. The point has both functions constant. And finding the intersection of the lines described by (x1(t),y1(t)), (x2(t),y2(t)), respectively, is the matter of finding t1 and t2 such that x1(t1)=x2(t2) and y1(t1)=y2(t2). This yields a system of linear equations, easily solved, and with a final check for whether the solution stays within the constraints given.</p>
<p>The method is not hard to adapt to rays and lines - just adjust permissible solutions to be positive or all of them, respectively.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Carl Witty</title>
		<link>http://bit-player.org/2006/only-connect#comment-935</link>
		<dc:creator>Carl Witty</dc:creator>
		<pubDate>Thu, 14 Sep 2006 23:12:57 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-935</guid>
		<description>Well, projective geometry is easier than Euclidean geometry in part because it has no good way to define "between", so you can't really even talk about line segments.  (This is similar to the reason that algebra is easier over the complex numbers than over the real numbers; in fact, maybe it's the exact same reason.)  (Also, even the projective geometry is not so easy as all that; the functions from two points to a line, and from two lines to a point, only work if the points/lines are distinct.)

I'm going to try for an algorithm without many case splits.  This is inspired by your description of the algorithm in Sedgewick, but it does give you the intersection point.  

I'll use some special notation: "." is the dot-product operator; if A is a point then Ax is the x coordinate; and if A,B,C are points then Area(ABC) is the signed parallelogram area: (Ax-Bx)*(Cy-By) - (Ay-By)*(Cx-Bx) (then &#124;Area(ABC)&#124; is the area of a parallelogram where 3 of the vertices are A,B,C; and Area(ABC) = -Area(CBA)).

We're testing whether the line segments AB and CD intersect.

First, if A=B and C=D, then we actually have two points; check whether A=C.  (first case split)

Now, assume without loss of generality that A!=B.  (second case split)

Next, compute Area(CAB) and Area(BAD).  If the product of these numbers is negative, then C and D are on the same side of AB; report no intersection, and exit.  (third case split)

If Area(CAB) and Area(BAD) are both 0, then A,B,C,D are all collinear; jump to the CollinearIntersection(AB,CD) routine below.  (fourth case split)

Now we know that the lines AB and CD are neither identical nor parallel, so we can find a unique intersection point E.  (Note that I said "lines", not "line segments"; we still don't know if the line segments intersect.)  This intersection point is:

  E = C + (D-C)*Area(CAB)/(Area(CAB) + Area(BAD))

(Due to the above case splits, we know that we are not dividing by 0 here.)

Now, A,B,E are collinear; jump to the CollinearIntersection(AB,EE) routine immediately below.

Now we are testing CollinearIntersection(AB,EF) (where EF is either CD or EE, depending on how we got here); we know that A!=B, and that A,B,E,F are all collinear.

Define UNIT=(B-A).(B-A).

Compute dE = (E-A).(B-A)/UNIT, and dF = (F-A).(B-A)/UNIT.

If dE and dF are both less than 0, or both greater than 1, then report no intersection, and exit. (fifth case split)

Now, sort the 4 numbers 0,1,dE,dF; remove the least and the greatest number; and call the remaining  middle two numbers dG and dH.  (several more case splits, depending on how you count)

Compute G = A + dG*(B-A) and H = A + dH*(B-A).  The intersection is the line segment GH (which may be a single point).

Finished!  After 5 case splits (into 6 cases), plus a 4-element sort (which you can decide to count as several case splits, or not, as you please).

Of course, in the real world, there's more to worry about geometric algorithms than just this.  Are you computing over the rationals (in which case this algorithm should work perfectly), or over floating-point numbers?  If you are computing over floating-point numbers, and you pass in coordinates which are collinear, is it acceptable to sometimes say that there is no intersection, or that there is a single-point intersection, rather than that there is a line-segment intersection?  (If you want an exact answer using floating-point arithmetic, then you've got a lot more work ahead of you!)</description>
		<content:encoded><![CDATA[<p>Well, projective geometry is easier than Euclidean geometry in part because it has no good way to define &#8220;between&#8221;, so you can&#8217;t really even talk about line segments.  (This is similar to the reason that algebra is easier over the complex numbers than over the real numbers; in fact, maybe it&#8217;s the exact same reason.)  (Also, even the projective geometry is not so easy as all that; the functions from two points to a line, and from two lines to a point, only work if the points/lines are distinct.)</p>
<p>I&#8217;m going to try for an algorithm without many case splits.  This is inspired by your description of the algorithm in Sedgewick, but it does give you the intersection point.  </p>
<p>I&#8217;ll use some special notation: &#8220;.&#8221; is the dot-product operator; if A is a point then Ax is the x coordinate; and if A,B,C are points then Area(ABC) is the signed parallelogram area: (Ax-Bx)*(Cy-By) - (Ay-By)*(Cx-Bx) (then |Area(ABC)| is the area of a parallelogram where 3 of the vertices are A,B,C; and Area(ABC) = -Area(CBA)).</p>
<p>We&#8217;re testing whether the line segments AB and CD intersect.</p>
<p>First, if A=B and C=D, then we actually have two points; check whether A=C.  (first case split)</p>
<p>Now, assume without loss of generality that A!=B.  (second case split)</p>
<p>Next, compute Area(CAB) and Area(BAD).  If the product of these numbers is negative, then C and D are on the same side of AB; report no intersection, and exit.  (third case split)</p>
<p>If Area(CAB) and Area(BAD) are both 0, then A,B,C,D are all collinear; jump to the CollinearIntersection(AB,CD) routine below.  (fourth case split)</p>
<p>Now we know that the lines AB and CD are neither identical nor parallel, so we can find a unique intersection point E.  (Note that I said &#8220;lines&#8221;, not &#8220;line segments&#8221;; we still don&#8217;t know if the line segments intersect.)  This intersection point is:</p>
<p>  E = C + (D-C)*Area(CAB)/(Area(CAB) + Area(BAD))</p>
<p>(Due to the above case splits, we know that we are not dividing by 0 here.)</p>
<p>Now, A,B,E are collinear; jump to the CollinearIntersection(AB,EE) routine immediately below.</p>
<p>Now we are testing CollinearIntersection(AB,EF) (where EF is either CD or EE, depending on how we got here); we know that A!=B, and that A,B,E,F are all collinear.</p>
<p>Define UNIT=(B-A).(B-A).</p>
<p>Compute dE = (E-A).(B-A)/UNIT, and dF = (F-A).(B-A)/UNIT.</p>
<p>If dE and dF are both less than 0, or both greater than 1, then report no intersection, and exit. (fifth case split)</p>
<p>Now, sort the 4 numbers 0,1,dE,dF; remove the least and the greatest number; and call the remaining  middle two numbers dG and dH.  (several more case splits, depending on how you count)</p>
<p>Compute G = A + dG*(B-A) and H = A + dH*(B-A).  The intersection is the line segment GH (which may be a single point).</p>
<p>Finished!  After 5 case splits (into 6 cases), plus a 4-element sort (which you can decide to count as several case splits, or not, as you please).</p>
<p>Of course, in the real world, there&#8217;s more to worry about geometric algorithms than just this.  Are you computing over the rationals (in which case this algorithm should work perfectly), or over floating-point numbers?  If you are computing over floating-point numbers, and you pass in coordinates which are collinear, is it acceptable to sometimes say that there is no intersection, or that there is a single-point intersection, rather than that there is a line-segment intersection?  (If you want an exact answer using floating-point arithmetic, then you&#8217;ve got a lot more work ahead of you!)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Suresh</title>
		<link>http://bit-player.org/2006/only-connect#comment-934</link>
		<dc:creator>Suresh</dc:creator>
		<pubDate>Thu, 14 Sep 2006 22:09:16 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-934</guid>
		<description>I sympathize with your plight: I'm surprised though that you didn't encounter yet another problem: precision !! After all, how do you really know that the two endpoints of a segment coincide. If they are floats, and came from some other application upstream, it's not clear that x == y suffices as a check.</description>
		<content:encoded><![CDATA[<p>I sympathize with your plight: I&#8217;m surprised though that you didn&#8217;t encounter yet another problem: precision !! After all, how do you really know that the two endpoints of a segment coincide. If they are floats, and came from some other application upstream, it&#8217;s not clear that x == y suffices as a check.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Blake Winton</title>
		<link>http://bit-player.org/2006/only-connect#comment-933</link>
		<dc:creator>Blake Winton</dc:creator>
		<pubDate>Thu, 14 Sep 2006 21:01:34 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-933</guid>
		<description>Just a thought, since you have two line segments, can you figure out whether the endpoints of one are both in front of or behind the other?  If they aren't, then you know they don't cross.

I guess what I'm suggesting is that maybe first you can figure out whether one line segment crosses the line made by extending the other, as an easier problem?

My other thought would be to project the one line onto the other, and see if the projected...  Uh, I'm not sure where I'm going with that.  Wait, if the projection doesn't overlap (which is easy to check), then the line segments don't cross?

I don't really know if that gets you any closer, but those would be the first two things I would try.</description>
		<content:encoded><![CDATA[<p>Just a thought, since you have two line segments, can you figure out whether the endpoints of one are both in front of or behind the other?  If they aren&#8217;t, then you know they don&#8217;t cross.</p>
<p>I guess what I&#8217;m suggesting is that maybe first you can figure out whether one line segment crosses the line made by extending the other, as an easier problem?</p>
<p>My other thought would be to project the one line onto the other, and see if the projected&#8230;  Uh, I&#8217;m not sure where I&#8217;m going with that.  Wait, if the projection doesn&#8217;t overlap (which is easy to check), then the line segments don&#8217;t cross?</p>
<p>I don&#8217;t really know if that gets you any closer, but those would be the first two things I would try.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Derek</title>
		<link>http://bit-player.org/2006/only-connect#comment-932</link>
		<dc:creator>Derek</dc:creator>
		<pubDate>Thu, 14 Sep 2006 20:41:17 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-932</guid>
		<description>Also, if you leave the cartesian coordinate system and use polar coordinates, you can specify a line in it's normal form, as is done with the Hough transform:

http://planetmath.org/encyclopedia/HoughTransform.html

In normal form, a line is defined as:
 x cos(theta) + y sin(theta) = rho.

That will eliminate the problem of infinite slopes.</description>
		<content:encoded><![CDATA[<p>Also, if you leave the cartesian coordinate system and use polar coordinates, you can specify a line in it&#8217;s normal form, as is done with the Hough transform:</p>
<p><a href="http://planetmath.org/encyclopedia/HoughTransform.html" rel="nofollow">http://planetmath.org/encyclopedia/HoughTransform.html</a></p>
<p>In normal form, a line is defined as:<br />
 x cos(theta) + y sin(theta) = rho.</p>
<p>That will eliminate the problem of infinite slopes.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Derek</title>
		<link>http://bit-player.org/2006/only-connect#comment-931</link>
		<dc:creator>Derek</dc:creator>
		<pubDate>Thu, 14 Sep 2006 20:31:21 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-931</guid>
		<description>I would find the intersection point of the two entire lines (not segments), then check the distance from the midpoint of each segment to the intersection point. If the distance is both cases is less than 1/2 the segment length, then the segments intersect. 

(I think that would work. Didn't test it though.)</description>
		<content:encoded><![CDATA[<p>I would find the intersection point of the two entire lines (not segments), then check the distance from the midpoint of each segment to the intersection point. If the distance is both cases is less than 1/2 the segment length, then the segments intersect. </p>
<p>(I think that would work. Didn&#8217;t test it though.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: D. Eppstein</title>
		<link>http://bit-player.org/2006/only-connect#comment-930</link>
		<dc:creator>D. Eppstein</dc:creator>
		<pubDate>Thu, 14 Sep 2006 19:54:46 +0000</pubDate>
		<guid isPermaLink="false">http://bit-player.org/?p=62#comment-930</guid>
		<description>It's much easier in projective geometry.

Cartesian coordinates of points to projective points:
(x,y) =&#62; (x,y,1)

The projective line ax+by+cz=0 through two projective points:
(y0z1-y1z0, z0x1-z1x0, x0y1-x1y0)

The projective point where two lines intersect:
same equation as the previous one, with the variable names changed

Projective back to Cartesian:
(x,y,z) =&#62; (x/z,y/z)

If you get a divide by zero in the last step, the lines are parallel.</description>
		<content:encoded><![CDATA[<p>It&#8217;s much easier in projective geometry.</p>
<p>Cartesian coordinates of points to projective points:<br />
(x,y) =&gt; (x,y,1)</p>
<p>The projective line ax+by+cz=0 through two projective points:<br />
(y0z1-y1z0, z0&#215;1-z1&#215;0, x0y1-x1y0)</p>
<p>The projective point where two lines intersect:<br />
same equation as the previous one, with the variable names changed</p>
<p>Projective back to Cartesian:<br />
(x,y,z) =&gt; (x/z,y/z)</p>
<p>If you get a divide by zero in the last step, the lines are parallel.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
