Eric
Eric

Reputation: 97631

Determining if one 2D vector is to the right or left of another

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

Answers (4)

manifoldcurious
manifoldcurious

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

Gab
Gab

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

eh9
eh9

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

Eric
Eric

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

Related Questions