LabVIEW Convex Hull(凸包)算法详解

凸包定义:

       凸包(Convex Hull)是一个计算几何(图形学)中的概念。

在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包。X的凸包可以用X内所有点(X1,…Xn)的凸组合来构造.

用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。

     最近写一个算法用到了平面内散乱点凸包计算,我直接使用LabVIEW自带的函数“Convex Hull.vi”计算,返回排好序的最小凸包集。

图片

使用一段时间后,发现该VI在一些特定情况下,返回错误的凸包,排序出错,这是非常棘手的问题,算法不稳定。如下图所示:红色点是给定的一个点集,白色线是LabVIEW Convex Hull.vi 计算的结果,显然出现了错误。

图片

那还是从原理入手,写一遍!

使用Graham扫描法:

时间复杂度:O(n㏒n) 

图片

1)把所有点放在二维坐标系中,则Y轴最小的点一定是凸包上的点,如图中的P0。
2) 将所有点平移,使P0作为原点。
3)计算各个点相对于 P0 的幅角 α ,按从小到大的排序各点。当 α 相同时,距离 P0 比较近的排在前面。例如上图得到的结果为 P1,P2,P3,P4,P5,P6,P7,P8。我们由几何知识可以知道,结果中第一个点 P1和最后一个点P8 一定是凸包上的点。 
 4) 以上,我们已经知道了凸包上的第一个点 P0 和第二个点 P1,我们把它们放在数组里面。现在从步骤3求得的那个结果里,把 P1 后面的那个点拿出来做当前点,即 P2 。接下来开始找第三个点:
如果第三个点与前两个点组成的三角形逆时针,则扔掉,继续找一下个点;如果三角形是顺时针则,则将该点存入数组,重复步骤4) 检查当前的点是不是最后一个元素p8,是最后一个元素的话就结束。如果不是的话就把 P2 后面那个点做当前点,继续重复步骤4)

LabVIEW实现:

1)检查输入数据是否有效:

图片

2)删除掉重复点

图片

这里使用变体属性来完成该操作,变体属性的存储方式是二叉树存储,是速度最快的一种删除方式。延展一点:常规的删除方式如下(OpenG的一种方式):

图片

效率取决于搜索方式,线性搜索远远慢于二叉树搜索,数据量大时,效率会差很多。

3)极坐标转换、相同角度保留最远的点

图片

这里依然使用变体属性操作函数来设计算法,该套操作函数出镜率还是很高的。

4)查找构建三角形是顺时针排序的点,一直到查找结束。

图片

5)顺时针判断

利用矢量叉积判断是逆时针还是顺时针。

设A(x1,y1),B(x2,y2),C(x3,y3),则三角形两边的矢量分别是:

AB=(x2-x1,y2-y1), AC=(x3-x1,y3-y1)

则AB和AC的叉积为:(2*2的行列式)

 |x2-x1, y2-y1|

 |x3-x1, y3-y1|

值为:(x2-x1)*(y3-y1) – (y2-y1)*(x3-x1)

利用右手法则进行判断:

如果AB*AC>0,则三角形ABC是逆时针的

如果AB*AC<0,则三角形ABC是顺时针的

如果……  =0,则说明三点共线,

图片

验证算法的准确性及稳定性:

图片
图片

具有COS标签的图,就是重写ConvexHull.vi算法的结果(右边图)。经过大量运算及验证,该方法稳定高效。

以上详细介绍了基于LabVIEW的凸包算法,并贴了源码!感兴趣的朋友欢迎交流!

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/221864.html

(0)
联系我们
联系我们
分享本页
返回顶部