确定一个2D矢量是否在另一个的右侧或左侧

时间:2012-11-04 19:11:08

标签: javascript geometry

给定两个2D向量,如何判断第二个向右(顺时针)第一个,还是向左(逆时针)?

例如,在这些图中,B是A

的右侧(逆时针)
A   B   .       .----> A
^  ¬    |\      |   
| /     | \     |  
|/      V  \    V 
.       B   A   B

4 个答案:

答案 0 :(得分:29)

您可以使用点积来实现此目的。 dot(a, b) == a.x*b.x + a.y*b.y可用于查找向量是否垂直:

var dot = a.x*b.x + a.y*b.y
if(dot > 0)
    console.log("<90 degrees")
else if(dot < 0)
    console.log(">90 degrees")
else
    console.log("90 degrees")

换句话说。 dot > 0会告诉您a是否在“b之前”。


假设b位于a的右侧。逆时针旋转b 90度会使其位于a前面 现在假设b位于a的左侧。逆时针旋转b 90度将其置于a之后。

因此,dot(a, rot90CCW(b))的符号会告诉您b是在rot90CCW(b) == {x: -b.y, y: b.x}处的a的右侧还是左侧。

Simplyifying:

var dot = a.x*-b.y + a.y*b.x;
if(dot > 0)
    console.log("b on the right of a")
else if(dot < 0)
    console.log("b on the left of a")
else
    console.log("b parallel/antiparallel to a")

答案 1 :(得分:1)

在@Eric评论的澄清中,“如果A指向前方,它的哪一方是B?”

在这个表述中,答案很简单。 “A”指向前方,如示例中所示,其x坐标为零。有了这个假设,当它的x坐标为正时,“B”在右边,当为负时,在左边,而当它为零时,则为左边。

在一般位置将此澄清扩展为“A”意味着引入新的坐标系,如下所示:“在A指向前方的坐标系中,......”。最简单的新坐标系是基向量为A(1,0)的坐标系。 (如果A是(1,0)的倍数,那么它只是基本情况的90度旋转。)坐标变换是L : P = (P_x, P_y) --> P' = (P'_x, P'_y) = (A_y * P_x - A_x * P_y, P_y)。这种线性变换称为偏斜变换。测试是坐标P'_x的符号。检查L是否将A带到新坐标系中的向量(0,1)。此方法使用与其他答案相同的算法。

我写了这篇文章,以便更深层的几何内容可能会有所启发。

答案 2 :(得分:0)

如果向量是正交的,点积方法不起作用。对于一般情况,您希望使用矩阵 [A B] 行列式的符号,其中 A 和 B 是您的 向量。一个伪代码是

c=sign(det([A B]))

这里,如果 c>0 表示 B 在左边。这将根据矩阵中 A 和 B 的顺序进行切换。

答案 3 :(得分:-1)

@Eric当矢量大小变化很大时,你的点积有一个基本问题。

var dot = a.x * -b.y + a.y * b.x;

如果a(2,-2)和b(-500,-500)明显B位于a的左侧,但是做点积时它会大于0。