Algorithm 确定线段的方向是顺时针还是逆时针
我有一个代表曲线段的2D点列表(x1,y1),(x2,y2)…(Xn,Yn),是否有公式确定绘制该段的方向是顺时针还是逆时针Algorithm 确定线段的方向是顺时针还是逆时针,algorithm,matlab,math,geometry,Algorithm,Matlab,Math,Geometry,我有一个代表曲线段的2D点列表(x1,y1),(x2,y2)…(Xn,Yn),是否有公式确定绘制该段的方向是顺时针还是逆时针 任何帮助都是非常感谢的一种可能的方法。如果点列表所代表的线的采样足够均匀和平滑,并且线足够简单,那么它应该工作得相当好 减去平均值,使线居中 转换为极坐标以获取角度 展开角度,以确保其增量有意义 检查总增量是正增量还是负增量 我假设你有x和y向量中的数据 theta = cart2pol(x-mean(x), y-mean(y)); %// steps 1 and 2 t
任何帮助都是非常感谢的一种可能的方法。如果点列表所代表的线的采样足够均匀和平滑,并且线足够简单,那么它应该工作得相当好
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
theta=cart2pol(x-均值(x),y-均值(y));%//步骤1和2
θ=展开(θ);%//步骤3
顺时针=θ(结束)或者,您可以使用一点线性代数。如果您有三个点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”形曲线何时从顺时针方向变为逆时针方向(如果有用的话) 这是我的方法,正如在对问题的评论中提到的-
另一种方法:从起点到终点画一条线。这条线实际上是一个向量。CW曲线的大部分部分位于该直线的右侧。《特定常规武器公约》,左
我编写了一个示例代码来阐述这个想法。大部分解释可以在代码中的注释中找到
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进行比较,始终可以判断点位于定向线(向量)的哪一侧。几秒钟的头脑动画可以帮助理解 一个线段如何具有顺时针/逆时针方向?确切的定义是什么?该段是手写阿拉伯语的一个弯曲部分character@LuisMendo-好的,我明白了。你可以做的一件事就是给定曲线,找到它的重心。完成此操作后,找到曲线上每个点与该质心的夹角。之后,使用diff
查看点之间的相邻差异。如果此输出向量中每个元素的diff
元素为正,则可将其视为顺时针方向,如果为负,则可将其视为逆时针方向。也许做一个正、负事件的柱状图,无论哪个箱子的计数更高,这就是方向chosen@rayryeng我认为可以通过展开相位来消除您提到的模糊性(前提是由点表示的采样足够精细)。这就是我在回答中所做的。@LuisMendo-正确。忘记了展开
。好地方!是的。。。这几乎就是我写的建议方法!很不错的。我决定把所有的差异都分类,看看哪个符号的计数更高,我会选择那个。这仍然是一个很好的方法。路易斯,我试过你的方法,效果很好:)谢谢你的帮助@rayryeng非常感谢你的帮助谢谢too@LuisMendo-我喜欢这篇文章,主要是因为不同的SO用户(Yvon,你和我)之间的合作,最终得出了一个对OP有效的答案。谢谢@艾哈迈达博巴克-非常欢迎你。很高兴我们能帮你解决这个问题@路易斯门多-那根本没问题。老实说,我不确定我的方法是否有效。看到你发布了一个答案,OP接受了,这证实了我的想法是有效的。声誉积分只是次要的。我来这里主要是为了帮助人们,这篇文章和合作就是对这一点的证明。对我来说,这是迄今为止最好的解决方案+1@seb-没关系。我误读了算法。我要删除我的评论,因为这是胡说八道。@Penguino:我有N个点,我尝试了你的方法,但因为我有N个点,我对每两个连续的微分向量的叉积的结果进行了求和,对吗?@ahmed:是的,做一些类似x1=diff(x)y1=diff(y)的事情,那么x1的所有连续元素的X积y1@ahmed是的,如果曲线沿其整个长度是局部顺时针的,那么你会得到所有的横积,所以求和是可以的。但是,如果曲线在其整个长度上具有相同的曲率方向,则只需在前三个点上进行测试即可节省时间。这不是无用的+1从我这里。。。大约22分钟后。我已经达到了今天的最高票数。