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
iTime - how would this look? Does anyone know simple algorithm?
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It only takes a minute to sign up.Sign up to join this community
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:
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 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:
Of course we also need the position the vector is currently in:
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:
Let’s describe the second method.
You need to have a method that takes:
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.
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:
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).
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:
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.