# How do you interpolate to get the desired angel?

This topic is 4280 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have got the angle of the Enemys start rotaion and the desired angle i wish it to rotate but how do intrpolate so that my enemy does not just jump to that angle? //Get the inverse of the Enemy matrix mat4 EnemyMatInversed; mat4 MatResult; f32 angleToIntruder; //get the inverse of the Enemy matrix Matrix_m3inversed(&EnemyMatInversed,&pData->EnemyMatrix); //Multiply the Intruder Matrix by the Inversed //Enemy Matrix and store it in Mat Result Matrix_m3prodd(&MatResult, &pData->IntuderMatrix,&Enemy MatInversed); //get the angle by the atan2 of x and z angleToIntruder = Maths_atan2(MatResult.mat[3][0], MatResult.mat[3][2]); //Get the angles from the Enemy matrix f32vec3 angles; Matrix_m3matrix_to_euler(angles,&pData->EnemyMatrix); //Rotate the Matrix by a said angle tkaMatrix_m3roty(&pDat->EnemyMatrix,???);

##### Share on other sites

Well you should think the problem in another way : You know your current direction and you know the direction where the enemy lies. Which way should you turn to reach the other angle. The speed of rotation is another issue, but when you can answer the first one question, the speed is quite simple thing.

##### Share on other sites
Great googly moogly!! what are you doing there? That is truely disastrous ;). We've already told you how to solve this problem in your other thread:

http://www.gamedev.net/community/forums/topic.asp?topic_id=396808

If you're having problems understanding any of it then simply say which bits are confusing you and I'll try and make things clearer. To be honest though I get the impression that maybe you're getting in a little over your head and you need to brush up a little on your 3D maths skills. Once you're able to visualise the effects that cross products and rotations etc have on matricies and vectors these problems become trivial to work out for yourself.

##### Share on other sites
So is my equation wrong to get the angle of the Player and to get the start rotation of the Enemy?

##### Share on other sites
Quote:
 Original post by Prog101So is my equation wrong to get the angle of the Player and to get the start rotation of the Enemy?

Unfortunately this is my point exactly ... if you cant see this for yourself then you're in too deep and you need to do a bit of studying. If it helps I'll give you a run down on what exactly is going on in the maths you posted:

In the first two steps you are putting the rotational part of the intruder matrix into the object space of the enemy. You then work out the angle between the intruders position in the x-z plane (y=0) with the origin. Finaly you extract the Euler angles from the enemy matrix. It would take a pretty good imagination and some more maths to use this data to rotate the enemy to face the intruder ;).

I do see what it is you're trying to do though. If you subtract the enemies position from the intruders position, rotate the resulting vector by the inverse matrix you calculated, the take the angle to this point this will give you the angle to rotate by. Its a very inefficient way of doing it though.

Time to crack out the maths books and the pencils and paper ;). I recommend 'Engineering Mathematics by K.A.Stroud'.

##### Share on other sites
oh wow...
all those matrices, and euler angle conversion....
thats too complicated

my approach:

current direction is a vector, desired ending direction is also a vector
to get intermediate positions, I average them, with different weightings depending on how far between each I want to be.
Might also do a distance constraint between the previous and new direction vectors, to cap rotation speed.
Be sure the renormalize each time!

##### Share on other sites
Whats wrong with good old vector to vector interpolation :)

Playerdir = Playerdir + (Enemydir - Playerdir) * Value;

Where 'value' is 0.0 - 1.0.

If you want to include interpolation over time:

Value = Clamp(DeltaTime * Speed);
Playerdir = Playerdir + (Enemydir - Playerdir) * Value;

You probably wanna make a function vec3lerp(vec3 &v1, vec3, &v2, float s) or something for that.

Simple isn't it?

##### Share on other sites
Vector interpolation wouldn't work if you need a smooth rotation (by the way you forgot to normalize the angle).
I would suggest quaternions if you're not that afraid of math. They have a nice slerp ( spherical interpolation ) function.

##### Share on other sites
Quote:
 Original post by smurfkillerWhats 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 ;)

##### Share on other sites
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);

##### Share on other sites
wouldn't cubic spline interpolation work here

##### Share on other sites
Why what would that do and can you give an example on how you would implement it

##### Share on other sites
Quote:
Original post by Motorherp
Quote:
 Original post by smurfkillerWhats 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.

##### Share on other sites
Quote:
 Original post by Prog101Right 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 matrixmat4 EnemyMatInversed;f32 angleToPlayer;//get the inverse of the Enemy matrixMatrix_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.

##### Share on other sites
Quote:
 Original post by Prog101Right 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 matrixmat4 EnemyMatInversed;f32 angleToPlayer;//get the inverse of the Enemy matrixMatrix_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]