This topic is now archived and is closed to further replies.


Rotate point around vector

Recommended Posts

Off the top of my head I would say...

Two words: Vector Addition

Add a magnitude that is at the angle you want to achive and equal in magnitude to the existing vector.

Opps... Looking back on this post I forgot something, that you would have to bring back the vector to its original magnitude. Easy enough to figure out, but I can just see someone trying this and not seeing why they get an odd result.

[edited by - thewayout_is_through on November 1, 2002 10:20:50 PM]

Share this post

Link to post
Share on other sites
the order of rotation matters. however, there are ways around it.

people will tell you to use quarternions, but if you cant understand them, there is a solution.

when dt is small the order of rotation doesnt matter!

what I do at the moment is devide the timestep by 128.

Then you can rotate by that tinydt 128 times and the rotation will be accurate.


this method can be improved about by using rotation matrices. see this code for inspiration.

/possible speedup: quarternions?
ident=matrix::RotateMatrix(ident,rot.x,rot.y,rot.z); //1 A
ident=matrix::AmultB(ident,ident); //A^2=AA //2
ident=matrix::AmultB(ident,ident); //A^4=A^2A^2 //4
ident=matrix::AmultB(ident,ident); //A^8=A^4A^4 //16
ident=matrix::AmultB(ident,ident); //A^16=A^8A^8 //256

ident=matrix::AmultB(ident,ident); //A^32=A^16A16
ident=matrix::AmultB(ident,ident); //A^64=A^32A32
ident=matrix::AmultB(ident,ident); //A^128=A^64A64 //this represents a rotation 128
//times larger than that which occured
//over time dt/128
//An accurate alternative to quaternions.


Share this post

Link to post
Share on other sites
Alright, time for the visual aid.

Excuse the 2D nature, but I generally work in 2D more than 3D. The white line represents our existing vector, the red is the vector we add and green is the resulting vector. The magnitude of white matches red and the angle of red to white is twice the end result. However, the resulting magnitude of green must be reduced to that of our original vector white.

edit by ze: Hm. Fixed image, I think.

[edited by - zealouselixir on November 2, 2002 5:46:09 PM]

Share this post

Link to post
Share on other sites
what you''re basically trying to do is rotate around one vector around another.

One vector is you''re axis of rotation - its magnitude equals the angle you want to rotate around.

This vector has components

axis.x axis.y axis.z
(remember |axis|=angle to turn around)

the vector you''re rotating, call it v

well what u would like to do is rotate:

v.x,v.y by angle axis.z
v.z,v.x by angle axis.y
v.z,v.x by angle axis.x

well that wont work because the order which u perform the rotations will affect the final result.

but if we devided axis by say 128 and then perform 128 rotations then the result is accurate(ish).

most people know how to rotate about an axis so if they dont know more precise ways then this is a good way to approximate. U get basically the same answer.


Share this post

Link to post
Share on other sites
kindfluffysteve, I understand what you mean now, but I would like to use something precise. These points make up models, and I dont want them deformed the least bit :-/

If there is a way using quatranions or something, that would be preferred.

Thanks for clearing it up though.

thewayout_is_through, Your image doesnt show up.

If anyone needs any clarification, it is basically 2 vectors. 1 is the axis and the other rotates "a" degrees around the axis.

thewayout_is_through, I see your image now, but that isn't my problem :-/ My explanation sucked.

[edited by - shrooboo on November 1, 2002 12:54:57 AM]

Share this post

Link to post
Share on other sites
my view is that in dynamics simulations things are always approximate.

the approach isnt too bad, the rotation happens over a time small dt - which is then devided by 128

to see the result of this operation check the torque physics demo on my web page.


Share this post

Link to post
Share on other sites
If you''re doing rigid body dynamics where you need to rotate an object, you DO NOT want to rotate the vertices in the models on every frame! Instead you store the orientation matrix for the model. The orientation matrix is:

[ a i x ]
[ b j y ]
[ c k z ]

Then you grab the column vectors (the basis of the coordinate system) by saying u=(a,b,c), v=(i,j,k), w=(x,y,z). Now let''s denote the vector you want to rotate around as r and the timestep by dt. The appropriate equations for the derivatives of u,v and w are:

u'' = r x u
v'' = r x v
w'' = r x w

(Where x denotes a crossproduct). I''m not exactly sure if the signs should be changed (to u x r, v x r and w x r), but anyway, you can check that out later. If you want to use the basic Euler''s method for computing the new basis, you compute:

u_new = u + u'' * dt
v_new = v + v'' * dt
w_new = w + w'' * dt

Then you place these back to the orientation matrix. The column vectors define the bases of the coordinate system - therefore, they should be orthogonal and have magnitude of one. After the modifications to the matrix this rarely is the case (because of the numerical errors). You can use a procedure called Gram-Schmidt orthogonalization to fix the matrix.

The method of using a separate orientation matrix is indeed a powerful and elegant one. When you render (or do collision detection) the models, you use this orientation matrix to find the world-coordinate-system positions of the vertices in the model. The numerical error in the system will only slow down the rotation of the orientation matrix, but this is practically almost neglible.

- Mikko Kauppila

Share this post

Link to post
Share on other sites
I had someone tell me elsewhere to multiply the point into a 3x3 matrix representation of the angle axis, which would return the new rotated point. Is that a good solution?

uutee, If I use my method instead of yours, I will only rotate the individual points when I am doing collision detection, so It wouldn''t technically be every frame. I am going to look into your solution though.

Share this post

Link to post
Share on other sites