Interpolating discrete points along a spline

479 Views Asked by At

I have 2 lines which i need to connect with a spline (or some other curve, but not the circle; it has to gradually increase its turning angle). The lines cross each other so the curve should make a kind of loop to connect them. The known points are P, P1, PS and P2, and the curve must begin and end at point P. It also may or may not pass directly through all the other points (P1, PS and P2):

enter image description here

Since i need this for a computer project im actually looking for a 2 step solution:

  1. Curve interpolation (done, kind of, using scipy)
  2. Interpolation of discreet points along the fitted curve (it would be nice to have a kind of parameter function f(length) which would calculate x,y points on the curve for me), or even better a function accepting a number between 0 and 1, where 0 would yield first point, and 1 would yield last point (in my case the same point)

What would be the best way to go about this?

I managed to go so far to interpolate a spline using scipy.interpolate.UnivariateSpline but there aren't any methods available to calculate points on the spline.

https://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.interpolate.UnivariateSpline.html#scipy.interpolate.UnivariateSpline

Sorry if the terms i used probably aren't the most mathematical.

1

There are 1 best solutions below

3
On BEST ANSWER

I'm going to change the notation a little, for simplicity. Let $\mathbf{U}$ be a unit vector in the direction of $\mathbf{P}_1 - \mathbf{P}$, and let $\mathbf{V}$ be a unit vector in the direction of $\mathbf{P}_2 - \mathbf{P}$, and let's use $\mathbf{Q}$ to denote $\mathbf{P}_s$.

Then any point on the line $\mathbf{P}\mathbf{P}_1$ can be written in the form $\mathbf{P} + \alpha \mathbf{U}$, for some $\alpha$. Similarly, any point on the line $\mathbf{P}\mathbf{P}_2$ can be written in the form $\mathbf{P} + \beta \mathbf{V}$, for some $\beta$.

We need to find two such points $\mathbf{P} + \alpha \mathbf{U}$ and $\mathbf{P} + \beta \mathbf{V}$ such that the mid-point of the line between them is $\mathbf{Q}$. In other words, we need to find $\alpha$ and $\beta$ such that $$ \tfrac12\big((\mathbf{P} + \alpha \mathbf{U}) + (\mathbf{P} + \beta \mathbf{V})\big) = \mathbf{Q} $$ This simplifies to $$ \alpha \mathbf{U} + \beta \mathbf{V} = 2(\mathbf{Q} - \mathbf{P}) $$ If we take dot products of this equation with $\mathbf{U}$ and $\mathbf{U}$ in turn, we get two linear equations that we can solve to get $\alpha$ and $\beta$.

Now construct a Bezier curve $\mathbf{C}(t)$ with control points $$ \mathbf{P}_1 = \mathbf{P} \quad ; \quad \mathbf{P}_2 = \mathbf{P} + \tfrac43\alpha\mathbf{U} \quad ; \quad \mathbf{P}_3 = \mathbf{P} + \tfrac43\beta\mathbf{V} \quad ; \quad \mathbf{P}_4 = \mathbf{P} $$ It's easy to confirm that this curve has the desired start and end points and start and end tangents. So, specifically, for example, $\mathbf{C}(0) = \mathbf{C}(1) = \mathbf{P}$. What is probably not so obvious is that $\mathbf{C}(0.5) = \mathbf{Q}$, but in fact this is true.

To calculate points on this curve, you can use the normal Bezier curve equations. $$ \mathbf{C}(t) = (1-t)^3 \mathbf{P}_1 + 3t(1-t)^2 \mathbf{P}_2 + 3t^2(1-t) \mathbf{P}_3 + t^3\mathbf{P}_4 $$

Edit I just re-read your question, and discovered that you don't necessarily want the curve to pass through the point $\mathbf{P}_s$. If that's the case, you can use any values of $\alpha$ and $\beta$ -- you don't need to find special values by solving the system of linear equations.