0
$\begingroup$

Suppose that I have two points in the xy plane: pt1 and pt2init. pt1 is fixed in space, while pt2init is supplied by the user (but its returned value will in general be different). I wish to write a function that will return the coordinates of a point pt2result that is located a user-specified distance d from pt1 along the line connecting pt1 and pt2init and that is closest to pt2init.

I wrote the following function f (and its supporting function dist2D, which finds the distance between two points with x- and y-coordinates):

dist2D[pt1_, pt2_] := 
 Sqrt[(pt2[[1]] - pt1[[1]])^2 + (pt2[[2]] - pt1[[1]])^2]

f[pt1_, pt2_, d_] := Module[{line, x2result, y2result, pt2result},
  line = Normal[LinearModelFit[{pt1, pt2}, xvar, xvar]];
  Solve[{dist2D[{pt1[[1]], pt1[[2]]}, {x2result, y2result}] == d,
    y2result == (line /. xvar -> x2result)},
   {x2result, y2result}];
  pt2result = {x2result, y2result}
  ]

But when I run it:

f[{0.77825, 0.551441676}, {0.7075, 0.67398427}]

it does not return anything. Is it possible to do constrained optimization like this?

$\endgroup$
1
  • 2
    $\begingroup$ BTW: your dist2D[] is built-in as EuclideanDistance[]. $\endgroup$ May 28, 2012 at 16:42

2 Answers 2

4
$\begingroup$

Implementation

You could use a very simple function:

f[p1_, p2_, d_] := Normalize[p2 - p1] d + p1

This will return a point on the line connecting p1 and p2, a distance d from p1 towards p2.

Discussion

Using vector arithmetic is usually very convenient for analytic geometry. Fortunately in Mathematica there's no need to separate the components of the vectors (e.g. writing p1[[1]]). We can add two vectors directly. Normalize[p2-p1] will construct the unit vector pointing from p1 in the direction of p2. Multiplying it by d and adding it to p1 gives what you asked for.

Trying it out

p1 = {0, 0};
Manipulate[
 Graphics[{PointSize[0.03], Point[p1], 
   Text["\!\(\*SubscriptBox[\(P\), \(1\)]\)", p1, {-2, 2}], Point[p2],
    Text["\!\(\*SubscriptBox[\(P\), \(2\)]\)", p2, {-2, 2}], 
   Line[{p1, p2}], Red, Point[f[p1, p2, d]]}, 
  PlotRange -> {{-1, 1}, {-1, 1}}],
 {{p2, {.5, .5}}, Locator}, {{d, 0.2}, 0, 1}
]

Mathematica graphics

$\endgroup$
3
$\begingroup$

(Too long for a comment.)

Only simple math is needed; no optimization required at all. Consider the vector equation $\mathbf x(t)=(1-t)\mathbf p_1+t\mathbf p_2$ for the line segment joining $\mathbf p_1$ and $\mathbf p_2$. The distance between $\mathbf p_1$ and $\mathbf x(t)$ is (check this!) $dt$, where $d$ is the length of the segment joining $\mathbf p_1$ and $\mathbf p_2$. You should now be able to reckon out the value of $t$ needed so that it is at a given distance from $\mathbf p_1$.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.