Reputation: 97631
Given two 2D vectors, how can you tell whether the second is to the right (clockwise) of the first, or to the left (counter-clockwise)?
For instance, in these diagram B is to the right (counter-clockwise) of A
A B . .----> A
^ ¬ |\ |
| / | \ |
|/ V \ V
. B A B
Upvotes: 13
Views: 22402
Reputation: 101
The dot product approach does not work if the vectors are orthogonal. For a general case you want to use the sign of the determinant of the matrix [A B], where A and B are your column vectors. A pseudo-code would be
c=sign(det([A B]))
Here, if c>0 is means that B is to the left. This will switch depending on the order of A and B in your matrix.
Upvotes: 0
Reputation: 19
@Eric there is a fundamental problem however with your dot product when the vector sizes vary greatly.
var dot = a.x*-b.y + a.y*b.x;
If a(2,-2) and b(-500,-500) clearly B is on the left of a, but doing the dot product it comes to greater than 0.
Upvotes: -2
Reputation: 7430
In the clarification in a comment from @Eric, "if A points forward, which side of it is B on?"
In this formulation the answer is dead-simple. "A" points forward, as in the example, when its x-coordinate is zero. With this assumption, "B" is on the right when its x-coordinate is positive, is on the left when negative, and is neither when zero.
Extending this clarification to "A" in general position means introducing a new coordinate system, as follows: "In a coordinate system where A points forward, ...". The simplest new coordinate system is the one where the basis vectors are A
and (1,0)
. (If A is a multiple of (1,0)
, then it's just a 90 degree rotation of the basic situation.) The coordinate transform is L : P = (P_x, P_y) --> P' = (P'_x, P'_y) = (A_y * P_x - A_x * P_y, P_y)
. This kind of linear transformation is called a skew transformation. The test is the sign of the coordinate P'_x
. Check that L takes A to the vector (0,1) in the new coordinate system. This method uses the same arithmetic as the other answer.
I wrote this up so that the deeper geometric content may be illuminating.
Upvotes: 1
Reputation: 97631
You can achieve this using a dot product. dot(a, b) == a.x*b.x + a.y*b.y
can be used to find whether vectors are perpendicular:
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")
Put another way. dot > 0
tells you if a
is "in front of" b
.
Assume b
is on the right of a
. Rotating b
90 degrees counterclockwise puts it in front of a
.
Now assume b
is on the left of a
. Rotating b
90 degrees counterclockwise puts it behind a
.
Therefore, the sign of dot(a, rot90CCW(b))
tells you whether b is on the right or left of a, where rot90CCW(b) == {x: -b.y, y: b.x}
.
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")
Upvotes: 46