给定两个2D向量,如何判断第二个向右(顺时针)第一个,还是向左(逆时针)?
例如,在这些图中,B是A
的右侧(逆时针)A B . .----> A
^ ¬ |\ |
| / | \ |
|/ V \ V
. B A B
答案 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。