How to use pchip to interpolate between data points in cartesian coordinate format
6 ビュー (過去 30 日間)
古いコメントを表示
I am trying to use pchip to interpolate between a series of data points. My data are spatial (lat/long) but have been converted into meters in a projected cartesian coordinate system (UTM 31N- i.e. x= 431804m, y=4571664m).
The code that I am using is below, but for some reason I get error messages when trying to create objects 't' and 'p'. long_m is a 1xcolumn matrix of longitude in meters, lat_m is a 1xcolumn matrix of latitude in meters, 0.01667= 1/60th in decimal, specifying that I want to end up 60 times more data points than I have now via the interpolation:
x=long_m;
y=lat_m;
t=x(1,1):0.016667:x(211,1);
p=pchip(x,y,t);
Output message:
t =
Empty matrix: 1-by-0
p =
Empty matrix: 1-by-0
I thought that the function would return a string of numbers that relate to my interpolated points, but instead I end up with an empty 't' matrix and an empty 'p' matrix. What am I doing wrong?
Some example data is below:
x= [518666 521872 519984 519591 518800];
y= [4694989 4667173 4644884 4645622 4647104];
I am new to matlab (although I have knowledge of programming language from R), so any advice would be greatly appreciated.
0 件のコメント
採用された回答
Kelly Kearney
2013 年 8 月 26 日
The all-increasing or all-decreasing issue you're encountering isn't a restriction of pchip, but rather of the : operator. If you try to define a vector with a positive step size but decreasing values, you'll get an empty vector. For example:
>> 5:1:2
ans =
Empty matrix: 1-by-0
I'm guessing that what you're really after in this case is a parametric interpolation, where you "fill in" points in both the x- and y-direction.
% Some fake data
theta = linspace(0, 2*pi, 10);
x = cos(theta);
y = sin(theta);
% Interpolate
told = 1:10;
tnew = linspace(1,10,50);
xnew = pchip(told, x, t);
ynew = pchip(told, y, t);
% Plot
plot(x,y,'-b.', xnew, ynew, '-ro');
You can get more sophisticated to evenly space your final points, but this gives you there general idea.
3 件のコメント
Kelly Kearney
2013 年 8 月 26 日
To approximate that, use the same idea as above, but define told based on distance along the curve:
d = sqrt((x(2:end) - x(1:end-1)).^2 + (y(2:end) - y(1:end-1)).^2);
told = [0 cumsum(d)];
tnew = linspace(0, max(told), 50);
Note that the key to this method isn't the use of linspace as opposed to :; I could have gotten approximately the same results by saying
tnew = 0:0.125:1;
The key is that I'm using a third variable ( t ) to represent "distance along the curve," and then interpolating both x and y against that.
その他の回答 (1 件)
Shashank Prasanna
2013 年 8 月 23 日
編集済み: Shashank Prasanna
2013 年 8 月 23 日
This works perfectly fine for me:
>> x= [518666 521872 519984 519591 518800];
>> y= [4694989 4667173 4644884 4645622 4647104];
>> p=pchip(x,y,x)
p =
4694989 4667173 4644884 4645622 4647104
p=pchip(x,y,x(1):0.01:x(end));
7 件のコメント
Shashank Prasanna
2013 年 8 月 26 日
Rhiannon, your Y can be increasing or decreasing. You can always sort your X which is meant to be increasing on the X axis. Your Y could be anything and PCHIP will happily interpolate for new X.
[sortX, idx] = sort(X);
sortY = Y(idx);
This way you can always take the sorted X to interpolate
newY = pchip(sortX,sortY,sortX(1):0.01:sortX(end));
And this doesn't change your data or results at all.
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!