[凸包计算]求解点集合的凸包轮廓

前提:

约定1----平面上两向量基于平面法向的夹角为[0-2π);

约定2----下文中路径为有向的;

约定3----下文中法向Normal由屏幕内指向屏幕外;

当然上述约定并不是绝对的,只是为了表述原理方便,或者说化繁为简而设的条件,

当然你可以约定Normal为指向屏幕内,这也是可以的,原理是不变的。

根据右手定则,Vector1基于Normal与Vector2夹角如图1为锐角,

同样可知Vector2基于Normal与Vector1夹角如图2为钝角,

思考:已知Vec12为当前路径,下一条路径为Vec23还是Vec24?

凸包,字如其意,凸多边形包围盒。

上述两个选项在不同前提条件下各为正确项,那么在约定前提条件下,就只有一个是对的了,

当然前提条件在约定后就不能随意更改了,起码不能在搜寻凸包过程中更改,这样就规则混乱,同样结果就不准确了。

凸多边形边是连续的,在搜寻凸包过程中路径同样是连续的,那么就存在这样两种情况,搜寻出来的凸包为逆时针或顺时针,

顺逆时针结果所对应的“搜寻过程中,已知当前路径,选取下一路径的”的规则是不一样的,对于顺时针结果情况,选取下一路径的依据是当前路径与下一路径夹角为最大,即最接近2π的(此时约定1如上),对于逆时针情况,规则即为当前路径与下一路径夹角最小,即最接近0(此时约定1不能如上所述了,需更改为(0,2π])。

简要说明过程如下:

(1)由点集合中任意两个不同位置的点0,1构造出第一条向量VecFirst;

(2)由点集合中搜寻另一个点,该点与点0构造出的向量VecTemp与VecFirst不平行;

(3)由步骤1和2求得法向Normal(指向屏幕内或外均可);

(4)点0,1构造出的路径为当前路径,基于该路径寻找下一路径,

依据为当前路径与下一路径基于步骤3所得法向的夹角最小,也可以理解为基于步骤3所得法向情况下当前路径与下一路径所构成的凸包中的一个拐角是“凸的”,“凸的”不是“秃的”;已下一路径为当前路径,继续寻找;

(5)重复步骤4,直到该路径中连续包含连续的两个点(比如第一次连续包含了点0,1,某个时刻又连续包含了点0,1时)即停止搜寻,此时已经找到闭合的凸包,以第一次包含的连续的两个点中的index稍小的点为第一点,沿路径直到第二次包含的该两点中index稍小的点(也就是第一点,同一个点,在路径中index不同罢了)为最后一点,该闭合路径即为凸包路径;

(6)以第5步所得凸包路径构造凸多边形即可;

(7)第5步终结条件是否满足,需要记录最近一次[重复包含]的点的index,当再次出现路径[重复包含]当前点的情况时做判断:

1.最近一次[重复包含]点index已记录,为index0Last,求得该点第一次包含时的index,记为index0First;

2.当前[重复包含]点index为未再加入当前点的路径序列的Count,记为index1Last,同样可求得当前点第一次包含时的index,记为index1First;

3.当(index1First-index0First==1)&&(index1Last-index0Last==1)时即为满足终止条件,按第5步所述取得凸包路径。

4.凸包路径为逆时针(基于第3步所求Normal);

5.增加一些约定只是为了将问题化简,搜寻过程示意图及效果图如下。

实际效果,效果图1左下角开口向上的小尾巴并不是线,是软件渲染问题,代码不上传了,有问题留言。

猜你喜欢

转载自blog.csdn.net/baidu_38621657/article/details/88069552
今日推荐