凸多边形判定需所有连续三顶点构成折线转向一致,通过计算相邻边二维叉积符号实现:对每个i,计算v1×v2=(p[i+1]−p[i])×(p[i+2]−p[i+1]),所有非零结果同号即为凸;整数坐标下须用long long防溢出。

用叉积符号判断每条边的转向是否一致
凸多边形的本质特征是:所有连续三条顶点构成的折线,其转向(左转或右转)必须完全一致(全为逆时针或全为顺时针)。C++ 中最稳定、无浮点误差风险的做法是计算每组相邻边的二维叉积符号。
假设顶点按顺序存储在 vector<pair double>></pair> 或 vector<point></point> 中(Point 含 x, y),对每个顶点 i,取向量 v1 = p[i+1] - p[i] 和 v2 = p[i+2] - p[i+1],计算叉积 v1.x * v2.y - v1.y * v2.x。这个值的正负号就代表转向。
- 所有非零叉积结果同号(全 > 0 或全
- 出现一个 0 → 三点共线,严格凸定义下不接受;若允许退化,需额外判断是否影响整体凸性
- 符号混杂(既有正又有负)→ 必定凹
注意顶点顺序和首尾闭合处理
算法依赖顶点是**按顺序(顺时针或逆时针)给出的简单多边形**。如果输入乱序或自交,结果无意义。实际使用前应确保:
- 顶点数 ≥ 3,否则直接返回 false
- 用模运算处理边界:对第
n-2个顶点,i+2应为(i+2) % n;同理i+1用(i+1) % n - 不要漏掉最后两组:即
i = n-2和i = n-1对应的三角形(p[n-2], p[n-1], p[0]和p[n-1], p[0], p[1])
避免浮点精度导致的误判
当坐标是 double 类型时,叉积结果可能因精度误差接近 0,但不等于 0,造成符号误判。不能直接用 > 0 / 判断,而应引入小量容差:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
定义 const double eps = 1e-9;,再用:sign = (cross > eps) ? 1 : (cross
- 一旦出现
sign == 0,跳过该组(共线),但记录;若后续出现异号sign,立即返回 false - 若全部为 0 → 所有点共线,不是多边形
- 只靠
== 0判断会崩溃,比如cross == 0.0在浮点下几乎不可能成立
整数坐标下可完全避免精度问题
如果输入顶点是整数(int),叉积结果也是整数,此时可安全使用 if (cross > 0) 等直接比较,无需 eps。这是嵌入式、几何竞赛或栅格地图场景下的优选方案。
但要注意:整数溢出。若坐标范围大(如 ±10⁵),两个 int 相乘可能溢出 int。应强制转为 long long 计算叉积:long long cross = (long long)(p1.x - p0.x) * (p2.y - p1.y) - (long long)(p1.y - p0.y) * (p2.x - p1.x);
漏掉类型提升会导致静默错误,且极难调试。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










