How can I interpolate between my original endpoints with cscvn?

14 ビュー (過去 30 日間)
Greg Kommel
Greg Kommel 2021 年 1 月 15 日
回答済み: John D'Errico 2021 年 1 月 15 日
I am attempting to interpolate a 3D path using cubic splines. I've tried to interpolate using either cscvn or interp1. The issue I'm running into with cscvn is that when I use fnval to evaluate the cubic spline at various points, I can't figure out how to only get points between my original end points. Perhaps I'm not understanding something in how cscvn and fnval work. The only way I've figured out how to get the interpolated points to end near the original endpoint is by guess and check with the fnval input values. The endpoints I pick to evaluate seem arbitrary along the curve (i.e. 0:0.1:16 gets me to the third to last original point and 0:0.1:18.8 gets me close to the original endpoint).
When I use interp1, the interpolated points are all strictly inside of the original endpoints, but the interpolation is not as good in my opinion.
How can I get cscvn and fnval to produce points only inside of my original endpoints?
Here is my code and the plot showing what I'm talking about. The blue line is the original data, the orange line is the interpolated line using fnplt, the yellow stars are the interpolated points found using cscvn/fnval (notice it doesn't go all the way to the end), and the red line is the interp1 plot (which produces a dispreferred interpolation).
% Generate some fake data
flightPathRate = 1;
x = -5:flightPathRate:10;
y = sin(4*x);
z = linspace(3,5, length(x));
% Interpolate with cubic spline
curve = cscvn(pathDataLocal(:,2:4)');
% Plot the cubic spline along with original points
plot3(x, y, z, 'ob-')
hold on
fnplt(curve)
splinePoints = fnval(curve, 0:0.1:16);
plot3(splinePoints(1,:), splinePoints(2,:), splinePoints(3,:), '*')
% Cubic spline using alternative method
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');
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'})
hold off

回答 (1 件)

John D'Errico
John D'Errico 2021 年 1 月 15 日
I think you do not understand splines. (Not uncommon.)
Splines have the property that they can produce results that lie outside of the values you had for your function. They don't care, as long as the result is a smoothly differentiable function. And in order to get that result, AND interpolate the data, then you get predictions that lie outside of your data. This will happen with a spline. Sorry, but it will.
If you want something that has better properties, then as you found, you can use a linear interpolant. This will be a piecewise linear function, but it is just that, linear segments. Not very smooth.
The use of 'spline' in interp1 is your problem. Instead, you can trade off SOME degree of smoothness, yet get a result that will stay inside your data. That is, use the 'pchip' method. as you did with interp1, but use pchip insted of spline.
pchip has the property that it will never introduce extrema into the interpolation that are not already there. And that is what you need.

カテゴリ

Help Center および File ExchangeSpline Construction についてさらに検索

製品


リリース

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by