5
\$\begingroup\$

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;
  }
  else 
  {
    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.

\$\endgroup\$
2
  • 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, 2012 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, 2012 at 2:22

1 Answer 1

15
\$\begingroup\$

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.

\$\endgroup\$
4
  • \$\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, 2012 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, 2012 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\$ Dec 27, 2012 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, 2012 at 21:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .