在计算几何中,判断一个多边形的顶点是凸(Convex)还是凹(Concave),最常用的方法是利用向量的叉积(Cross Product)。
这段代码的核心逻辑如下:
double crossZ = Vector3d.CrossProduct(ePrev, eNext).Z; bool isConvex = crossZ > 0;
在三维空间中,两个向量 $\vec{A}$ 和 $\vec{B}$ 的叉积结果是一个新的向量 $\vec{C}$: $$ \vec{C} = \vec{A} \times \vec{B} $$
这个新向量 $\vec{C}$ 有两个重要特性:
对于二维平面(XY平面)上的向量,它们的 Z 坐标为 0。 设 $\vec{A} = (x_1, y_1, 0)$,$\vec{B} = (x_2, y_2, 0)$。 它们的叉积结果 $\vec{C}$ 将只有 Z 分量:
$$ \vec{C} = (0, 0, x_1 y_2 - x_2 y_1) $$
我们关注的就是这个 Z 分量 $(x_1 y_2 - x_2 y_1)$ 的正负号。
判断 Z 分量正负的直观方法是使用右手定则:
| Z 分量符号 | 大拇指指向 | 旋转方向 (从 A 到 B) | 几何含义 (左/右转) |
|---|---|---|---|
| 正 (+) | 指向屏幕外 (Z+) | 逆时针 (CCW) | 向左转 (Left Turn) |
| 负 (-) | 指向屏幕内 (Z-) | 顺时针 (CW) | 向右转 (Right Turn) |
| 零 (0) | 无 | 共线 | 直线,无转弯 |
在你的代码中:
想象你沿着多边形的边界行走:
判定逻辑: 如果 `crossZ > 0`,根据右手定则,这意味着从 `ePrev` 到 `eNext` 是逆时针旋转。 在二维平面行进中,逆时针旋转等同于向左转。
这取决于多边形的点的排列顺序(Winding Order)。
通常在 GIS 和图形学算法中,定义一个实心多边形的标准是:
在此前提下:
注意:如果你的多边形是顺时针 (CW) 排列的(例如某些图形库如 GDI+ 的默认行为),那么逻辑会完全反过来:`CrossZ < 0` 才是凸角。
代码中的 `bool isConvex = crossZ > 0;` 隐含假设了输入数据 `input` 是逆时针排列的。
| 代码 | 数学含义 | 物理动作 | 形状特征 (CCW多边形) |
| crossZ > 0 | 逆时针旋转 | 向左拐弯 | 凸 (Convex) |
| crossZ < 0 | 顺时针旋转 | 向右拐弯 | 凹 (Concave) |
这段代码利用叉积的 Z 分量,快速判断了在当前顶点处,路径是向左拐还是向右拐,从而识别出需要处理的“凸”尖角。