How to rotate to a target position over time

I know how to do rotations to vectors, but how do I rotate over time?

For instance say I made a function

RotateTo(vec2 iPosition, float iTime);

so it rotates to iPosition over iTime - how would this look? Does anyone know simple algorithm?

• What do you mean by "it rotates to iPosition"? Rotates from where? Around which point? – Laurent Couvidou Dec 3 '12 at 15:21

If you’re in 3D space it really depends on the axis on which you want to rotate. There are indefinite numbers of possibilities when you do not tell your function where it should rotate. With the current function signature there seem to be two possibilities:

• you rotate in 2D space
• you always want to rotate over the smallest distance

I can only give you a theoretical overview of how rotation can be done. As it seems real game programming uses other methods (see other answers and the comment below my text). However, I guess it still good to know as it is a first principle of rotating.

Rotation over time

Rotation over time is simply a partial rotation each time step. You have to find out about which timespan you want to rotate and which time has elapsed since the last rotation performed. This will require at least 3 variables:

• rotation timespan
• elapsed time since last partial rotation
• angle to rotate

Of course we also need the position the vector is currently in:

• vector position

There are now two possibilities I currently see (when using rotation matrices). As I learned, quaternions would be better, because they do not suffer from that much error when doing many small rotations. Yet I think, there also is a method to minimize that with matrices.

There are different ways to go now. The ones I see:

• really use the time since last rotation and rotate n times by angle/n degree
• remember the time elapsed since you started and the starting position and do the rotation from there. This will eradicate error, as the final position will be like one rotation from the original position.

Let’s describe the second method.

You need to have a method that takes:

• original vector position
• target angle
• timespan to rotate
• elapsed time since rotation start

Then you can simply rotate by the following formula:

function rotateOverTime(vector, angle, timespan, elapsedTimeSinceStart):
partialAngle = elapsedTimeSinceStart / timespan * angle;
rotateZ(vector, partialAngle);

Note that with this method vector will always be the original vector (not taking into consideration the partial rotations) and elapsedTimeSinceStart is the since since the beginning of all your rotations.

The other method is to use the new vector position and onl the time since last rotation, but then you would accumulate error from small rotations and the rotation would not be a nice circle anymore.

Rotation in 2D space

If you want a rotation in 2D space, you actually rotate around the z-axis (because you draw on x- and y-axis). In case your library has a RotateZ function implemented, you can use this. Otherwise, you can use sin and cos.

I do not know it in detail, but it should work something similar to this. Possible that it’s not the fastest and most elegant solution:

• Calculate the current angle of the vector. This can be done with atan2()
• The point around which you want to rotate is usually not (0,0), so you have to move your stuff so that it seems like that was the case (if the rotation center is e.g. (10,10) you have to subtract 10,10 from the point which shall be rotated)
• Multiply the new point (=vector; I will use both later, because in algebra you always talk about vectors) with a rotation matrix. I will show in more detail later what this is.
• Remove your point to the old location by adding the amount you have subtracted before (here 10).

I hope these images make my math talk a bit clearer ;)

We want to rotate the point (5,5) around (1,2) like the green circle indicates. But with matrices we would rotate around (0,0) as the purple circle shows. To solve it, we move our point a bit left-down, then we can rotate it around (0,0) and then we move it back again. This moving-around is called translation. Actually my image sucks a bit here, the purple arrow which is going upwards should be the same diagonal as the first purple arrow. Remember, we move our point (-1,-2) down at first and then (1,2) up again. So my arrows are not that well. I talked about rotation matrix. A rotation matrix is a matrix which you can multiply with your vector to achieve a rotation around the origin (0,0).

cos a     -sin a
sin a      cos a

Where a is the desired angle you want to rotate. This angle is determined by the number of frames you have like Philip has already shown. E.g. if you want it to be rotated in 2 seconds by 90° and 1 second has passed since then, you would rotate it by 1/2 of the total rotation (=45°).

In this case your rotation matrix would look like this:

cos 45°     -sin 45°
sin 45°      cos 45°

Given this matrix, you can multiply it with your current vector to rotate it.

Let’s imagine your vector is (5, 7). This would give you (-1.414, 8.485) which is a rotation by 45° counterclockwise.

In case you need a rotation clockwise, you can just adjust the rotation matrix. Either by subtracting your rotation from 360 (e.g. 15° clockwise is 365° counter clockwise) or by using trgonometrical rules.

Let me mention that this always rotates around the origin. Usually you do not want to rotate around the origin in games, because the origin is some random point. In 2D programming it’s often the top-left point of either the whole world or the current viewport (camera). Higher level abstractions within your library usually use the image’s origin (top-left position), but that’s also not what’s often desired.

What can we do against this? The magic keyword here is translation and it means moving an object around. When rotating you have to make sure to move your object to a desired place for rotation, later you can move it back.

Imagine you have a point in 2D at (200, 300) world coordinates. Now you want to rotate it around (250, 250) by 50°. If you would just multiply (200, 300) with the rotation matrix (where you would set a = 50°), the point would be totally of the screen. Instead, move your point so that (250,250) equals (0,0). We would get our current point (200-250, 300-250) = (-50, 50). Now you can rotate this one! After the rotation you move your new point back again (+250).

Rotation in 3D space

In 3D space you can rotate around an indefinite number of axises to reach one point from a given other point. However, the rotation will not always be the shortest. It can require some time to understand this, but just use your left and your right index finger as points in space. Now you can either make a turn upwards, a turn downwards, a turn frontwards, …

Thus we always need to know around which axis to turn when we are in 3D. Generally, you have the base rotations around X, Y and Z axis. Remember we used Z axis for 2D.

Maybe you remember I mentioned something about the shortest distance from the top. Actually, I am not totally sure if this is right, but I think I remember something from my linear algebra classes. According to what I think now, there should always be a shortest distance when rotating in 3D. Only when both vectors are not independant there is again an indefinite number of shortest distances, but let’s forget about this for now.

So if you do not have an axis to circle around, but want to determine one, you could go like this:

• Calculate the cross product of both vectors (points) => the result is a vector which is independant from both other vectors.
• Rotate around the newly vector as axis. This will give you the shortest rotation distance.
• Measure the angle between the two vectors (around the calculated axis). Can’t tell you at the moment how this could be done, but it’s not a hard compuation, you just have to know how ^_^
• Normalize this vector (length = 1)
• Move your whole scene so that the point around which you want to rotate is the origin (0,0,0)
• Use a formula for rotation around axis and angle in 3D
• Remove your (rotated) scene back to the former position

Hope I could somehow help you, because it seems pretty difficult to me, but I wanted to explain in detail how rotating works.

Let's say you wanted it to spin 360 degrees in one second.

Let's also say that iTime determines how many seconds since the function was called. So if iTime was .01 then 1/100 of a second had passed since the last time the function was called.

Then you would use iTime / 360 to figure out how much rotation you'd need to apply.

As noted by others, you really don't have enough information there to do what you want. You need an axis to rotate around, a starting angle, and an ending angle.

However, given all of that, what you want to look up is slerp. Most APIs and engines will provide the calls you need to implement and construct what you're trying to achieve, but you haven't given enough information in your question to point you at any specific resources.