我有一个由2D点 (x1,y1),(x2,y2)......(Xn,Yn) 组成的曲线段列表,是否有公式可以确定绘制该曲线段的方向是顺时针还是逆时针?非常感谢您的帮助。
另外,您也可以使用一些线性代数知识。如果您有三个点a、b和c,并按顺序排列,则可以按照以下步骤进行:
1) create the vectors u = (b-a) = (b.x-a.x,b.y-a.y) and v = (c-b) ...
2) calculate the cross product uxv = u.x*v.y-u.y*v.x
3) if uxv is -ve then a-b-c is curving in clockwise direction (and vice-versa).
通过沿着相同的方式沿着更长的曲线走,甚至可以检测出当“S”形曲线从顺时针变为逆时针时的变化,如果有用的话。
一种可能的方法。 如果您点列表所代表的行的采样均匀且足够平滑,并且该行足够简单,则应该可以正常工作。
我假设您的数据在x
和y
向量中。
theta = cart2pol(x-mean(x), y-mean(y)); %// steps 1 and 2
theta = unwrap(theta); %// step 3
clockwise = theta(end)<theta(1); %// step 4. Gives 1 if CW, 0 if ACW
x
和y
的平均值。原因是:如果在一个区域中采样更密集,则平均值会偏向该区域,而积分不会。clear;clc;close all
%% draw a spiral curve
N = 30;
theta = linspace(0,pi/2,N); % a CCW curve
rho = linspace(1,.5,N);
[x,y] = pol2cart(theta,rho);
clearvars theta rho N
plot(x,y);
hold on
%% find "the vector"
vec(:,:,1) = [x(1), y(1); x(end), y(end)]; % "the vector"
scatter(x(1),y(1), 200,'s','r','fill') % square is the starting point
scatter(x(end),y(end), 200,'^','r','fill') % triangle is the ending point
line(vec(:,1,1), vec(:,2,1), 'LineStyle', '-', 'Color', 'r')
%% find center of mass
com = [mean(x), mean(y)]; % center of mass
vec(:,:,2) = [x(1), y(1); com]; % secondary vector (start -> com)
scatter(com(1), com(2), 200,'d','k','fill') % diamond is the com
line(vec(:,1,2), vec(:,2,2), 'LineStyle', '-', 'Color', 'k')
%% find rotation angle
dif = diff(vec,1,1);
[ang, ~] = cart2pol(reshape(dif(1,1,:),1,[]), reshape(dif(1,2,:),1,[]));
clearvars dif
% now you can tell the answer by the rotation angle
if ( diff(ang)>0 )
disp('CW!')
else
disp('CCW!')
end
通过比较两个向量,即将旋转向量[起点 -> 质心]旋转到向量[起点 -> 终点],然后将旋转角度与0进行比较,可以始终确定点在有向线(向量)的哪一侧。几秒钟的思维动画可以帮助理解。
diff
函数来查看点之间相邻的差异。如果输出向量中每个元素的diff
元素为正数,则可以将其视为顺时针方向。如果它是负数,则可以将其视为逆时针方向。也许可以制作一个正负次数的直方图,并选择具有更高计数的箱子作为所选方向。 - rayryengunwrap
。很好的发现! - rayryeng