1.前言
轮廓有正面和反面,可以通过其法向识别正反面,而法向是轮廓或面的重要特征,求轮廓法向是一种基础的几何工具算法。
由于浮点数存储和运算的精度损失,可能造成求轮廓法向的精度损失,如角点由于精度损失并非精确的在一个平面上(而是在容差范围内属于一个平面)、角点距离很近导致可能进一步影响法向计算的精度等。
2.算法概述
单纯的选取任意两个相邻边来计算法向可能是错误的,因为存在凹角的情况,这时得到的“法向”与正确的法向是方向相反的。
而进一步通过轮廓面积计算来得到法向的符号貌似是一种比较准确的补偿方法,是的,很有效,但是上述选取任意相邻边计算的法向可能精度损失较大,如相邻边的3个点偏离平面较大、相邻3个点存在距离很近的情况等导致法向精度损失较大。
一个思路是考虑所有相邻边得到的法向因素,进行加权平均,权重值为相邻边的夹角angle因素(弧度表示法),夹角在[0,PI/2)时取原值,在[PI/2,PI]时取PI-angle,因为在相同的条件下上述取值越大计算的精度越高,其对法向的贡献度越大,即权重值越大。
试想一下,当两条边无限接近于共线的情况,那么由它们计算得到的法向无限接近于(0,0,0)。
3.关键情况的考虑
仍然需要考虑凹凸角情况,统一将凹角或凸角计算得到的法向进行取反即可,因为符号会通过计算面积得到。一种实践是判断当前计算的法向是否与已计算过的法向存在夹角大于接近于PI值的情况(如PI/6*5,即150°),如果存在即取反,这样所有的法向被统一在面的一个方向了。
仍然需要考虑相邻点过近的情况, 可以在计算前进行无效边去除,无效边的判断依据可以根据边长(是否小于一个很小的值如1e-2)、前一条和后一条边的情况(如长度、夹角,避免误将尖锐的角去除)
一些软件或库不支持对存在尖锐角的(三角面、面、轮廓等)情况进行一些计算,可能是相关算法没有很好的兼容尖锐角情况。
4.写在后面
经理论分析和实际测试,这种算法得到的轮廓法向精度较高,所得到的法向有效的支持了面相交、轮廓剖分等算法的健壮性。
由于博主懒,此处不将代码贴出来了。
图形几何、数据处理、并行计算相关研究和研发,公众号:geometrylib,欢迎交流。