首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ccw算法的解释

ccw算法的解释
EN

Stack Overflow用户
提问于 2014-10-11 13:54:49
回答 1查看 4.5K关注 0票数 3

我很难理解ccw (逆时针方向)算法:

代码语言:javascript
复制
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;
}

它用来查看两行是否相交的代码:

代码语言:javascript
复制
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))
}

我可以理解intersect中的代码,但我并不真正理解ccw函数中的代码。

为什么它不使用交叉产品?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-11 17:40:45

ccw函数中的代码是以一种非常特殊的方式编写的,但它确实使用了有时非常非正式地称为2D版本的交叉积。对于两个向量(dx1, dy1)(dx2, dy2),乘积被定义为等于

代码语言:javascript
复制
CP = dx1 * dy2 - dx2 * dy1;

(在形式上正确的术语中,CP实际上是向量(dx1, dy1, 0)(dx2, dy2, 0)的经典三维交叉积的符号大小。)因此,这个值只是一个标量(点)乘积,其中一个向量被它的垂直方向所代替。

如果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位于P1P2之间时,函数总是返回1,指示逆时针顺序。好吧,我想这只是代码作者的约定。

最后,如果两个向量指向相同的方向,即当P0位于P1-P2段之外时,则判决基于向量长度(第四if)。如果P1P2更接近P0,则报告顺时针顺序。否则,如果P2更接近,则报告逆时针顺序.这也只是代码作者所假定的约定。

而且,从代码的其余部分来看,这并不是关于两行的交点。它是关于两个段的交点。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26315401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档