PDA

Click to See Complete Forum and Search --> : [RESOLVED] 3D rotation


Atheist
Dec 22nd, 2010, 08:08 AM
So I am facing this problem that I KNOW I have faced before...the solution can probably be found somewhere in a couple of my old projects.

I have a unit vector that describes a direction.
I have an object that needs to be rotated accordingly. When no rotation is applied, the object points straight down (0, -1, 0).

So, as an example, if this direction vector is (0, 1, 0), the object could be rotated 180 degrees on the X or Z axis in order to point in the diretion of the vector.

I'm looking for the best way retrieve the radians to rotate the object to point in the direction of said unit vector.
If there are plenty ways to skin this cat, I'd really like the most "efficient" way to calculate this.

jemidiah
Dec 22nd, 2010, 09:49 AM
There are several solutions, depending on precisely what you want and have.


If you have a start and end direction vector, the easiest solution is a linear interpolation between the two--no angles or trig required. That might be problematic since a linear interpolation of the direction vectors is a nonlinear interpolation when the intermediate vectors are projected back onto the unit sphere by normalizing. This can be overcome with a little bit of calculus and trig. Another problem is that your intermediate vectors may sometimes be the 0 vector, which generally isn't a valid direction.
If you just want the angle between two vectors, the dot product formula is easiest. I explained it in this post (http://www.vbforums.com/showpost.php?p=3687774&postcount=4).
If you have an axis-angle rotation routine (like the one I described in this thread (http://www.vbforums.com/showthread.php?t=584390), using quaternions) you can generate the relevant axis by taking the cross product of your input vectors and calculating the angle using (2). There are degenerate cases like your example when a unique rotation isn't determined, which corresponds to the cross product being the 0 vector. These need to be special-cased; one technique that comes to mind is converting to spherical, where the special cases are all simple.


(1) is quite elegant if you don't mind a nonlinear rotation. (3) is quite powerful but complicated if you don't already have an axis-angle rotation routine. (2) answers "the best way retrieve the radians to rotate the object", which might not have said precisely what you meant it to say.

Atheist
Dec 22nd, 2010, 12:34 PM
Thanks for your reply jemidiah.

I am actually very proud of myself right now. I figured out the solution you mention as #3 before reading your response. It looks like this at the moment:

Vector3 axis = Vector3.Cross(this.direction, Vector3.Up);
axis.Normalize();
float dot = Vector3.Dot(this.direction, Vector3.Up);

this.world = Matrix.CreateScale(new Vector3(triangleBase, length, triangleBase)) *
Matrix.CreateFromAxisAngle(axis, -(float)Math.Acos(dot)) * Matrix.CreateTranslation(this.position);

Thank you very much for your help!

Milk
Dec 22nd, 2010, 06:08 PM
apparently I must spread before I can rep you again Jed but excellent post

Atheist
Dec 23rd, 2010, 07:58 AM
apparently I must spread before I can rep you again Jed but excellent post

Same here unfortunately :(

zaza
Dec 31st, 2010, 06:51 AM
BTW, there's a link in my sig to my old Coordinates, Vectors and 3D Volumes project, which has got a maths library and some functions to do a load of this stuff, if you're interested.....

Atheist
Dec 31st, 2010, 07:34 AM
Thanks zaza, I'll definitely check it out!