确定线段的方向是顺时针还是逆时针

时间:2014-08-11 21:24:04

标签: algorithm matlab math geometry

我有一个2D点(x1,y1),(x2,y2)......(Xn,Yn)列表,表示一个曲线段,是否有任何公式来确定是否绘制该段的方向是顺时针还是逆时针?

感谢任何帮助

3 个答案:

答案 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)

一种可能的方法。如果您的点列表所代表的线的采样是均匀和平滑的,并且该线足够简单,那么它应该能够合理地工作。

  1. 将平均值减去“居中”线。
  2. 转换为极坐标以获得角度。
  3. 打开角度,确保其增量有意义。
  4. 检查总增量是正确的还是负数。
  5. 我假设您拥有xy向量中的数据。

    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
    

    这仅考虑所有点的集成效果。它没有告诉你是否有“扭结”或沿途有不同转弯方向的部分。

    可能的改进是用某种积分代替xy的平均值。原因是:如果一个区域的采样密度较大,则平均值会偏向于该值,而积分则不会偏差。

答案 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.几秒钟的精神动画可以帮助理解。