如何有效地确定 3D 多边形的法线 space?

How to efficiently determine the normal to a polygon in 3D space?

我有一堆共面点在 3D 中定义多边形 space。这些总是以相同的方式缠绕(例如顺时针)。我需要确定包含此多边形的平面的有符号法线,即知道该多边形的 "up" 是哪条路。

乍一看这似乎很简单:取两条边(顶点差)并计算叉积。但如果边缘恰好是共线的(你得到一个零幅度的叉积),那就失败了。

然后我尝试遍历顶点列表,直到找到与第一条边成相当大角度的第二条边。这在凸多边形上可靠地工作,但如果我最终得到的两条边没有定义多边形内部的三角形,它可能会在非凸多边形上失败(指向相反的方向)。

我知道如果我先对多边形进行三角剖分,那么我就可以轻松可靠地检查任何三角形的面...但问题是我的三角剖分库需要知道平面法线。所以,先有蛋,后有鸡。

如何在非凸多边形中选取两条边(或三个顶点)来可靠地定义多边形面向的方向?

如果我是你,我会按以下方式完成:

  1. 选择多边形(任何顶点或质心)附近的任意点 C
  2. 所有 i 的叉积总和 (P[i] - C) x (P[i+1] - C) (包括最后和第一个点对)。
  3. 归一化和向量。

请注意,在第 2 步之后,您将得到一个具有正确方向的法线方向的矢量,其大小为 2 S,其中 S 是多边形的面积。这就是为什么它应该工作,除非你的多边形面积为零或几乎为零。

顺便说一下,这里使用C点只是为了让距离原点较远的小多边形计算更精确一些。您可以选择 C = 0,有效地将其从计算中移除。

计算将 3D 多边形投影到 XY、YZ 和 ZX 平面所产生的三个多边形中的三个 signed areas,从而得到所需的法线。

is not robust. See Robust polygon normal calculation为例。

一个稳健的解决方案是找到所有 i、j 的最大叉积 (P[i] - C) x (P[j] - C),(i < j) 并将其归一化。它将对应多边形的最大内接三角形。