Search code examples
matlabinterpolationspline

How can I interpolate time and velocity of 3D data?


I am using MATLAB to try to interpolate data for an object that is moving in 3D space at variable speed. I am starting with an array with columns: time, x, y, z, velocity. I want to interpolate the xyz path, but I can't figure out how to interpolate time and velocity at the same points that the xyz interpolation produces.

My problem is that if I interpolate using the cscvn function and fnval, then the interpolated points are not evenly spaced (yellow stars in the below image) and I'm not sure how to interpolate the times and speeds for those points. Alternatively if I interpolate with interp1, it does produce evenly spaced points, but the interpolation is not better with cscvn.

I tried doing a 5 dimensional interpolation, and that didn't produce the desired results. I'm not sure how to deal with this problem.

How can I interpolate the xyz path, and then interpolate the time and velocities at those unevenly spaced points?

Here is the code I am using:

% Generate some fake data
flightPathRate = 1;
x = (-5:flightPathRate:10)';
y = sin(4*x);
z = linspace(3,5, length(x))';
t = ((0:length(x)-1)*flightPathRate)';
vel = x.^2 + 10;

pathData = [t x y z vel];

% Interpolate with cscvn
curve = cscvn(pathData(:,2:4)');

plot3(x, y, z, 'ob-')
hold on
fnplt(curve) 

% Evaluate the spline curve created with cscvn at finer points.
splinePoints = fnval(curve, 0:0.1:16);
plot3(splinePoints(1,:), splinePoints(2,:), splinePoints(3,:), '*')

%% Interpolate with interp1
cs = cat(1,0,cumsum(sqrt(sum(diff([x, y, z], [], 1).^2, 2))));
dd = interp1(cs, [x, y, z], unique([cs(:)' linspace(0,cs(end),100)]), 'spline')

hold on
plot3(dd(:,1), dd(:,2), dd(:,3), '.r-')
axis image, view(3), legend({'Original', 'Spline Curve with cscvn/fnplt', 'Interp. Points with cscvn/fnval', 'Interp. Spline with interp1'})

Here is the plot produced. Interpolation Plot MATLAB


Solution

  • I ran your code successfully.
    Q.1: Please explain the role of velocity in your code. You define vel as fake data, at every fake data time point. But it is totally unrelated to the x,y,z fake data.
    Answer to your question about how to determine the times associated with the x,y,z points which you get from cscvn(): there is no reasonable proven way to do that. Therefore I recommend that you not use cscvn(). Its main advantage is to make periodic splines, i.e. splines for cirves that return to their origin. But this problem is not like that. Your interpolated data from interp1() looks good to me. I would go with it. It is a simple matter to esitmate velocity (|v| and vx, vy, vz) from the interpolated points. When you do, I recommend using the interpolated points before and after each point, to get an un-shifted estimate in the middle. Try the 'makima' or 'pchip' method with interp1(), instead of the 'spline' method, if you think 'spline' overshoots too much.