稳健的多边形法线计算

时间:2014-04-03 12:40:29

标签: algorithm 3d geometry numerical-methods

是否有一个很好的鲁棒算法来计算凸多边形的法向量(当然是3D)?对于三角形,很容易:一个取三角形的两个边并计算叉积:

vec3 u = point[0] - point[1], v = point[0] - point[2];
vec3 n = normalize(cross(u, v));

但是这种方法并没有真正扩展到多边形。多边形的某些边缘可能几乎或“完全”共线(这通常发生在发生T形连接的网格中),因此有必要选择一对边,给出“强”法线(两条边都是“足够长”并且它们保持“几乎垂直”的角度。)

但是,这种方法仍然不适用于所有多边形。想象一下圆盘形状的多边形。如果细分非常精细,则无论光盘的半径如何,所有边缘都将非常短并且所有连续边缘将几乎共线。与此同时,正常情况也很明确。

一种解决方案可能是找到最大的内切三角形并计算其正常值。但是,找到它会有O(n^2)的复杂性,这似乎太高了。

更好的解决方案是使用SVD或特征值分解来计算法线,给定所有多边形点,而不仅仅是三个或四个。

这是否有标准算法?任何人都有一个很好的方法吗?

3 个答案:

答案 0 :(得分:3)

如果您将三角形的公式分解,您将得到以下内容:

n ~ (p1 - p0) x (p2 - p0)
  = p0 x p1 + p1 x p2 + p2 x p0

您可以针对任意多边形推广此公式:

n ~ p0 x p1 + p1 x p2 + ... + pn x p0

总结连续边的叉积。这是一种强大的算法,适用于非平面多边形。

如果您可以确定多边形是平面的,我会执行以下操作(以节省计算时间):

Repeat k times
    Pick 3 random polygon vertices
    Calculate the normal of the according triangle
Choose the longest normal as the polygon's normal.

您可以放弃具有length <= epsilon的任何法线。

答案 1 :(得分:1)

您可以计算多边形所有点的协方差矩阵(这将是3D空间的3x3矩阵)。多边形的法线将是对应于最小特征值的特征向量。

答案 2 :(得分:0)

从任意顶点开始(将其称为顶点A),然后移动到列表中的下一个顶点(称为顶点B)。计算与AB向量垂直的向量(称为向量P)。然后继续在顶点列表中进行迭代,以找到与向量AB垂直最远的顶点。因此,在每次迭代中,将当前元素的点积(以顶点B为原点)与向量P相乘,并选择幅度最大的结果(取绝对值),然后将其称为C.计算ABC向量。

如果多边形是凸的,则可以停止迭代,直到垂直距离开始 变小。

我想到了这个主意,我不知道这种方法的效率,因为我不知道要与之比较的其他算法。