给定两个二维向量,如何判断第二个向量是在第一个向量的右侧(顺时针)还是在左侧(逆时针)?
例如,在这些图中,B 在 A 的右侧(逆时针)
A B . .----> A
^ ¬ |\ |
| / | \ |
|/ V \ V
. B A B
给定两个二维向量,如何判断第二个向量是在第一个向量的右侧(顺时针)还是在左侧(逆时针)?
例如,在这些图中,B 在 A 的右侧(逆时针)
A B . .----> A
^ ¬ |\ |
| / | \ |
|/ V \ V
. B A B
您可以使用点积来实现这一点。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 是在 a 的右侧还是左侧,其中rot90CCW(b) == {x: -b.y, y: b.x}
。
简单化:
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")
在@Eric 的评论中的澄清中,“如果 A 指向前方,B 在它的哪一边?”
在这个公式中,答案非常简单。“A” 指向前方,如示例中所示,当其 x 坐标为零时。有了这个假设,“B”在其 x 坐标为正时在右侧,在负时在左侧,在零时都不在。
将此说明扩展到一般位置的“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)。此方法使用与其他答案相同的算术。
我写了这个,以便更深层次的几何内容可能会有所启发。
如果向量是正交的,则点积方法不起作用。对于一般情况,您希望使用矩阵 [AB] 的行列式的符号,其中 A 和 B 是您的列向量。一个伪代码是
c=sign(det([AB]))
这里,如果 c>0 表示 B 在左侧。这将根据矩阵中 A 和 B 的顺序进行切换。
@Eric 但是当矢量大小变化很大时,您的点积存在一个基本问题。
var dot = ax*-by + ay*bx;
如果 a(2,-2) 和 b(-500,-500) 显然 B 在 a 的左侧,但是做点积会大于 0。