多边形顺逆时针判定算法详解

多边形顺逆时针判定解决的问题是给一个多边形的顶点列表或者边列表,判断该多边形是顺时针还是逆时针。

多边形顺逆时针判定算法在几何算法中应用十分广泛。因为很多几何算法都需要要根据几何的拓扑结构,为了方便,往往规定外环多边形是逆时针,内环多边形是顺时针。

除了介绍算法,作者还会关于误差对算法稳定性影响有详细介绍

更多几何算法,欢迎关注作者gongzhonghao:几何算法

算法一:用最远顶点判断顺逆时针

边不包含曲线的情况

简单起见,我们以每条边都是直线段的多边形开始,后面讨论包含曲线边多边形的情况。

凸多边形顺逆时针判定比较简单,我们只需根据任意顶点前一条边的切线和后一条边切线向量做叉积即可判定,如下图所示。

关于叉积的详细内容,在下面文章中有详细介绍。

       向量的定义、性质及其在几何算法中的应用

凹多边形就不能随便选一个点了,如果恰巧选中凹进去的点,得出的结论正好相反,如图所示。

问题是我们如何判断选择到的点是一个凸点还是一个凹点呢?

对于凹点判断起来难度比较大,而判断某些凸点却很简单,例如在某个向量上投影最大的点或最小的点都是凸点,如图所示。

算法具体流程如下:

1. 确定一个向量v
2. 遍历所有顶点,找到在向量v上投影最大的点
3. 获得该顶点前一条边和后一条边的向量v1和v2,计算两个向量的叉积
   分四种情况讨论
   3.1 叉积大于0,返回结果为逆时针
   3.2 叉积小于0,返回结果为顺时针
   3.3 叉积等于0,计算v1和v2的点积,分两种情况讨论
       3.3.1 点积大于0,说明v1和v2同向,计算v与v1的叉积
             v与v1的叉积大于0返回结果为逆时针
             v与v1的叉积小于0返回结果为顺时针。
    3.3.2 点积小于0,回到步骤一重新选择一个向量v

下图列出了该算法的所有情况。

为了方便计算,我们一般选择x轴或y轴作为向量,这样投影计算就不用计算点积了。

边包含曲线的情况

边包含曲线的情况和全是直线的区别是需要找曲线边在向量方向上的极值点。假设曲线为C,采用参数方程形式描述,这个极值点的计算公式如下:

C ′ ( t ) ⋅ V = 0 C^{'}(t) \cdot V = 0 C(t)V=0

这对非线性方程求解能力有一定要求。特殊曲线可以用解析法求解(例如圆弧);对于任意曲线建议采用区间迭代法来求解。还建议先通过曲线Box来排除不需要求解的情况。

也将这些极值点作为顶点处理,算法原理和全是直线的就一致了。

算法的误差稳定性

理论上,上述算法是绝对稳定的。但如果算法发生在计算过程中,搜出来的环有可能存在误差范围内自交的情况,如下图所示。

如果我们恰巧选到了自交点,计算结果就错误了。不要小看这种情况,作者工作中实实在在碰到过的,都是血泪经验

这种情况的解决方法一般分两种。

一是取投影最大点的同时取投影最小点,判断是否一致,不一致就重新选择其他向量。这是个降低概率的方法,一般出现上述情况的概率不大,两端都出现的概率是乘法关系,就更小了。取最大点同时取最小点计算量增加不多,所以这么做还是很值得的。

如果还是不放心,就使用面积符号判断方法,面积符号判断法能很好的吃掉小的自交。

算法二:用面积符号判断顺逆时针

关于面积符号判断法,我在如下文章中已经介绍过了。

       多边形面积计算算法

计算面积效率肯定不如最远点算法高,但它稳定性好,另外如果判断顺逆时针只是一个更大算法的一部分,有了面积后还能做很多后续优化,用面积符号判定整体效率反而会更高(例如布尔运算,面积大小还能用来给更慢的环的包含关系判断加速)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值