Vector rotation and dot product question

Started by
4 comments, last by Crazy Chicken 19 years, 3 months ago
I have two 2D vectors A and B and my goal is to rotate A so it faces in the same direction as B. I have computed the angle between the vectors using the dot product but I still need to find out whether the angle is negative or positive. My question is this: What is the simplest and most efficient way of finding out which way I need to rotate the vector? I can think of three possible solutions: 1: Rotate vector A by the computed angle and check if the new vector is equal to the target vector B. If not, rotate the other way. 2: Check in which quadrant of the coordinate system vector A is located. Then check in which quadrant vector B is located. Depending on the quadrant of B the rotation direction can be discovered. 3: Use a hypothetical third axis and compute the cross product between vector A and B. The perpendicular vector will be either positive or negative depending on whether B is to the left or right of A. When rotating around that vector the rotation will always be in the right direction. Any suggestions would be greatly appreciated. Thx
Advertisement
#1 seems inefficient. #2 doesn't work. I suggest #3 -- it's trivial.

Just check the sign of xAyB-xByA. If it is negative, then your angle of rotation from A to B is negative.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
The easy way : atan2

The standard way uses these three steps (you search alpha):
1) dot prod, divide by the lengths (normas) and you get c=cos(alpha)
2) cross prod, divide by the lengths (normas) and you get s=sin(alpha)
3) atan2 gives you alpha = atan2(s,c)

Note that atan2 is as speedy as the acos you used (I suppose). Bur it's even better, you get rid of testing signs, and your code remains clear and concise.

Also note that you don't necessarilly have to define a rotation in the polar form (angle + scaling factor). You can also simply define a matrix, then you don't need any trigonometry, just linear algebra.
"Coding math tricks in asm is more fun than Java"
Quote:Original post by Crazy Chicken
I have two 2D vectors A and B and my goal is to rotate A so it faces in the same direction as B.

My question is this:

What is the simplest and most efficient way of finding out which way I need to rotate the vector?


You have to rotate A around an extern axis (that is a vector pointing in/out from your plane) by an agle a.

If you know a to rotate a vector you can use the rotation matrix

    |  c   s  |R = |         |  where c = cos(a) and s = sin(a)     | -s   c  |


and multiply A by R

R * A = (c*ax+ s*ay, c*ay - s*ax)


How to compute a ?

The angle you need can be computed from the scalar product ('dot')

i) A * B = (ax,ay)*(bx,by) = ax*bx + ay*by


but it is also

ii) A * B = |A|*|B|*cos(a)where |A| = sqrt(A*A) = sqrt(ax*ax+ay*ay)      |B| = sqrt(B*B) = sqrt(bx*bx+by*by)


hence

cos(a) = A*B/(|A|*|B|)


that is

a = arcos((ax*bx+ay*by)/(|A|*|B|))   


Rotate CW or CCW?

If you compute the extern product ('cross')

A x B = (ax,ay,az) x (bx,by,bz) = (vx,vy,vz)


where

az = 0bz = 0vx = ay*bz-az*by = 0    // right because v is 'extern'vy = az*bx-ax*bz = 0vz = ax*by-ay*bx 


If vz is positive you have to rotate A counterclockwise(CCW), CW if vz is negative (this is the 'right hand rule').

if vz>0    rotate CCW by a else    CW by a


Note1 : if vz = 0 -> a = 0° or 180°

Note2 : Charles is right too because |A x B| is also equal to
vz = |A x B| = |A|*|B|*sin(a) -> tan(a)=sin(a)/cos(a) -> compute a
Code

// returns the angle CCW needed to rotate A and make it parallel to Bfloat GetAngle(const Vector& A, const Vector& B){  float a  = acos( (A*B)/(A.Len()*B.Len()) );  return( A^B>0 ? a : -a );}float Vector::Len(void)const{ return(sqrt((*this)*(*this)));}float Vector::operator * (const Vector& B)const{  return(x*B.x+y*B.y);}float Vector::operator ^ (const Vector& B)const{  return(x*B.y-y*B.x);} 
Great. Thanks a lot people!

This topic is closed to new replies.

Advertisement