Move a dot along a path

359 Views Asked by At

I have a multi-point, straight line path - to keep it simple it has three points, A B & C.

  • A = 60,410
  • B = 127.5,410
  • C = 195,240

This is the 'template' path, I need to animate a dot moving along this path, lets keep it simple and say there are 10 steps.

So, step 1 = point A and step 10 = point C, I need to calculate equidistant points along this path.

What is the most efficient way to determine each equidistant point?

4

There are 4 best solutions below

4
On

There are many paths that pass through those three points. There's an arc of a circle, for instance. You could take that arc and divide it into 10 equal parts. There's also the graph of some quadratic in $x$, but finding arclengths on that is likely to be a bit messy. There's the Catmull-Rom spline through those 3 points (with various end-conditions possible), but finding arclengths on that is likely to be almost impossible.

In short: I think you need to clarify the problem and nail down exactly which path you're speaking of; only then can we hope to tell you how to calculate equidistant points.

(By the way, do you mean "straight line distance" or "distance along the curved path itself"?)

2
On

Appologies, I am a programmer, not a mathimatician so I am not used to marking up using standard notation. here is some pseudo code to describe how i solved the problem.

first step is to calculate the total distance of the path so distance from point[n] to point[n+1]:

for p in paths
    dx = points[p+1].x - points[p].x
    dy = points[p+1].y - points[p].y

    distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2))

then i need to figure out how far along this total distance the dot is up to

step = n
stepDistance = (totalDistance / totalSteps) * step

then i need to determine which segment of the path this distance falls upon and how far along that segment the dot should be placed

dist = 0
for p in paths
    dist += path.distance
    if stepDistance <= dist
         stepPath = p
         stepPathDist = stepDistance - (dist - path.distance)

lastly, I resolve the coordinates of the point along the path segment by working out the paths angle and moving along this angle the correct distance

dx = points[stepPath+1].x - points[stepPath].x
dy = points[stepPath+1].y - points[stepPath].y
angle = Math.atan2(dy, dx)
x = (Math.cos(angle) * stepPathDist) + points[stepPath].x
y = (Math.sin(angle) * stepPathDist) + points[stepPath].y

this works however i'm sure can be expressed much more mathematically, feel free to improve!

8
On

Method

If it is an straight line path then all you need is the start point $\vec{p}_1$ and the end point $\vec{p}_n$

  1. Find the distance between the end points $\ell = \| \vec{p}_n - \vec{p}_1 \|$
  2. Find the direction of the line $\vec{e} = \frac{\vec{p}_n - \vec{p}_1 }{\ell} $
  3. Find the i-th point like this

$$ \vec{p}_i = \vec{p}_1 + (\vec{p}_n - \vec{p}_1) \frac{i-1}{n-1} = \vec{p}_1 + \vec{e} \ell \;\frac{i-1}{n-1} $$

Example

If you have $\vec{p}_1 = (60,410)$ and $\vec{p}_n = (195,240)$ and you want to split into $n=10$ points (9 segments) then

  1. $\ell = \| (155, -170) \| = 230.0543$
  2. $\vec{e} = (155, -170)/230.0543 = (0.6738, -0.7390)$
  3. The points are $$\begin{align} \vec{p}_1 &= (60,410) \\ \vec{p}_2 &= (60,410) + (155, -170) \frac{1}{9} = (57.2222, 391.1111) \\ \vec{p}_3 &= (60,410) + (155, -170) \frac{2}{9} = (74.4444, 372.2222) \\ \vdots \\ \vec{p}_9 &= (60,410) + (155, -170) \frac{8}{9} = (177.7778, 258.8889) \\ \vec{p}_{10} &= (60,410) + (155, -170) = (195,240) \end{align} $$
2
On

In Mathematica:

a = {60,410};
b = {127.5,410};
c = {195,240};

Animate[
 Graphics[{{Red, PointSize[0.02], Point[#]} & /@ {a, b, c},
   If[0 < t < .5, {Point[(1 - 2 t) a + 2 t b]}, 
    Point[(2 - 2 t ) b + (-1 + 2 t) c]]}], 
{t, 0, 1}]