Plotting a smooth curve from points

조회 수: 55 (최근 30일)
Osama Anwar
Osama Anwar 2021년 1월 23일
댓글: Osama Anwar 2021년 1월 27일
I'm trying to plot a smooth line for 6 points in such a way that slope at each is zero. I have successfully achieved it for middle points using 'pchip' but I also want it for extreme points i.e. x=0 and x=15 which I am unable to do while using 'pchip'.
Here is my code
clear
clc
x = [0;3;6;9;12;15];
y = [0;1.9190;-3.2287;3.5133;-2.6825;1];
xi = linspace(min(x), max(x), 150); % Evenly-Spaced Interpolation Vector
yi = interp1(x, y, xi, 'pchip');
figure
plot(x, y, 'b')
hold on
plot(xi, yi, '-r')
hold off
grid
xlabel('X')
ylabel('Y')
legend('Original Data', 'Interpolation', 'Location', 'NE')
  댓글 수: 3
Osama Anwar
Osama Anwar 2021년 1월 23일
1) It seems very much zero to me. if you increase points from 150 to say 15000 and zoom in at say 3 then you would find line flattening that is one indication.
2) It is a mode shape of building. It will be used to find displacements and at max displacements your velocity is zero.
Adam Danz
Adam Danz 2021년 1월 23일
편집: Adam Danz 2021년 1월 23일
The slopes are very close to 0. Vertical lines show the original x-values without the endpoints.
x = [0;3;6;9;12;15];
y = [0;1.9190;-3.2287;3.5133;-2.6825;1];
xi = linspace(min(x), max(x), 150);
yi = interp1(x, y, xi, 'pchip');
% compute slopes
s = gradient(yi, 150);
plot(xi,s)
yline(0)
arrayfun(@xline, x(2:end-1)

댓글을 달려면 로그인하십시오.

채택된 답변

Bruno Luong
Bruno Luong 2021년 1월 24일
편집: Bruno Luong 2021년 1월 24일
Direct analytic method using piecewise cublic polynomial. The curve is first-order differentiable, but not second order differentiable (as with sublic spline or result with my first answer using BSFK)
x = [0;3;6;9;12;15];
y = [0;1.9190;-3.2287;3.5133;-2.6825;1];
[xx,is] = sort(x(:));
yy = y(is);
yy = yy(:);
dx = diff(xx);
dy = diff(yy);
y0 = yy(1:end-1);
n = numel(xx)-1;
coefs = [-2*dy./(dx.^3), 3*dy./(dx.^2), 0*dy, y0];
pp = struct('form', 'pp',...
'breaks', xx(:)',...
'coefs', coefs,...
'pieces', n, ...
'order', 4,...
'dim', 1);
figure
xi = linspace(min(x),max(x));
yi = ppval(pp,xi);
plot(x,y,'b-o',xi,yi,'r');
xlim([min(x),max(x)])
grid on
Propably this is how John generates his curve
x = [0 1 1.5 2 4];
y = x;
  댓글 수: 10
Bruno Luong
Bruno Luong 2021년 1월 27일
Sorry you are on your own if you use symbolic variables. Once you modify/adap the code it's yours.
I don't have this toolbox to help, even if I want to .
Osama Anwar
Osama Anwar 2021년 1월 27일
Ok no problem Thanks.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Adam Danz
Adam Danz 2021년 1월 23일
편집: Adam Danz 2021년 1월 23일
You could add values to the beginning and end to make the curve continuing in both directions. The example below uses hard-coded values but it wouldn't be difficult to programmatically extend the trend in the opposite y-direction on each side of X.
x = [-3;0;3;6;9;12;15;18];
% ^^ ^^ added
y = [2;0;1.9190;-3.2287;3.5133;-2.6825;1;-2];
% ^ ^^ added
xi = linspace(min(x), max(x), 150);
yi = interp1(x, y, xi, 'pchip');
% Trim the additions
rmIdx = xi<0 | xi>15;
xi(rmIdx) = [];
yi(rmIdx) = [];
x([1,end]) = [];
y([1,end]) = [];
figure
plot(x, y, 'b')
hold on
plot(xi, yi, '-r')
hold off
grid
xlabel('X')
ylabel('Y')
legend('Original Data', 'Interpolation', 'Location', 'NE')
  댓글 수: 13
Adam Danz
Adam Danz 2021년 1월 24일
Yeah, it's not a robust hack.
I'm following the conversation. John and Bruno have great points.
Osama Anwar
Osama Anwar 2021년 1월 24일
Yeah I get your point.

댓글을 달려면 로그인하십시오.


Bruno Luong
Bruno Luong 2021년 1월 24일
편집: Bruno Luong 2021년 1월 24일
No extra points needed (but you might add to twist the shape of the curve in the first and last interval),
Spline order >= 8th is needed using my FEX
x = [0;3;6;9;12;15];
y = [0;1.9190;-3.2287;3.5133;-2.6825;1];
interp = struct('p', 0, 'x', x, 'v', y);
slope0 = struct('p', 1, 'x', x, 'v', 0*x);
% Download BSFK function here
% https://www.mathworks.com/matlabcentral/fileexchange/25872-free-knot-spline-approximation
pp = BSFK(x,y, 9, length(x)-1, [], struct('KnotRemoval', 'none', 'pntcon', [interp slope0]));
% Check
figure
xi = linspace(min(x),max(x));
yi = ppval(pp,xi);
plot(x,y,'b',xi,yi,'r');
for xb=pp.breaks
xline(xb);
end
grid on
  댓글 수: 4
Osama Anwar
Osama Anwar 2021년 1월 24일
1st and 3rd are not the one I need. 2nd one without Adam addition would do the trick. Thanks for taking out time to answer. Very much appreciated
Bruno Luong
Bruno Luong 2021년 1월 25일
편집: Bruno Luong 2021년 1월 26일
The shape might not meet your (un-written) expectation but it definitively meets every requiremenrs you state in the question. The interpolating solution is trully "smooth" (I believe up to the 7th derivative order is continue) with zero slope at the give abscissa.
This illustres one of the difficulty using spline fitting/interpolating: the chosen boundary conditions affects globally the shape of the interpolation.
It might be still useful for futur readers.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Preprocessing Data에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by