我有一个2D点(x1,y1),(x2,y2)......(Xn,Yn)列表,表示一个曲线段,是否有任何公式来确定是否绘制该段的方向是顺时针还是逆时针?
感谢任何帮助
答案 0 :(得分:7)
或者,您可以使用一些线性代数。如果您按顺序有三个点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).
通过以相同的方式跟随较长的曲线,您甚至可以检测何时曲线从顺时针方向变为逆时针方向(如果有用)。
答案 1 :(得分:4)
一种可能的方法。如果您的点列表所代表的线的采样是均匀和平滑的,并且该线足够简单,那么它应该能够合理地工作。
我假设您拥有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
的平均值。原因是:如果一个区域的采样密度较大,则平均值会偏向于该值,而积分则不会偏差。
答案 2 :(得分:2)
现在这是我的方法,正如对问题的评论中提到的那样 -
另一种方法:从起点到终点画一条线。这条线确实是一个矢量。 CW曲线的大部分内容都与该线的RHS有关。对于CCW,请离开。
我写了一个示例代码来阐述这个想法。大多数解释都可以在代码中的注释中找到。
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
通过比较两个向量,即旋转向量[起始点 - &gt;],可以总是指出有向线的哪一侧(向量)。质量中心]到向量[起始点 - &gt;结束点,然后将旋转角度比较为0.几秒钟的精神动画可以帮助理解。