执行此操作的一种方法是定义轨道的起点,然后通过路径的标准化弧长参数化循环周围的每个遍历。然后,您可以使用此参数化沿轨道以特定间隔对每条曲线进行插值,并对结果进行平均。
% Assume that the first point is the start point (t = 0)
start_point = path(1,:);
% Compute the distance to this point for all data points
distances = sqrt(sum(bsxfun(@minus, path, start_point).^2, 2));
% Find the minima of this curve (these are all the times that the car passed the start)
% We apply some smoothing to get rid of necessary noise. Really depends on your data
[~, locs] = findpeaks(smooth(-distances, 20));
% Make sure we include the first and last point
locs = [1; locs; numel(distances)];
% Desired samples for each loop
nSamples = 1000;
% Pre-allocate the outputs
xpoints = zeros(numel(locs) - 1, nSamples);
ypoints = zeros(numel(locs) - 1, nSamples);
for k = 1:(numel(locs) - 1)
% Get the coordinates recorded for this particular loop
loop_points = path(locs(k):locs(k+1),:);
% Compute the cumulative arc-length using these points
arc_length = cumsum([0; sum(diff(loop_points, [], 1).^2, 2)]);
% Normalize the arc_length between 0 and 1
arc_length = arc_length ./ arc_length(end);
% Interpolate along the curve
xpoints(k,:) = interp1(arc_length, loop_points(:,1), linspace(0, 1, nSamples));
ypoints(k,:) = interp1(arc_length, loop_points(:,2), linspace(0, 1, nSamples));
end
% Average all the x and y locations
X = mean(xpoints, 1);
Y = mean(ypoints, 1);
plot(X, Y)
我们可以通过一个完美的循环来测试这一点,并在每个电路中添加一些噪声并每次更改样本数量
nLoops = 10;
x = [];
y = [];
for k = 1:nLoops
nSamples = randi([50, 70]);
t = linspace(0, 2*pi, nSamples + 1);
t(end) = [];
x = cat(1, x(:), cos(t(:)) + 0.1 * (rand(size(t(:))) - 0.5));
y = cat(1, y(:), sin(t(:)) + 0.1 * (rand(size(t(:))) - 0.5));
end
path = [x(:), y(:)];
注意:findpeaks 和 smooth 是工具箱函数,可能会被 MATLAB File Exchange 中的函数替换。或者,如果您知道汽车何时通过起点,则可以完全删除 findpeaks 的使用。