多边形等距算法实现中遇到的问题及其解决办法

  本文得益于徐庆荣(武汉大学)的文章思路,参考地址:http://dev.csdn.net/article/13/13811.shtm 实现了一个多边形等距的算法,其间参考了wyz20020214 在CSDN资源区上传的“开放源码的计算机图形学几何算法包”,参考下载地址:http://download.csdn.net/source/457600 在此总结一下实现过程中的收获。  

1、如果不考虑任何异常情况,做一个已知多边形的等距线的方法有很多,我采用的方法是:逆时针遍历多边形的各个顶点,求出每个角平分线的方程,然后根据角平分线与等距的距离向临边做一个垂线,根据三角形性质确定出等距线上的一个点(这个点就是相邻两条等距边的交点)。这里可能比较难做的事情是对于凹多边形的凹角处的判断,我采用了根据两条边的向量叉积的方法来判断出凹角,然后对于凹角的对角线方向取一个逆向(一般的凸角采用的是由余弦定理求出cos值,然后进行三角换算得到的,这样效率比较高),就使得交点仍然取在了多边形内部。这里多亏从网上看到的一篇BLOG讲到的向量叉积提醒了我,致敬!  

2、对于逆向环和逆向线段,很直观的处理方法就是判断按照无异常得到的等距线的各条边之间是否存在交点。再没有交点的情况下,等距线还是一个正常的单环,这时候只要判断等距线的各个边是否和原来的多边形“走向”相同(我使用的具体方法是判断沿逆时针方向的下一个点在当前边所在直线的左侧或右侧,只要等距线的相应点和原多边形每条边的左右侧分布情况都相同,就可以认为“走向”相同);如果有交点,则必然存在环,存在环就有可能存在逆向环和逆向线段,这时的判断稍微复杂一点,对于单环时的判断要类似的进行判断,而逆向通常发生在交点处,因此在交点处,按照逆时针方向所成的角度大于180度,就认为当前的环发生了逆向(由于要遍历等距线各个顶点一圈,所以每个交点要被判断两次,相当于逆向和正向都考虑到了,不会漏掉正向的情况,也不会多删除环)。  

3、其实最头疼的问题莫过于阈值的确定,即在什么时候等距线收缩为一个点。开始试图根据重心到多边形上所有点中最短距离作为阈值,但是这个阈值明显比实际的要大,滤掉了中心的很多等距线;后来试图使用重心到各边的最短距离中的最大值作为阈值,但是实验表明这个值有比实际的要大,最后还是会出现很多形状奇怪的等距线;后来想到如果对于一个很小的多边形画等距那么使用它的重心或这其他数学上的中心点来计算都会因为误差的原因而不明显了,所以我想到了“递归”,将每一个等距线作为新的多边形进一步画它的等距线,最后收缩到很小的时候,不管加入的是重心最短距离还是重心各边最短距离的最大值,都和实际的阈值很接近,可以看做误差的效果了。(感谢递归的思想,关键时候帮了我的大忙)。后来进一步改进,用多边形的面积进行逼近判断,如果等距后的多边形比原来的面积小就画,如果比原来的面积大则说明肯定是异常,就不画。这两者结合后的效果比单独用一种能够避免更多的异常,现在的代码就是两个结合判断的。但是这里并不完美,还有待改进。

4、对于等距线可能分化成为多个小多边形的情况,我是和逆向环、逆向线段的判定基础上进行处理的。我的处理方法是,对于已经确定的环,就将这个新的环重新组织,存储在一个新的多边形数组里,然后作为进行递归调用。其实这个问题在我想到递归方法之前就已经通过逆向环的方法解决了(过滤逆向环的时候就可以将多个环筛选出来),但是用递归更加精确一些,效率也更高了。  

5、其中的一些数学问题的钻研和实现,使我对于数学的一些思想加深了认识,算是这次的最大收获了。  

李文凯2008年5月23日于ImLab

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值