Sign in to follow this  
chillypacman

Deriving an angle from a vector - bleh

Recommended Posts

This is kind of confusing me and it really shouldn't but maybe it should? Basically I'm trying to derive an angle in world space from a vector to orient a 3D model (zombies moving in any given direction). So basically I normalize the vector then do basic trigonometry to figure out the angle, the code is fairly simple:
D3DXMATRIX rot;
        D3DXVECTOR3 look = beings[i].eyes.getLook();

        //just in case look was modified without being normalized (possibly when attacking):
        D3DXVec3Normalize(&look, &look);
        beings[i].eyes.setLook(look);

        //figure out which quadrant we're dealing with and add pi offset (or whatever they call it)
        //on top of the trig equation
        if(look.x > 0 && look.z > 0)
        {
            float z = sqrt(look.x * look.x + 1);
            D3DXMatrixRotationY(&rot, atan2(look.x, z));
        }
        else if(look.x > 0 && look.z < 0)
        {
            float z = sqrt(look.x * look.x + 1);
            D3DXMatrixRotationY(&rot, atan2(look.x, -1 * z) + pi/2);
        }
        else if(look.x < 0 && look.z < 0)
        {
            float z = sqrt(look.x * look.x + 1);
            D3DXMatrixRotationY(&rot, atan2(look.x, -1 * z) + (3*pi)/2);
        }
        else if(look.x < 0 && look.z > 0)
        {
            float z = sqrt(look.x * look.x + 1);
            D3DXMatrixRotationY(&rot, atan2(look.x, z) + 2*pi);
        }
So it's the whole quadrant circle deal and whatnot. The problem is the model seems to flip (mirror?) vertically when it moves from the first to second quadrant and third and fourth quadrant so in other words the zombies left is swapped with its right. No problems when it's moving from the fourth to first or second to third. I'm not sure if I'm overlooking something obvious here or if it's just normal for it to happen but no one told me?

Share this post


Link to post
Share on other sites
Why exactly are you adding different offsets and using a big if statement? I'm a little confused at what you're trying to do here...

If you want the zombie to face in the direction of the vector in the X/Z plane, the code should be very simple.



look.y = 0;
D3DXVec3Normalize(&look, &look);
D3DXMatrixRotationY(&rot, atan2(look.z, look.x));



That assumes your model originally faces in the direction of positive x. If it faces in the direction of positive z, you can subtract pi/2 from the angle to offset it.




Share this post


Link to post
Share on other sites
can't you just do:

D3DXVECTOR3 look = beings[i].eyes.getLook();
// assuming look is in the XZ-plane only (i.e., y = 0)
float angle = atan2( look.z, look.x );

Or maybe some permutation depending on coordinate system and what not, i.e.,

float angle = atan2( -look.z, look.x );
or
float angle = atan2( look.z, -look.x );

My main point is the vector "look", when normalized, should already correspond to a point on the unit circle, which means x = cos( theta) and z = sin( theta ); these are also the x and y that atan2 expects. If you still want your angle in [0, 2pi], and not [-pi, +pi], you can always just add 2pi to the result if angle < 0. Should simplify the logic significantly (you shouldn't have to do all those cases).

An alternative to finding the angle is just to use the look vector directly and reconstruct your matrix from this vector. E.g., assuming "up" is (0,1,0), you can cross Up with your look to get your "x" vector, then cross x with your look to get the y axis for the matrix. This latter description is just a brief sketch, i.e., I don't know if you're in a left-handed or right-handed coord system, what your conventions are for which axis "look" corresponds to, etc... just a thought.

Share this post


Link to post
Share on other sites
Quote:
Original post by MJP
Why exactly are you adding different offsets and using a big if statement? I'm a little confused at what you're trying to do here...

If you want the zombie to face in the direction of the vector in the X/Z plane, the code should be very simple.



look.y = 0;
D3DXVec3Normalize(&look, &look);
D3DXMatrixRotationY(&rot, atan2(look.z, look.x));



That assumes your model originally faces in the direction of positive x. If it faces in the direction of positive z, you can subtract pi/2 from the angle to offset it.


I tried that but the zombie turns twice as fast as it should and when it should be facing up it faces down and when it should be facing downwards it faces upwards. Addint an offet doesn't help because al it does is offset the initial amount of how far it turns, it turns twice as fast as it should in any case.

Share this post


Link to post
Share on other sites
It sounds like you may be multiplying the old rotation to the new rotation and getting a larger rotation than desired.

The rotation matrix call given by MJP is for the total rotation of the object. Make sure your world matrix is set to identity before you rotate the object.

If that doesn't work, post a short section of code where you set up the matrices for drawing the object and we'll see what the problem is.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this