如何有效地计算由共面点定义的闭环的法线?
How can I efficiently calculate the normal of a closed loop defined by coplanar points?
我们有一组定义闭环的共面点,它们是逆时针缠绕的。循环保证不会自相交。
我们要计算法线
我们有两个问题。
对于接近共线的点,浮点精度会导致使用叉积计算错误的法线。
对于凹形闭环,一些法线会指向相反的方向。
我们的解决方案是计算定义闭环的所有连续段的法线。这样,问题 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派生出来的。法线的长度(归一化之前)等于循环所包围的带符号区域的两倍。所以你保证它不会为空(如果该区域不为空)并且你保证它会指向正确的方向。
我们有一组定义闭环的共面点,它们是逆时针缠绕的。循环保证不会自相交。
我们要计算法线
我们有两个问题。
对于接近共线的点,浮点精度会导致使用叉积计算错误的法线。
对于凹形闭环,一些法线会指向相反的方向。
我们的解决方案是计算定义闭环的所有连续段的法线。这样,问题 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派生出来的。法线的长度(归一化之前)等于循环所包围的带符号区域的两倍。所以你保证它不会为空(如果该区域不为空)并且你保证它会指向正确的方向。