<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Geometry - shortest distance between a point and line</title>
		<link>http://www.allegro.cc/forums/view/589720</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Fri, 26 Jan 2007 00:47:47 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;m having trouble grasping this simple concept for some reason.  Basically I have a point (A) and a line (BC), and I want to find the shortest distance between the two.</p><p><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/0/e/0ea95c7355c698dcd30e4b2f131a9c7e.gif" alt="591076" width="97" height="115" /></p><p>Knowing that the shortest distance will be a line (AX) that has a slope perpendicular to the slope of BC and goes through A.  So the intersection of the two lines is X.</p><p><img src="http://www.allegro.cc//djungxnpq2nug.cloudfront.net/image/cache/9/9/9986b6df6c30ac067e872f357af747fb.gif" alt="591077" width="113" height="122" /></p><p>For some reason I can&#39;t seem to get the math to work out right?!  Basically I find the slope-intercept form of both lines and then work the two out to find the x and y coordinates of point X, but this code isn&#39;t giving me the correct answers. <img src="http://www.allegro.cc/forums/smileys/huh.gif" alt="???" /> Here&#39;s what I have:</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="p">#include "allegro.h"</span></td></tr><tr><td class="number">2</td><td><span class="p">#include &lt;math.h&gt;</span></td></tr><tr><td class="number">3</td><td>&#160;</td></tr><tr><td class="number">4</td><td><span class="k1">float</span> d <span class="k2">(</span> <span class="k1">float</span> x1, <span class="k1">float</span> y1, <span class="k1">float</span> x2, <span class="k1">float</span> y2<span class="k2">)</span></td></tr><tr><td class="number">5</td><td><span class="k2">{</span></td></tr><tr><td class="number">6</td><td>    <span class="k1">return</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_738.html" target="_blank">sqrt</a><span class="k2">(</span> <span class="k2">(</span><span class="k2">(</span>x1 <span class="k3">-</span> x2<span class="k2">)</span> <span class="k3">*</span> <span class="k2">(</span>x1 <span class="k3">-</span> x2<span class="k2">)</span><span class="k2">)</span> <span class="k3">+</span> <span class="k2">(</span><span class="k2">(</span>y1 <span class="k3">-</span> y2<span class="k2">)</span> <span class="k3">*</span> <span class="k2">(</span>y1 <span class="k3">-</span> y2<span class="k2">)</span><span class="k2">)</span> <span class="k2">)</span> <span class="k2">;</span></td></tr><tr><td class="number">7</td><td><span class="k2">}</span></td></tr><tr><td class="number">8</td><td>&#160;</td></tr><tr><td class="number">9</td><td><span class="k1">float</span> shortest_distance<span class="k2">(</span><span class="k1">float</span> point_x, <span class="k1">float</span> point_y, <span class="k1">float</span> line_x1, <span class="k1">float</span> line_y1, <span class="k1">float</span> line_x2, <span class="k1">float</span> line_y2<span class="k2">)</span></td></tr><tr><td class="number">10</td><td><span class="k2">{</span></td></tr><tr><td class="number">11</td><td>    <span class="c">// find the slope</span></td></tr><tr><td class="number">12</td><td>    <span class="k1">float</span> slope_of_line <span class="k3">=</span> <span class="k2">(</span>line_y1 <span class="k3">-</span> line_y2<span class="k2">)</span> <span class="k3">/</span> <span class="k2">(</span>line_x1 <span class="k3">-</span> line_x2<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">13</td><td>    </td></tr><tr><td class="number">14</td><td>    <span class="c">// find the perpendicular slope</span></td></tr><tr><td class="number">15</td><td>    <span class="k1">float</span> perpendicular_slope <span class="k3">=</span> <span class="k2">(</span>line_x1 <span class="k3">-</span> line_x2<span class="k2">)</span> <span class="k3">/</span> <span class="k2">(</span>line_y1 <span class="k3">-</span> line_y2<span class="k2">)</span> <span class="k3">*</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>    </td></tr><tr><td class="number">17</td><td>    <span class="c">// find the y_intercept of line BC</span></td></tr><tr><td class="number">18</td><td>    <span class="k1">float</span> y_intercept <span class="k3">=</span> slope_of_line <span class="k3">*</span> line_x2 <span class="k3">-</span> line_y2<span class="k2">;</span></td></tr><tr><td class="number">19</td><td>    </td></tr><tr><td class="number">20</td><td>    <span class="c">// find the y_intercept of line AX</span></td></tr><tr><td class="number">21</td><td>    <span class="k1">float</span> new_line_y_intercept <span class="k3">=</span> perpendicular_slope <span class="k3">*</span> <span class="k3">-</span><span class="n">1</span> <span class="k3">*</span> point_x <span class="k3">-</span> point_y<span class="k2">;</span></td></tr><tr><td class="number">22</td><td>    </td></tr><tr><td class="number">23</td><td>    <span class="c">// get the x_coordinate of point X</span></td></tr><tr><td class="number">24</td><td>    <span class="c">// equation of BC is    y = slope_of_line * x + y_intercept;</span></td></tr><tr><td class="number">25</td><td>    <span class="c">// equation of AX is    y = perpendicular_slope * x + new_line_y_intercept;</span></td></tr><tr><td class="number">26</td><td>    <span class="c">//   perpendicular_slope * x + new_line_y_intercept == slope_of_line * x + y_intercept;</span></td></tr><tr><td class="number">27</td><td>    <span class="c">//   perpendicular_slope * x == slope_of_line * x + y_intercept - new_line_y_intercept;</span></td></tr><tr><td class="number">28</td><td>    <span class="c">//   (perpendicular_slope - slope_of_line) * x == (y_intercept - new_line_y_intercept);</span></td></tr><tr><td class="number">29</td><td>    <span class="k1">float</span> intersect_x <span class="k3">=</span> <span class="k2">(</span>y_intercept <span class="k3">-</span> new_line_y_intercept<span class="k2">)</span> <span class="k3">/</span> <span class="k2">(</span>perpendicular_slope <span class="k3">-</span> slope_of_line<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">30</td><td>    </td></tr><tr><td class="number">31</td><td>    <span class="c">// get the y_coordinate of point X</span></td></tr><tr><td class="number">32</td><td>    <span class="k1">float</span> intersect_y <span class="k3">=</span> slope_of_line <span class="k3">*</span> intersect_x <span class="k3">+</span> y_intercept<span class="k2">;</span></td></tr><tr><td class="number">33</td><td>    </td></tr><tr><td class="number">34</td><td>    <span class="c">// measure the distance between A and X</span></td></tr><tr><td class="number">35</td><td>    <span class="k1">return</span> d<span class="k2">(</span>point_x, point_y, intersect_x, intersect_y<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">36</td><td><span class="k2">}</span></td></tr><tr><td class="number">37</td><td>&#160;</td></tr><tr><td class="number">38</td><td>&#160;</td></tr><tr><td class="number">39</td><td>&#160;</td></tr><tr><td class="number">40</td><td><span class="k1">void</span> main<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">41</td><td><span class="k2">{</span></td></tr><tr><td class="number">42</td><td>     <a href="http://www.allegro.cc/manual/allegro_init" target="_blank"><span class="a">allegro_init</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">43</td><td>     </td></tr><tr><td class="number">44</td><td>     <span class="k1">float</span> point_x <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">45</td><td>     <span class="k1">float</span> point_y <span class="k3">=</span> <span class="k3">-</span><span class="n">10</span><span class="k2">;</span></td></tr><tr><td class="number">46</td><td>     <span class="k1">float</span> line_x1 <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">47</td><td>     <span class="k1">float</span> line_y1 <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">48</td><td>     <span class="k1">float</span> line_x2 <span class="k3">=</span> <span class="n">10</span><span class="k2">;</span></td></tr><tr><td class="number">49</td><td>     <span class="k1">float</span> line_y2 <span class="k3">=</span> <span class="k3">-</span><span class="n">10</span><span class="k2">;</span></td></tr><tr><td class="number">50</td><td>     </td></tr><tr><td class="number">51</td><td>     <span class="k1">float</span> dist <span class="k3">=</span> shortest_distance<span class="k2">(</span>point_x, point_y, line_x1, line_y1, line_x2, line_y2<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">52</td><td>     dist <span class="k3">=</span> d<span class="k2">(</span>line_x1, line_y1, line_x2, line_y2<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">53</td><td>     </td></tr><tr><td class="number">54</td><td>     <a href="http://www.allegro.cc/manual/allegro_message" target="_blank"><span class="a">allegro_message</span></a><span class="k2">(</span><span class="s">"%i"</span>, <span class="k2">(</span><span class="k1">int</span><span class="k2">)</span>dist<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">55</td><td><span class="k2">}</span> <a href="http://www.allegro.cc/manual/END_OF_MAIN" target="_blank"><span class="a">END_OF_MAIN</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr></tbody></table></div></div><p>

What am I doing wrong? <img src="http://www.allegro.cc/forums/smileys/huh.gif" alt="???" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mark Oates)</author>
		<pubDate>Thu, 25 Jan 2007 06:50:40 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Instead of trying to fix your algorithm I shall suggest you a better one. It is faster, and it can handle vertical/horizontal lines(which yours can&#39;t as of now).</p><p>What you do is you find a vector from the first point on the line to the second point. Then you find the absolute value of the cross product between the two vectors(which find the area of the parallelogram formed by the two vectors) and then divide it by the magnitude of the first vector to find the height(which is what you want).</p><p>Here&#39;s the code for that:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> A <span class="k3">=</span> x <span class="k3">-</span> x1<span class="k2">;</span>
<span class="k1">int</span> B <span class="k3">=</span> y <span class="k3">-</span> y1<span class="k2">;</span>
<span class="k1">int</span> C <span class="k3">=</span> x2 <span class="k3">-</span> x1<span class="k2">;</span>
<span class="k1">int</span> D <span class="k3">=</span> y2 <span class="k3">-</span> y1<span class="k2">;</span>

<span class="k1">int</span> dist <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_38.html" target="_blank">abs</a><span class="k2">(</span>A <span class="k3">*</span> D <span class="k3">-</span> C <span class="k3">*</span> B<span class="k2">)</span> <span class="k3">/</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_738.html" target="_blank">sqrt</a><span class="k2">(</span>C <span class="k3">*</span> C <span class="k3">+</span> D <span class="k3">*</span> D<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Thu, 25 Jan 2007 09:37:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>seems to work, but I&#39;m guessing this assumes the line is of infinate length?  How should I accomidate for this?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mark Oates)</author>
		<pubDate>Thu, 25 Jan 2007 10:41:43 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Then it would be the end point.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matthew Leverton)</author>
		<pubDate>Thu, 25 Jan 2007 10:43:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hmm, I still don&#39;t understand.  How do I know when it&#39;s going to be the end point or a point along the line?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mark Oates)</author>
		<pubDate>Thu, 25 Jan 2007 11:06:05 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>(x1,y1) and (x2,y2) are any two(non-coinciding) on the line. There is no order requirement.</p><p>This method does indeed assume an infinite line. It shall return the distance from the line to the point regardless whether the perpendicular projection of it onto the line(point X in your diagram) is actually between the two points.</p><p>If you want the distance of a point from a segment(which is what I assume you are referring to) you need a different approach. It is obviously slower.</p><p>First you get the above vectors the same way. Then you calculate the dot product between them. You divide that by the length of the line segment to get the length of the projection. Then you divide it again by the same value to get the parameter value of that point. If that point parameter is less than 0, then it is behind the start of the segment, if it is more than 1 then it is in front of the end of the segment. If it is between those two then it is on the segment. You use the parameter to calculate the point(or choose one of the endpoints) and then use the distance formula to find the distance from the two points.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">float</span> A <span class="k3">=</span> x <span class="k3">-</span> x1<span class="k2">;</span></td></tr><tr><td class="number">2</td><td><span class="k1">float</span> B <span class="k3">=</span> y <span class="k3">-</span> y1<span class="k2">;</span></td></tr><tr><td class="number">3</td><td><span class="k1">float</span> C <span class="k3">=</span> x2 <span class="k3">-</span> x1<span class="k2">;</span></td></tr><tr><td class="number">4</td><td><span class="k1">float</span> D <span class="k3">=</span> y2 <span class="k3">-</span> y1<span class="k2">;</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td><span class="k1">float</span> dot <span class="k3">=</span> A <span class="k3">*</span> C <span class="k3">+</span> B <span class="k3">*</span> D<span class="k2">;</span></td></tr><tr><td class="number">7</td><td><span class="k1">float</span> len_sq <span class="k3">=</span> C <span class="k3">*</span> C <span class="k3">+</span> D <span class="k3">*</span> D<span class="k2">;</span></td></tr><tr><td class="number">8</td><td><span class="k1">float</span> param <span class="k3">=</span> dot <span class="k3">/</span> len_sq<span class="k2">;</span></td></tr><tr><td class="number">9</td><td>&#160;</td></tr><tr><td class="number">10</td><td><span class="k1">float</span> xx,yy<span class="k2">;</span></td></tr><tr><td class="number">11</td><td>&#160;</td></tr><tr><td class="number">12</td><td><span class="k1">if</span><span class="k2">(</span>param <span class="k3">&lt;</span> <span class="n">0</span><span class="k2">)</span></td></tr><tr><td class="number">13</td><td><span class="k2">{</span></td></tr><tr><td class="number">14</td><td>    xx <span class="k3">=</span> x1<span class="k2">;</span></td></tr><tr><td class="number">15</td><td>    yy <span class="k3">=</span> y1<span class="k2">;</span></td></tr><tr><td class="number">16</td><td><span class="k2">}</span></td></tr><tr><td class="number">17</td><td><span class="k1">else</span> <span class="k1">if</span><span class="k2">(</span>param <span class="k3">&gt;</span> <span class="n">1</span><span class="k2">)</span></td></tr><tr><td class="number">18</td><td><span class="k2">{</span></td></tr><tr><td class="number">19</td><td>    xx <span class="k3">=</span> x2<span class="k2">;</span></td></tr><tr><td class="number">20</td><td>    yy <span class="k3">=</span> y2<span class="k2">;</span></td></tr><tr><td class="number">21</td><td><span class="k2">}</span></td></tr><tr><td class="number">22</td><td><span class="k1">else</span></td></tr><tr><td class="number">23</td><td><span class="k2">{</span></td></tr><tr><td class="number">24</td><td>    xx <span class="k3">=</span> x1 <span class="k3">+</span> param <span class="k3">*</span> C<span class="k2">;</span></td></tr><tr><td class="number">25</td><td>    yy <span class="k3">=</span> y1 <span class="k3">+</span> param <span class="k3">*</span> D<span class="k2">;</span></td></tr><tr><td class="number">26</td><td><span class="k2">}</span></td></tr><tr><td class="number">27</td><td>&#160;</td></tr><tr><td class="number">28</td><td><span class="k1">float</span> dist <span class="k3">=</span> d<span class="k2">(</span>x,y,xx,yy<span class="k2">)</span><span class="k2">;</span><span class="c">//your distance function</span></td></tr></tbody></table></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Thu, 25 Jan 2007 11:53:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thank you SO much!  It&#39;s working perfectly now. <img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" /><img src="http://www.allegro.cc/forums/smileys/grin.gif" alt=";D" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mark Oates)</author>
		<pubDate>Thu, 25 Jan 2007 13:49:12 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>SiegeLord, could I by any chance add this function to OpenLayer (Line::GetShortestDistanceTo( const Vec2D &amp;point ))? I think it&#39;d be a nice addition <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Fladimir da Gorf)</author>
		<pubDate>Thu, 25 Jan 2007 17:49:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Sure.</p><p>It should also work for 3D lines/points as well.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Thu, 25 Jan 2007 23:38:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>OK, there it is now, thanks!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Fladimir da Gorf)</author>
		<pubDate>Fri, 26 Jan 2007 00:47:47 +0000</pubDate>
	</item>
</rss>
