Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Signed angle between vectors

  1. Apr 8, 2008 #1
    The following discussion is in 2 dimensions:

    Take two vectors, A and B. Generally we find the angle (theta) between them by
    cos(theta) = dot(A,B) / (norm(A) * norm(B))

    however, take vector A to be [0, 1] (straight up)

    If vector B is [1,1], the angle between them is pi/4 radians. If vector B is [-1, 1], the angle between them is STILL pi/4 radians!!

    I need to know the signed angle between them (one of the B's above should be -pi/4, the other, pi/4). How would I do that?


  2. jcsd
  3. Apr 8, 2008 #2
    Well, such a signed angle measure would have to be assymmetric in its arguments. I.e., angle(A,B) = -1*angle(B,A), right?

    More generally, it seems that you'd need some kind of convention to specify which vector is the "reference" vector. In your above example, A played this role. So, supposing we make the first vector in the argument the reference, how would we go about getting a signed angle? Presumably we still want to normalize by the norms of the vectors in question, but then it follows that we need to change the dot product. Can you think of a way to modify it to reflect sign?
  4. Apr 8, 2008 #3
    No problem choosing a reference angle. I saw something called the "perp dot product" which rotated one vector pi/2 (we'll say C=(A rotated by pi/2) and then said
    sin(theta) = dot(C,A)/(norm(A)*norm(C))

    I tried this and I still was getting positive numbers both ways (unless I did something wrong - maybe rotated A the wrong way?)

    Any other thoughts?

  5. Apr 8, 2008 #4

    That looks to just be the regular cosine applied to a vector that's been rotated ahead of time. And, yeah, since the regular cosine gives you positive angles, this will too.

    How about this: first, compute the usual cosine between A and B, and call this [itex]\theta[/itex]. Suppose A is the reference vector, and suppose that a counter-clockwise rotations are "positive" (i.e., the right hand rule). Now, the usual cosine has given you the magnitude of the angle between A and B, but not its sign. You can determine the sign by applying a rotation of [itex]-\theta[/itex] to B and seeing if you end up parallel to A. If so, you know the sign was positive. If not, you know the sign was negative.
  6. Apr 8, 2008 #5
    Since you only want an answer for R^2, use a complex polar representation:

    \hat{b} = \hat{a} \exp(i\theta)

    \theta = -i \ln(\hat{b}/\hat{a})

    EDITed: forgot to write the hats above (ie: scale by length first just as with the typical cosine formula).
    Last edited: Apr 9, 2008
  7. Apr 9, 2008 #6
    quadraphonics: it seems like there may be some numerical error in check if the resulting rotated vector is parallel to the original vector. And you may also run into a case where the two vectors are originally perpendicular, so then no matter which way you rotate one of them they end up parallel...

    Peeter, I dont understand - theta seems to be a complex number, how does this tell me the signed angle?
  8. Apr 9, 2008 #7
    theta's real in this case. The log of the quotient isn't, and that's why the -i factor is needed. Without loss of generality (since you can scale), for two unit vectors you have:

    \bar{a}b = (a_1 b_1 + a_2 b_2) + i (a_1 b_2 - a_2 b_1) = \cos(\theta) + i\sin(\theta)

    Roughly speaking, if you cosine (the dot product) is positive you can tell the angle is in the first or third quadrant. If the sine (the wedge product part of the vector product) is positive you know the angle is in the first or second quadrant.

    Using just [tex]\cos(\theta) = a \cdot b[/tex], you have really tossed half of the product information. In complex numbers, the log gives you both parts of the info to determine the angle appropriately (up to a factor of [tex]2 \pi n[/tex]).

    A good treatment of this can be found in the Hestenes book "New foundations for Classical Mechanics". He treats the general case for vectors of dimension >=2, but for R^2 the ideas all reduce to classical complex variables.
  9. Apr 9, 2008 #8
    Well, what I meant by 'check if they're parallel' was actually 'check that [itex]A^TB=|A||B|[/itex].'
  10. Apr 9, 2008 #9
    quadraphonics - if i'm not mistaken A'B will only equal |A||B| if theta is exactly equal 0 (because then cos(theta) = 1) - there will still be some numerical error?

    peeter- i'll take a look at doing it using actual complex numbers tomorrow
  11. Apr 9, 2008 #10
    fyi. The following two wikipedia article's look like they spell out the angle conversion if you don't have an arg() function handy:



    I tried on my hand calculator with a = (3,1) and b=(2,-2) and [tex]arg(\sqrt{(10/8) }((2,2)/(3,1)))[/tex] gives -63 degrees for the angle from a to b, which looks about right by eye.
  12. Apr 10, 2008 #11
    There's going to be numerical error in any finite-precision computation. You just make sure to use enough precision that you can ignore it. I'm not sure what your point is here.
  13. Apr 10, 2008 #12
    my point is that if you have a function that gives the signed angle and it has a precision error the angle should be 60 but it is really 59.9999 that is no problem, but if you have a conditional statement, to say
    if (Rotated Vector B is parallel to Vector A)

    and that comparison had an error, then you're in big trouble

    of course you could fix it by saying

    if (Angle between A and Rotated B is < epsilon) where epsilon is .0001 or something

    but that seems very "not nice" haha

    peteer - thanks for the links

    everyone - i appreciate it - i got it working!

  14. Apr 10, 2008 #13
    Well, if 59.9999 is close enough to 60 for you, then I see no reason why 0.0001 shouldn't be close enough to 0.

    More generally, though, maybe you can avoid this issue. That is, you try applying the positive and negative rotations to one of the vectors. One is going to make it more parallel, and the other is going to make it less parallel (or, equivalently, more anti-parallel). So, you don't have to check that it's *exactly* parallel (even though it should theoretically be so), but just confirm that the other possible rotation made it *less* parallel. What I mean is that for any non-zero angle [itex]\theta[/itex], when you rotate one of the vectors by that angle, the inner-product between the result and the other original vector is going to either increase or decrease. That it should come out to 0 for one of the rotations doesn't really matter; you just pick the sign such that you get an increase in the resulting inner product.
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook