如何有效地计算由共面点定义的闭环的法线?

How can I efficiently calculate the normal of a closed loop defined by coplanar points?

我们有一组定义闭环的共面点,它们是逆时针缠绕的。循环保证不会自相交。

我们要计算法线

我们有两个问题。

  1. 对于接近共线的点,浮点精度会导致使用叉积计算错误的法线。

  2. 对于凹形闭环,一些法线会指向相反的方向。

我们的解决方案是计算定义闭环的所有连续段的法线。这样,问题 1 可以通过丢弃计算出的异常法线来解决。通过知道大多数法线的方向是正确的,可以克服问题 2。

这似乎可行,但非常昂贵。

是否有更简单、更便宜、更优雅的解决方案?

假设点{p_i}0<=i<n构成一个逆时针多边形,计算该多边形的三角形扇形(包括凹部)的每个三角形的叉积之和:

normal = vector3(0, 0, 0);
for(int i=1; i<n-1; ++i) 
    normal += cross(p[i+1]-p[0],p[i]-p[0]);
normal /= norm(n);

这是从Stoke's theorem派生出来的。法线的长度(归一化之前)等于循环所包围的带符号区域的两倍。所以你保证它不会为空(如果该区域不为空)并且你保证它会指向正确的方向。