Message Boards Message Boards

0
|
1155 Views
|
0 Replies
|
0 Total Likes
View groups...
Share
Share this post:

Distance Between a Point and a Line Segment

In[1]:= (* Square of the distance between two points *)
distsqr[{{x1_, y1_}, {x2_, y2_}}] = (x1 - x2)^2 + (y1 - y2)^2;

In[2]:= (* Derivative of the distance squared between a point {x,y} \
and a point on a line passing through {x1,y1} and {x2,y2}, \
parameterizing the point on the line with the variable t *)
eqs = D[distsqr[{{x, y}, { x1 + t (x2 - x1), y1 + t (y2 - y1)}}], {t}]

Out[2]= 2 (x1 - x2) (x - x1 - t (-x1 + x2)) + 
 2 (y1 - y2) (y - y1 - t (-y1 + y2))

(* Minimize the distance squared by setting the derivative equal to 0 \
*)
ln = Solve[eqs == 0, t] // FullSimplify

Out[3]= {{t -> -(((x - x1) (x1 - x2) + (y - y1) (y1 - y2))/((x1 - 
       x2)^2 + (y1 - y2)^2))}}

In[4]:= (* The value of t, the distance between the point and \
infinite line and the point on the infinite line *)
dsqrpos[{{x1_, y1_}, {x2_, y2_}}][{x_, 
   y_}] = {t, 
     distsqr[{{x, y}, {xt, yt}}], {xt, yt}} /. {xt -> 
      x1 + t (x2 - x1), yt -> y1 + t (y2 - y1)} /. ln[[1]] // 
  FullSimplify

Out[4]= {-(((x - x1) (x1 - x2) + (y - y1) (y1 - y2))/((x1 - 
     x2)^2 + (y1 - y2)^2)), (x1 y - x2 y - x y1 + x2 y1 + x y2 - 
   x1 y2)^2/((x1 - x2)^2 + (y1 - y2)^2), {(
  x (x1 - x2)^2 + (x2 (-y + y1) + x1 (y - y2)) (y1 - y2))/((x1 - 
     x2)^2 + (y1 - y2)^2), 
  y1 - (((x - x1) (x1 - x2) + (y - y1) (y1 - y2)) (-y1 + y2))/((x1 - 
      x2)^2 + (y1 - y2)^2)}}

In[5]:= (* The distance between a point {x,y} and a line segment \
between {x1,y1} and {x2,y2} and the point on the line.  If t is <= 0 \
then the point on the line is {x1,y1}.  If t >= 1, the point on the \
line is {x2,y2}.  Otherwise it is the solution from dsqrpos  *)
dsqrposl[{{x1_, y1_}, {x2_, y2_}}][{x_, y_}] :=
 Block[{dsqposv, res},
  dsqposv = dsqrpos[{{x1, y1}, {x2, y2}}][{x, y}];
  res = Which[
    dsqposv[[1]] <= 0, {distsqr[{{x1, y1}, {x, y}}]^(1/2), {x1, y1}},
    0 < dsqposv[[1]] < 1, {dsqposv[[2]]^(1/2), dsqposv[[3]]},
    dsqposv[[1]] >= 1, {distsqr[{{x2, y2}, {x, y}}]^(1/2), {x2, y2}}
    ]
  ]

In[6]:= (* test case *)
AbsoluteTiming @ dsqrposl[{{2, 3}, {3, 4}}][{5/2, 3}]

Out[6]= {0.0000716, {1/(2 Sqrt[2]), {9/4, 13/4}}}

In[7]:= (* compare to Mathematica function RegionDistance *)
AbsoluteTiming @ RegionDistance[Line[{{2, 3}, {3, 4}}], {5/2, 3}]

Out[7]= {0.0095428, 1/(2 Sqrt[2])}

In[8]:= (* compare to Mathematica function RegionNearest \
*)AbsoluteTiming @ RegionNearest[Line[{{2, 3}, {3, 4}}], {5/2, 3}]

Out[8]= {0.0070957, {9/4, 13/4}}
POSTED BY: Frank Kampas
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract