Angle between two 3D vectors in 3D rotated by a quaternion -


i have 3d unit quaternion = {w,x,y,z} coming sensor device. want amount of angles(ax,ay,az) x, y , z axes ( angles should independent, 1 should not change when other changes). have come across, quaternion euler angle conversion, have gimbal lock problem & dependents. i'm thinking take different approach.

take 3d vectors x = [1,0,0], y = [0,1,0] , z = [0,0,1]. if rotate these vectors x, y , z quaternion, 3 vectors xx, yy , zz. calculate angle between x, xx vectors. angle between y, yy , z, zz. seems not working. following c# code i've written. angle range should -180 180 or 0 360deg. acos not preferred has precision problems.

how done ? there standard approaches ? how decompose 3d quaternion 3 quaternions individual x, y , z axes ?

vector3d rotvecx = quatvecrotation(quaternion, new vector3d(1,0,0)); vector3d rotvecy = quatvecrotation(quaternion, new vector3d(0,1,0)); vector3d rotvecz = quatvecrotation(quaternion, new vector3d(0,0,1));                 float ax = (float)getxangle(new vector3d(1, 0, 0), rotvec1); float ay = (float)getyangle(new vector3d(0, 1, 0), rotvec2); float az = (float)getzangle(new vector3d(0, 0, 1), rotvec3);  

vector3d quatvecrotation(quaternion quat, vector3d vec)     {                     quaternion qvec = new quaternion(0,vec.x,vec.y,vec.z);                       quaternion qvecr = quaternion.multiply(quat, qvec);         quaternion qinv = new quaternion( quat.w, -quat.x, -quat.y, -quat.z); // conjugate or inverse         quaternion qr = quaternion.multiply(qvecr, qinv);         vector3d resultvec = new vector3d(qr.x, qr.y, qr.z);         resultvec.normalize();         return resultvec;     }     public double getxangle(vector3d vec1, vector3d vec2)     {                     vector3d axis = vector3d.crossproduct(vec1, vec2);         double angle = rad2deg((float)math.atan2(axis.length, vector3d.dotproduct(vec1, vec2)));                     double dir = vector3d.dotproduct(vector3d.crossproduct(axis, vec1), new vector3d(0, 1, 1));         if(dir<0)             angle = angle * math.sign(dir);                     return angle;     } 

use dot product:

x·xx = |x||xx|cos(angle)

so:

angle = acos( x·xx / ( |x||xx| ) )


Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

rewrite - Trouble with Wordpress multiple custom querystrings -

php - Accessing static methods using newly created $obj or using class Name -