I'm reading Programming Game AI by Example by Mat Buckland. In the Math & Physics primer chapter there's a listing of the declaration of a class used to represent 2D vectors.

This class contains a method called Sign. It's implementation is as follows

//------------------------ Sign ------------------------------------------
//  returns positive if v2 is clockwise of this vector,
//  minus if anticlockwise (Y axis pointing down, X axis to right)
enum {clockwise = 1, anticlockwise = -1};

inline int Vector2D::Sign(const Vector2D& v2)const
  if (y*v2.x > x*v2.y)
    return anticlockwise;
    return clockwise;

Can someone explain the vector rules that make this hold true?

What do the values of y*v2.x and x*v2.y that are being compared actually represent?

I'd like to have a solid understanding of why this works rather than just accepting that it does without figuring it out. I feel like it's something really obvious that I'm just not catching on to.

Thanks for your help.

  • 5
    \$\begingroup\$ It looks like it's looking at the sign of the cross product, which would be x * v2.y - y * v2.x. When the cross product is negative, y * v2.x > x * v2.y. \$\endgroup\$ – amitp Dec 12 '12 at 2:10
  • \$\begingroup\$ I think I've found a page that describes what's being done: oocities.org/pcgpe/math2d.html The section entitled 'Clockwise/Anticlockwise'. At the bottom of that section they have the following: if ((E1x * E2y - E1y * E2x) >= 0) clockwise = TRUE; else clockwise = FALSE; If the E1Y * 2x is brought over to the other side of the equation you have a very similar comparison. And once you account for the fact that they are using a coordinate system in which +Y goes up, rather than down as stated in the code snippet, I think it's pretty much the same thing. \$\endgroup\$ – MTLPhil Dec 12 '12 at 2:22

Let's first discuss the dot product. A·B is a measure of A's component in the direction of B or vice versa; of the magnitudes of both vectors as well as their similarity in direction. Vectors pointing in the same direction have a dot product equal to the product of their lengths, perpendicular vectors have a dot product of zero. Turn the vectors even further apart, and the dot product becomes negative. Though normally defined as (x,y)·(u,v) = xu + yv, it has the property: A·B = A B cos θ, where θ is the angle between the two vectors.

The sign of this product can be used to determine whether a vector B partly points in the same or opposing direction of a reference vector A, i.e. if A·B is positive, the angle is less than 90° (or greater than -90°). It doesn't tell us if the vector points left or right with respect to the reference. Below is a graphical description. Blue vectors B would yield a positive A·B, red vectors a negative.

Vector diagram 1

We do have this information we want if we carry out the dot product of B and a different reference vector: A rotated ninety degrees clockwise (we'll call it A'). Once again, in blue vectors B that would yield a positive A'·B, negative values in red.

Vector diagram 2

Note that in a coordinate system with the x-axis pointing right and the y-axis pointing down, we can rotate a vector 90° clockwise as (x,y)' = (-y,x), ergo: A'·B = (x,y)'·(u,v) = (-y,x)·(u,v) = -yu + xv. This number is positive (B is clockwise of A) if x v > y u. Those are exactly the two values your code is comparing.

  • \$\begingroup\$ I could be wrong but I think (-y,x) yields a counter clockwise rotation and (y,-x) yields a clockwise rotation by 90 degrees. (-y,x) = (1,1) == (-1,1) (y,-x) = (1,1) == (1,-1) \$\endgroup\$ – Alex Brown Dec 27 '12 at 18:52
  • \$\begingroup\$ and thanks for a detailed answer. I keep reinventing the wheel when it comes time to rotate an object in the direction the user clicked. This makes so much sense to me now I wish I could give you 10 upvotes. \$\endgroup\$ – Alex Brown Dec 27 '12 at 18:57
  • 1
    \$\begingroup\$ @AlexBrown: Assuming the x-axis points right and the y-axis points up, (-y,x) is indeed the counter-clockwise rotation of (x,y). However, the question uses a coordinate system in which the y-axis points down. That's easily overlooked though. I will add it to my answer for completeness. Thanks. \$\endgroup\$ – Marcks Thomas Dec 27 '12 at 19:35
  • \$\begingroup\$ I see it now in the comments of the code. I knew I was missing something ;) \$\endgroup\$ – Alex Brown Dec 27 '12 at 21:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.