How do you interpolate to get the desired angel?

Started by
13 comments, last by Motorherp 17 years, 10 months ago
wouldn't cubic spline interpolation work here
Advertisement
Why what would that do and can you give an example on how you would implement it
Quote:Original post by Motorherp
Quote:Original post by smurfkiller
Whats wrong with good old vector to vector interpolation :)


Sadly there's a few ;). For a start he's wanting to rotate an orientation matrix so that its heading vector looks at a certain point in space (the intruder). Interpolating the heading vector is one thing but what do you do with the rest of the matrix? This type of vector interpolation only realy works for vectors which are already closely aligned anyway since you're effectively interpolating across a line where as the vector would sweep out an arc. Since the length of the vector changes across the interpolation line this leads to uneven rotation, and in the worse case, when you want to get to a vector which is the exact opposite, results in zero rotation or instantaneous flipping. This is why its much better to rotate, or even better still do it with quaternions.


Edit: Doh, beaten to the punch ;)


Ofcaurse there is alot of work to do after you have interpolated the direction vector. I asumed he new what to do next. That was just an example how to make a moderatly smooth turn. It is ofcourse much better to use quaternions in theese cases instead of linear interpolation and reorthonormalizing the rotation matrix. Actualy there is smooth interpolation for matrices too but thats not as effective as quaternion interpolation.

By the way thats probably the most basic problem in a game engine and there is tons and i meen tons of information on the net about that case.

Crush your enemies, see them driven before you, and hear the lamentations of their women!
Quote:Original post by Prog101
Right Guys i have solved it, all i have to do is calculate when they are facing each other and stop the rotation.

//Get the inverse of the Enemy matrix
mat4 EnemyMatInversed;
f32 angleToPlayer;

//get the inverse of the Enemy matrix
Matrix_m3inversed(&EnemyMatInversed,&pData->Enemy2Matrix);

/*Multiply the Player Matrix by the Inversed Enemy Matrix and store it in Mat Result*/
Matrix_m3prodd(&pData->MatResult, &pData->PlayerMatrix,& EnemyMatInversed);
angleToPlayer = Maths_atan2 (pData->MatResult.mat[2][0],pData->MatResult.mat[2][2]);

if ( angleToPlayer < 0 )
Matrix_m3roty(&pData->EnemyMatrix, -0.2);
else Matrix_m3roty(&pData->EnemyMatrix, 0.2);



Thats not a very good solution to my opinion. First of all you do not use any time information (probably because you asume there is a constant framerate of 30fps or something), but what hapens if framerate drops or you want to run at highest framerate posible? The matrix inversion and multiplication works but i don't think you should use them in this case.

I would do it like this:
Vector3 heading = Vec3Lerp(playerDir, enemyDir, Clamp(rotationSpeed * deltaTime);Vector3 axis = playerMatrix.GetY();float angle = atan2(-heading.x, heading.z);Quaternion rotationQuat = QuatFromAngleAxis(angle, axis);Matrix3 rotationMatrix = QuatToMatrix3(rotationQuat);

"rotationMatrix" now rotates your player to desired position.
Crush your enemies, see them driven before you, and hear the lamentations of their women!
Quote:Original post by Prog101
Right Guys i have solved it, all i have to do is calculate when they are facing each other and stop the rotation.

//Get the inverse of the Enemy matrix
mat4 EnemyMatInversed;
f32 angleToPlayer;

//get the inverse of the Enemy matrix
Matrix_m3inversed(&EnemyMatInversed,&pData->Enemy2Matrix);

/*Multiply the Player Matrix by the Inversed Enemy Matrix and store it in Mat Result*/
Matrix_m3prodd(&pData->MatResult, &pData->PlayerMatrix,& EnemyMatInversed);
angleToPlayer = Maths_atan2 (pData->MatResult.mat[2][0],pData->MatResult.mat[2][2]);

if ( angleToPlayer < 0 )
Matrix_m3roty(&pData->EnemyMatrix, -0.2);
else Matrix_m3roty(&pData->EnemyMatrix, 0.2);


Rightio, looks like you're getting close to something that will do the job, at least for x-z plane rotations anyway. A couple of pointers though:

1) For orthonormal matricies the transpose is the same as the inverse and is much cheaper to calculate so use this instead. In fact you could create transpose multiply functions so that its not actualy necessary to calculate the transpose and store it in a temporary matrix.

2) You're only inetersted in the rotated z vector so you only need to do a (transpose)matrix-vector multiply rather than a matrix-matrix multiply. This will also save you a lot of calculations.

3) Finaly you'll find using your logic that when the object becomes aligned it will jiggle back and forth as angleToPlayer swings positive and negative. You'll want to rotate by min(0.2, angleToPlayer) or max(-0.2, angleToPlayer) instead.

Hope this helps



[Edit:] Sorry I jumped ahead of myself there and didn't really analyse the maths you wrote. I'm afraid what you're doing is still not getting the correct rotation. Like i said in my previous post, if you want to do it this way you have to rotate the vector between player and enemy and extract the angle from this. The angle you're actually calculating there is the difference in y angle between the two objects. All that will happen using this is that your enemy will rotate till it has the same facing as the player rather than rotating to face the player. Try drawing this stuff down on paper if you're having difficulties visualing it and go from there.

[Edited by - Motorherp on June 8, 2006 6:46:48 AM]
[size="1"] [size="4"]:: SHMUP-DEV ::

This topic is closed to new replies.

Advertisement