Sunday, June 14, 2015

mathematics - How do I find rotation in 3D based on a vector/normal?


I've been playing with Blender and Python, doing basic things like accessing vertices/normals,etc.


I can get the normal of each face of a mesh. I was wondering, how can I get the rotation of a face based on it's normal ? Can I 'decompose' the normal's rotation into rotation x,y,z ? If so how ?


I remember 3dsmax had something that allowed you to easily place objects on another object's faces/surface. Haven't seen that in Blender, might be handy.



Answer



There are a few things to consider here. The first is that a face is not necessarily rotated just because its normal is not aligned with an axis. The second is that you can't obtain Euler angles (x,y,z rotations) from just a normal. You would need to know at least 2 non collinear vectors to do that as you need three perpendicular vectors (a basis in R3) to derive them.


However, I believe you are asking how to find the angles needed to rotate an axis vector so that it is collinear with the normal. This is possible to do with just a normal, and only requires two rotations. You can pick which two axises to rotate from as it doesn't really matter, but for an example I will use rotation about the +Z axis (pointing up) and the +X axis (pointing right).


First we have the normal N = (Xn,Yn,Zn). The best way to think about it is to project the vector onto two of the 2D planes made by the basis vectors. In this case it would be the YZ plane and XY plane. In the YZ plane, the X coordinate of the normal essentially disappears and we are left with a 2D trig problem. Similarly in the XY plane, the Z coordinate of the normal disappears. Just solve for the angle between the axis vector you will be rotating and the projected normal vector.


Be careful of the domains of the inverse trig functions, they do not cover all 360 degrees of rotations uniquely. Also, if the normal is on one of the planes (XY, YZ, XZ) make sure you use that plane in your calculations. Otherwise you will get two angles of 0 which is not useful.


The second part is done by changing the basis for the new object from the basis of the original object to one that has its origin at the point on the face where you clicked, one of the basis vectors as the normal of that face (or a normalized version if the normal is not of length 1), and two other perpendicular vectors. Note that if you wanted to, you could do the calculations from the first part to determine the angle between the up axis in the original basis and the normal, then rotate all three axises of the original basis by those angles to obtain the basis for the new object.



This can also be done using matrix math and would avoid the calculation of trig function values.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...