目录

原理解析:利用叉积 Z 分量判断凸凹性

在计算几何中,判断一个多边形的顶点是凸(Convex)还是凹(Concave),最常用的方法是利用向量的叉积(Cross Product)

这段代码的核心逻辑如下:

double crossZ = Vector3d.CrossProduct(ePrev, eNext).Z;
bool isConvex = crossZ > 0;

1. 向量叉积的几何意义

在三维空间中,两个向量 $\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)$ 的正负号。

2. 右手定则 (Right-Hand Rule)

判断 Z 分量正负的直观方法是使用右手定则

  1. 伸出右手,四指指向第一个向量 $\vec{A}$ (即代码中的 `ePrev`) 的方向。
  2. 将四指弯曲向第二个向量 $\vec{B}$ (即代码中的 `eNext`) 的方向。
  3. 大拇指的指向就是叉积结果的方向(Z轴方向)。
Z 分量符号 大拇指指向 旋转方向 (从 A 到 B) 几何含义 (左/右转)
正 (+) 指向屏幕外 (Z+) 逆时针 (CCW) 向左转 (Left Turn)
负 (-) 指向屏幕内 (Z-) 顺时针 (CW) 向右转 (Right Turn)
零 (0) 共线 直线,无转弯

3. 结合代码的具体分析

在你的代码中:

想象你沿着多边形的边界行走:

  1. 你先沿着 `ePrev` 走。
  2. 到了当前点,你需要转向 `eNext` 的方向继续走。

判定逻辑: 如果 `crossZ > 0`,根据右手定则,这意味着从 `ePrev` 到 `eNext` 是逆时针旋转。 在二维平面行进中,逆时针旋转等同于向左转

4. 为什么 "向左转" 代表 "凸角"?

这取决于多边形的点的排列顺序(Winding Order)

通常在 GIS 和图形学算法中,定义一个实心多边形的标准是:

在此前提下:

  1. 凸角 (Convex):行进时向转(角度 < 180°)。此时 `CrossZ > 0`。
  2. 凹角 (Concave):行进时向转(角度 > 180°,向内凹陷)。此时 `CrossZ < 0`。

示意图:CCW多边形中的左转与右转

注意:如果你的多边形是顺时针 (CW) 排列的(例如某些图形库如 GDI+ 的默认行为),那么逻辑会完全反过来:`CrossZ < 0` 才是凸角。

代码中的 `bool isConvex = crossZ > 0;` 隐含假设了输入数据 `input` 是逆时针排列的。

5. 总结

代码 数学含义 物理动作 形状特征 (CCW多边形)
crossZ > 0 逆时针旋转 向左拐弯 凸 (Convex)
crossZ < 0 顺时针旋转 向右拐弯 凹 (Concave)

这段代码利用叉积的 Z 分量,快速判断了在当前顶点处,路径是向左拐还是向右拐,从而识别出需要处理的“凸”尖角。