这有点像我必须在实验室进行的动物追踪数据分析。我的反应是这样的:
首先按照@Iterator 的建议定义一个线性化轨道。我通过定义具有 3 到 20 个控制点的样条曲线来做到这一点。您可以通过所有数据拟合样条曲线,也可以使用绝对的东西,例如滑行跑道的物理形状,或者教科书般完美的滑行会产生的最佳路径。无论您选择什么,我们都将其称为参考路径。
然后对该样条线进行密集采样 - 沿着样条线从头到尾均匀分布找到 100,000 个左右的点。
接下来,对于每个时间点和每个轨迹,确定两件事:(x) 沿参考路径的点的标识,该点最接近该时间点平面的 XY 位置,以及 (y) 欧几里得距离在瞬时数据点和最近的样条点之间。将 y 绘制为 x 的函数为您提供平面和参考路径之间的距离图,按该路径的距离。
如果您将参考路径定义为通过平面 A 轨迹的样条曲线,并针对该路径绘制平面 B 的上述图,您将获得平面之间的距离,作为它们沿轨道的路线的函数,与时间无关。
这是一些可以解决问题的注释代码。在我的电脑上使用这里的测试数据。
% 脚本将 2 条路径之间的距离确定为函数
沿第一条路径的距离百分比
%
% 路径 1 用于拟合样条曲线。该样条被密集插值
% 对于路径 2 上的给定点,搜索 path1 插值点
% 表示欧几里得距离最小的那个。到的距离
% 最近的 Path1 插值点 ALONG 路径 1 是路径 2 点'
%“参考路径距离”,与插值之间的距离
% 点和路径 2 点是“参考路径偏差”
%
% 因为路径 1 上的点不是从
% 路径的起点到终点,以适应平滑的样条曲线
% 路径 1,我让用户单击路径 1 上的样条控制点。A
% 临时样条适合用户的点击点,而临时样条
% spline 用于将路径 1 的数据分解为小数据组。这
每组的 % 质心作为构建路径的控制点 1
% 样条。
%% 加载数据。path1 和 path2 都是 2xn [x_data; y_data] %%
加载 pos_data.mat path1 path2;
%% 绘制原始数据并从用户那里获取样条点 %%
数字; 情节(路径1(1,:),路径1(2,:),'b');% 第一条路径
坚持,稍等; 情节(路径2(1,:),路径2(2,:),'r');% 第二条路径
[spl_x, spl_y] = getpts(); % 鼠标点击定义样条曲线
user_path = [spl_x'; spl_y']; % 重新排列为与path1,2相同的格式
%% 从用户点创建样条 %%
n_xx = 100;% n_xx 临时样条的插值点
n_x = 大小(用户路径,2);% n_x 个样本,每个样本 2 个值
xx_t = linspace(0,1,n_xx); % 插值
x_t = linspace(0,1,n_x); % 我们的时间参数 fn 的参数
yy_t = spline(x_t,user_path,xx_t); % yy 是沿路径在 xx 处的点
情节(yy_t(1,:),yy_t(2,:),“.b”,“线宽”,4);
%% 通过最近的 tmp 样条插值将 path1 点分成组 %%
% 对于每个 path1 点,找到最近的临时样条点
TRI = delaunay(yy_t(1,:), yy_t(2,:));
index = dsearch(yy_t(1,:), yy_t(2,:), TRI, path1(1,:), path1(2,:));
path1_x = 零(2,n_xx);% 为每个 path1 点组制作 1 个 path1 样条控制点
% 路径 1 中的点有 n_xx 个 bin。确定 n_xx 质心
落入这些箱中的点组的百分比。
对于 n = 1:n_xx
path1_x(:,n) = [平均值(path1(1, index==n)); ...
平均值(路径1(2,索引==n))];
结尾
%% 使用刚刚获得的质心作为“path1 spline”的控制点。%%
n_xx = 1000; % 我们将密集采样 path1 样条
n_x = 大小(path1_x,2); % 虽然我们只有 50 个用于路径 1 样条的控制点
xx_p1 = linspace(0, 1, n_xx); % 插值到 path1 样条曲线的位置
x_p1 = linspace(0, 1, n_x); % 参数:沿临时样条的距离
yy_p1 = 样条线(x_p1,path1_x,xx_p1);% 样条沿路径 1 的 x&y 坐标
数字; 情节(路径1(1,:),路径1(2,:),'。','MarkerSize',10);
坚持,稍等; 情节(yy_p1(1,:),yy_p1(2,:),'-');
%% 通过为每个 path2 点找到沿 path1 样条曲线的最近点来“线性化”路径 2。%%
TRI = delaunay(yy_p1(1,:), yy_p1(2,:));
index = dsearch(yy_p1(1,:), yy_p1(2,:), TRI, path2(1,:), path2(2,:));
path2_dist_along = xx_p1(1,index); 每个 path2 点沿 path1 样条线的 % 距离
% 只是
% 路径 1 样条
% 偏差是每个 path2 点与其之间的欧几里得距离
% 最近的 path1_spline 对应
path2_deviance = sqrt((path2(1,:) - yy_p1(1,index)).^2 + (path2(2,:) - yy_p1(2,index)).^2);
数字; 情节(path2_dist_along,path2_deviance,'。');
我的路径并不好,甚至像你的一样:/动物追踪现状。因此,有一种变通方法可以将样条曲线拟合到有点混乱的原始数据上。

这是脚本的输出。

注意:如果将其绘制为折线图而不是散点图,您会看到点沿 x 轴的顺序不正确,并且 x 轴的采样不均匀。我认为这可以通过插值和平滑的某种组合来解决,但解决方案可能取决于您希望输出格式的确切方式,因此我没有对其进行编码。
我试图使代码清晰,但如果有什么令人困惑的地方,请告诉我。有趣的问题,谢谢。