MCA
MCA

Reputation: 17

MATLAB - interpolating a 2D curve with multiple Y's per X

I would like to interpolate a data set, but a given X can have multiple Y's, example given below:

A(:,1:2,1)=
95.2343   70.6159
   96.4501   71.5573
   97.4430   72.7315
   98.9743   72.8699
  100.0470   71.7690
  100.3872   70.2699
  100.7797   68.7837
  102.1478   68.0814
  103.6851   68.0521
  105.0307   68.7966
  105.8972   70.0666
  106.7177   71.3665
  107.7095   72.5416
  108.9175   73.4924
  110.3574   74.0309
  111.8943   73.9859
  113.3936   73.6446
  114.6645   72.7794
  115.5911   71.5522
  116.2426   70.1591
  116.3922   68.6286
  116.3503   67.0914
  116.7771   65.6147
  117.9045   64.5692
  119.4065   64.2425
  120.9432   64.2923
  122.2526   65.0975
  122.9486   66.4682
  122.8841   68.0043
  122.5492   69.5051
  122.2403   71.0109
  122.0819   72.5402

These are points along the body of a snake, digitized from top-down video. Their posture frequently results in 2 or more Y points per X, and because they turn (often dramatically) while I need to maintain a consistent XY framework, I can't just rotate my X and Y.

I can make a spline function using cscvn, and when plotted using fnplt it looks great! But the moment I try to get values back using ppval, it all goes to crap and I get two curves that look nothing like the snake or what's shown in fnplt.

IMAGE HERE: https://i.sstatic.net/Os8vQ.jpg

All I want is to fit a curve to those points, and convert that curve to a series of maybe 200 XY points.

I'm assuming that there is some obscenely simple answer, some command I've just never turned up in my searching, but I cannot find it for the life of me. This is quite far outside my usual skillset (I'm more used to crawling through swamps catching anything scaly or slimy), so I'm sure I'm overlooking something totally obvious to a skilled MATLAB user.

Thanks!

Upvotes: 0

Views: 2287

Answers (2)

MCA
MCA

Reputation: 17

OK, thanks to Yvon and Trogdor, I managed to crudely cludge together some code:

ht=[1:32];
tx=linspace(1,32,500);
m=ht;
m(2:3,:)=squeeze(A(:,:,i))';
m1=m(1,:);
m2=m(2,:);
m3=m(3,:);
SFX=spline(m1,m2);
pSFX=ppval(SFX,tx);
SFY=spline(m1,m3);
pSFY=ppval(SFY,tx);
AS(:,1,i)=pSFX;
AS(:,2,i)=pSFY;
plot(AS(:,1,i),AS(:,2,i),'Marker','o');

It's riddled with pointless variables, steps, and redundancies, but I'm an anatomist, so that makes me comfortable (seriously, google 'recurrent laryngeal nerve').

How do I add reputation for y'all?

Upvotes: 0

Trogdor
Trogdor

Reputation: 1346

Perhaps this is what you already tried, but a comment was a bit small, so here is one idea that may help you

x = [1 2 3 4 5 6 7 6 5];
y = [1 4 4 3 2 2 2 3 4];
t = 1:length(x);
figure; plot(x,y)


xx = interp1(t,x,1:.01:length(x),'pchip');
yy = interp1(t,y,1:.01:length(x),'pchip');

hold on; plot(xx,yy,'g')

I avoided the unique values restriction on interp by interpolating x and y both as a function of t.

Upvotes: 4

Related Questions