CCW 算法说明
Explanation of ccw algorithm
我在理解 ccw(逆时针(算法时遇到了一些麻烦:
int ccw (Point P0, Point P1, Point P2) {
dx1 = P1.x - P0.x;
dx2 = P2.x - P0.x;
dy1 = P1.y - P0.y;
dy2 = P1.y - P0.y;
if (dy1 * dx2 > dy2 * dx1) return -1;
if (dx1 * dy2 > dy1 * dx2) return 1;
if ((dx1 * dx2 < 0) || (dy1 * dy2 < 0)) return 1;
if ((dx1 * dx1 + dy1 * dy1) < (dx2 * dx2 + dy2 * dy2)) return -1;
return 0;
}
它用于查看两行是否相交的代码:
bool intersect (Vector2D l1, Vector2D l2) {
return (((ccw(l1.start, l1.end, l2.start) * ccw(l1.start, l1.end, l2.end)) <= 0)
&& ((ccw(l2.start, l2.end, l1.start) * ccw(l2.start, l2.end, l1.start)) <= 0))
}
我可以理解相交函数中的代码,但我并不真正理解 ccw 函数中的代码。
为什么不使用交叉乘积?
函数内部的代码ccw
以一种相当临时的方式编写,但它确实使用了有时非常非正式地称为交叉乘积的 2D 版本。对于两个向量(dx1, dy1)
和(dx2, dy2)
,乘积定义为标量值等于
CP = dx1 * dy2 - dx2 * dy1;
(在形式正确的术语中,CP
实际上是向量(dx1, dy1, 0)
和(dx2, dy2, 0)
的经典 3D 交叉乘积的符号大小。显然,该值只是一个标量(点(积,其中一个向量被其垂直方向所取代。
如果 CP
的值为正,则从 (dx1, dy1)
到 (dx2, dy2)
的最短径向扫描将逆时针方向移动。负CP
表示顺时针扫描。CP
中的零表示共线向量。(所有这些都假设 Y 轴向上,X 轴指向右侧。
显然,CP > 0
条件等同于dx1 * dy2 > dx2 * dy1
条件,CP < 0
等同于dx1 * dy2 < dx2 * dy1
。这正是您的ccw
函数在前两个if
检查的内容。
其余if
处理共线情况。
如果向量指向相反的方向(由第三个if
检测到(,即当P0
位于P1
和P2
之间时,该函数总是返回1
,表示逆时针排序。嗯,我想这只是代码作者假设的约定。
最后,如果两个向量指向同一方向,即当P0
位于P1-P2
段之外时,则决策基于向量长度(第四if
(。如果P1
接近P0
P2
,则报告顺时针顺序。否则,如果P2
更接近,则报告逆时针顺序。这也只是代码作者假设的约定。
而且,从代码的其余部分来看,它不是关于两行的交集。它是关于两个部分的交集。
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 当使用通配符和null指针调用函数时,对输出的说明
- 算法问题:查找从堆栈中弹出的所有序列
- 下面是排序算法O(n)吗
- KMP算法和LPS表构造的运行时间
- 为什么我的排序算法会更改数组值
- 求最大元素位置的分治算法
- 具有非整数边容量的最大流量的Dinic算法
- 到连接组件算法的问题(递归)
- 关于C++中具有多重继承"this"指针的说明
- STL算法函数在多个一维容器上的使用
- 读取最后一行代码算法 - c++ 时出现问题
- 减少整数分数算法-解决方案说明
- CCW 算法说明