Interpolating 2D position data

4 Ansichten (letzte 30 Tage)
John Alperto
John Alperto am 24 Dez. 2021
Beantwortet: Voss am 27 Dez. 2021
I have some data that was acquired from an individual that moved a cursor from one target that was presented on a screen to another straight-ahead target that was 10 centimeters away from the original start position. I have 15 movements from this person. The data I have is the instantaneous x-position x(t) and y-position y(t) of the cursor for each movement. Because the individual did not move the mouse at the exact same speed from one movement to another, the number of samples for each movement is not the same. Below, I am showing the x-positions, y-position, and complete x-y trajectory for all movements. I am attaching the data here as well. Hopefully this gives a sense for the nature of the data. Note that the cursor position always start at the [0,0] point, but don't always exactly end at the [0,10] point.
I am tasked with linearly interpolating the x-positions of the cursor onto a vector of y-positions every 0.05cm in order to align the cursor measurements across movements (that is, I must obtain x(y). I would like to present my code below and get some feedback about whether or not I am doing this correctly:
%% Try interpolating x as a function of y (i.e., transform x(t) to x(y))
%Goal is to linearly interpolated the x-positions of the cursor onto a
%vector of y-positions every 0.05cm to align the hand path measurements
%across movements
clear all;
close all;
home;
%load the data: xpos & ypos
load('pos_data.mat')
%create cell array that will hold interpolated data
x_interp = cell(size(xpos));
y_interp = cell(size(ypos));
%construct grid vector
ypos_grid = [0:0.05:10];
num_interp_samples = length(ypos_grid);
%loop through each movement
for k=1:num_movements
%get data for the current movement
xp = xpos{k};
yp = ypos{k};
%to deal with duplicate samples, I add a very small offset to each
%sample to make them all unique
offset = cumsum([0:length(yp)-1]*1e-16);
yp2 = yp+offset(:);
%interpolate xp wrt yp
x_interp{k} = interp1(yp2, xp, ypos_grid);
%interpolate yp so that it is the same size as x_interp
t = linspace(1,length(yp2),length(yp2));
ti = linspace(1,length(yp2),num_interp_samples);
y_interp{k} = interp1(t, yp2, ti);
end
I *think* this should be relatively simple, but when I plot the interpolated data, it looks a bit strange to me. See below:
Namely, the trajectories seem to have lost much of its "curvature", which has me worried. Note when plotting the interpolated trajectories, I am simply doing:
figure; hold on;
for k=1:num_movements
plot(x_interp{k}, y_interp{k}, 'color', 'k');
end
xlabel('x-position (cm)');
ylabel('y-position (cm)');
title('Examples of complete trajectories (interpolated data)');
axis equal;
Here are my specific questions:
(1) Am I interpolating correctly?
(2) If the answer to (1) is yes, then am I interpreting the interpolated result correctly? Specifically, why do the shapes of the trajectories appear as they doo (lacking curvature)?
(3) Am I perhaps missing a step where after obtaining x(y), I should re-transform the data back into x(t)?

Antworten (1)

Voss
Voss am 27 Dez. 2021
I would not do the interpolation this way. Instead, I would find x(t) and y(t), i.e., interpolate both x and y in terms of some common parameter t.
In fact, since you already have x and y as vectors of the same length (for a given motion), you can say t is the sample number and it is equivalent actual time assuming a constant sampling interval (probably a safe assumption). So the interpolation is easier that what you have now:
%load the data: xpos & ypos
load('pos_data.mat')
num_movements = numel(xpos);
%create cell array that will hold interpolated data
x_interp = cell(size(xpos));
y_interp = cell(size(ypos));
%construct grid vector
ypos_grid = [0:0.05:10];
num_interp_samples = length(ypos_grid);
%loop through each movement
for k=1:num_movements
%get data for the current movement
xp = xpos{k};
yp = ypos{k};
t = 1:length(yp);
ti = linspace(1,length(yp),num_interp_samples);
x_interp{k} = interp1(t, xp, ti);
y_interp{k} = interp1(t, yp, ti);
end
Plot the actual data and interpolated data as y vs x:
figure();
subplot(1,2,1);
hold on;
for k=1:num_movements
plot(xpos{k}, ypos{k}, 'color', 'k');
end
xlabel('x-position (cm)');
ylabel('y-position (cm)');
title('raw data');
subplot(1,2,2);
hold on;
for k=1:num_movements
plot(x_interp{k}, y_interp{k}, 'color', 'k');
end
xlabel('x-position (cm)');
ylabel('y-position (cm)');
title('interpolated data');
Now you can see the curvature is preserved.
This doesn't get you x(y), but it does allow you to compare the trajectories across multiple motions.

Kategorien

Mehr zu Interpolation finden Sie in Help Center und File Exchange

Produkte


Version

R2015a

Community Treasure Hunt

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

Start Hunting!

Translated by