Code covered by the BSD License  

Highlights from


4.5 | 6 ratings Rate this file 57 Downloads (last 30 days) File Size: 6.81 KB File ID: #34874
image thumbnail




01 Feb 2012 (Updated )

Distance based interpolation along a general curve in space

| Watch this File

File Information

A common request is to interpolate a set of points at fixed distances along some curve in space (2 or more dimensions.) The user typically has a set of points along a curve, some of which are closely spaced, others not so close, and they wish to create a new set which is uniformly spaced along the same curve.

When the interpolation is assumed to be piecewise linear, this is easy. However, if the curve is to be a spline, perhaps interpolated as a function of chordal arclength between the points, this gets a bit more difficult. A nice trick is to formulate the problem in terms of differential equations that describe the path along the curve. Then the interpolation can be done using an ODE solver.

As an example of use, I'll pick a random set of points around a circle in the plane, then generate a new set of points that are equally spaced in terms of arc length along the curve, so around the perimeter of the circle.

theta = sort(rand(15,1))*2*pi;
theta(end+1) = theta(1);
px = cos(theta);
py = sin(theta);
100 equally spaced points, using a spline interpolant.

pt = interparc(100,px,py,'spline');

% Plot the result
axis([-1.1 1.1 -1.1 1.1])
axis equal
grid on
xlabel X
ylabel Y
title 'Points in blue are uniform in arclength around the circle'

You can now also return a function handle to evaluate the curve itself at any point. As well, CSAPE is an option for periodic (closed) curves, as long as it is available in your matlab installation.

[~,~,foft] = interparc([],px,py,'spline');
ans =
      0.98319 0.18257
     -0.19064 0.98151
     -0.98493 -0.17486
      0.18634 -0.98406
      0.98319 0.18257


This file inspired Active Figure Zoom For Selecting Points and Xy2sn.

Required Products MATLAB
MATLAB release MATLAB 7.12 (R2011a)
Other requirements Earlier releases will work as well.
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (16)
06 Feb 2014 Mayar

Thank You Mr.John, you found my problem very well.
With regards

05 Feb 2014 John D'Errico

Mayar -

I'm sorry, but you need to provide an example that fails. In fact, if I try to emulate what you SAID you did that fails, I have no problems at all.

x = [200 221 221 240];
y = [100 102 107 110];

ans =
200 100
205.69 97.159
211.63 94.893
217.88 94.532
220.9 99.706
220.98 106.06
222.27 112.2
228.01 114.09
234.15 112.49
240 110

It is true that if there are two consecutive points that are identical for all the variables, then it will fail. That is, this sequence of points will cause an error:

x = [200 221 221 240];
y = [100 102 102 110];

If this is indeed your issue, and NOT what you actually stated, just drop the replicates of that point! The error message indicated exactly that. Learn how to use unique to solve that, or you can find my consolidator tool on the file exchange to help with floating point near replicates.

04 Feb 2014 Mayar


this function is not working while we have two value for the same station. for instance i have two value of Z for the same station of x. ex: x=221.0 , z= 102 next value in the data set is x=221.0 , z= 107,
my data set contain such data, while i run this function, it give me error massage of " the data sites should be distinct", for t=1, and while i change t to vector suppose t=0:5:556 ( 556 end of data set), it give me again error of " all element of t must be 0<= t <=1 " . even I set the t as t=0:0.5:556.

wish you give me some instruction soon
with regards

24 Dec 2013 John D'Errico

There is no decoupling of the axes. Basic 2nd semester calc, or something like that. I won't claim it is obvious at all, since so many nice tricks in mathematics are only obvious after you see the trick. The arc length of a parametric curve is an integral of the sqrt of the sum of the squares of the first derivatives.

Since interparc wants to locate a specific point along that curve, it simply integrates that function using an ODE solver. A nice thing about the ODE solvers in MATLAB is they can identify the location where the integrated function crosses a point of interest.

The only decoupling of the axes is the use of splines on each dimension independently as a function of the linear chordal arc length. This allows me to define a parametric curve in an arbitrary number of dimensions, (x(t),y(t),z(t),...), and then form differentials at any point along that curve.

So we have the arc length as:

L = int(sqrt(x'^2 +y'^2 + ...))

where the differentials are with respect to t, the linear chordal arc length.

24 Dec 2013 Mathew

This program is really impressive. I wanted to understand the math a bit more since it seems to be unique relative to many other interpolation methods. From what I can understand for the spline case, is it using a cubic spline interpolation over each dimension independently, then using differential equations to solve for the length of the curve for each axis? For a curve in 3 dimensions, xyz, I am confused if it is decoupling each axis or it is solving them together.

If anyone understands how this actually works it would be great to hear.

11 Nov 2013 Dinesh

Thanks so much John. It really helped me in my hard time. This program is very nice, it is fast also. Even if I input smaller number of points it adjust them to the required number of equally spaced points.

Thank you again.

03 Mar 2013 Evgeny Pr  
19 Jan 2013 Jon


Thanks for the response! I've been playing with the linear interpolation and you're right--it's much faster. It also seems to be accurate enough for my model. Thanks for your input!

18 Jan 2013 John D'Errico

Jon - you can gain considerable speed by use of the 'linear' method in the code, if you can afford the loss in accuracy. It will be MUCH faster (as much as 1000 times faster), because I do the interpolation for that method in a different way from the other methods.

Those smoother methods in this tool are forced to call an odsolver for the interpolation, so the time taken is much higher for those methods. The only possibility is that I might have offered a different ode solver than ode45, but it is the fastest solver for these problems in my tests.

18 Jan 2013 Jon

Excellent code.

I have only one complaint, which is the code takes awhile to run. For some applications this doesn't matter much, but I'm trying to resample a stream centerline after each time step in a 100's of time steps numerical model, and run times have become too large for me to use this (at least with each iteration). Do you have any suggestions for speeding it up? I tried going line-by-line through the code to find the bottleneck, but I was unsuccessful.

16 Aug 2012 John D'Errico

Iain - You may find pchip a better choice for that class of curve. However, you have a valid point that there is a problem for this curve when a spline is used. I've just sent in a new version that should do better. It should appear in the morning.

15 Aug 2012 Iain

Hi John. It is only a problem when pushing the spline fit quite hard, i.e. when there is a big gap between data. Then t and ti are not necessarily close. Test data and program at:

Try with and without change suggested. Thanks again for the code, hope that helps.

15 Aug 2012 John D'Errico

Iain - correct, there was a problem in recognizing contractions. I accidentally used strcmpi, not strncmpi. Fixed, and uploaded to appear when they process it.

As far as derivatives, there is no need to move the derivative evaluation into the loop. ppval is fully vectorized, so no explicit loop is needed for that part. In fact, putting it inside a loop will just slow things down. If you have found a case where this fails please let me know, but the code does run correctly in my tests, as I would expect.

15 Aug 2012 Iain

Excellent function, just what I needed. Thanks.

Slight bug in evaluating dudt - the (nargout > 1) block should be moved into the i=1:nt loop, and evaluated at ti, i.e.

for i=1:nt
%stuff - then
if nargout > 1
for j = 1:ndim
dudt(i,j) = ppval(spld{j},ti);
Also does not accept contractions of 'spline' etc. as equivalent arclength function does.

26 Jul 2012 John D'Errico

Prabhu - I don't know what you are doing to generate nans. Please send me an example that causes it to happen, as none of my tests generated NaNs.

With one exception. There is actually one case I can find where interparc returns NaN. That is when I passed in a vector with NaNs in it already. In that case, how would one expect it not to return NaN? What logical action should it do when one asks it to interpolate a curve that is undefined at some set of points?

26 Jul 2012 Prabhu

Thanks for this excellent code.
I'm facing one problem when I use this code. It works fine in most cases. But sometimes its churning NaNs as one of the points. Can you help me out with this issue?

04 Mar 2012

Add csape for periodic fits, and return a function handle for external evaluation.

15 Aug 2012

Fixed bug in recognizing contractions

16 Aug 2012

Fix for dudt at the proper points.

Contact us