/* * pQuaternion.java * * (C) 2005, Alex S. */ public class pQuaternion { public double w,x,y,z; private pQuaternion(){ } public pQuaternion(double w,double x,double y,double z){ this.w = w; this.x = x; this.y = y; this.z = z; normalize(); } public pQuaternion(pQuaternion q){ this.w = q.w; this.x = q.x; this.y = q.y; this.z = q.z; } /** * sets this quaternion to length 1 */ public void normalize(){ double len = length(); if(len > 0){ w /= len; x /= len; y /= len; z /= len; } } /** * returns the norm */ public double length(){ return Math.sqrt(w*w+x*x+y*y+z*z); } /** * convert to rotation matrix */ public double[] to3x3matrix(){ double[] m = { 1 - 2*y*y - 2*z*z, 2*x*y - 2*w*z, 2*x*z + 2*w*y, 2*x*y + 2*w*z, 1 - 2*x*x-2*z*z, 2*y*z - 2*w*x, 2*x*z - 2*w*y, 2*y*z + 2*w*x, 1-2*x*x-2*y*y }; return m; } /** * convert to rotation matrix */ public double[] to4x4matrix(){ double[] m = { 1 - 2*y*y - 2*z*z, 2*x*y - 2*w*z, 2*x*z + 2*w*y, 0, 2*x*y + 2*w*z, 1 - 2*x*x-2*z*z, 2*y*z - 2*w*x, 0, 2*x*z - 2*w*y, 2*y*z + 2*w*x, 1-2*x*x-2*y*y, 0, 0, 0, 0, 1 }; return m; } /** * convert to axis/angle form * * Ax, Ay, Az, Theta */ public double[] toAxisAngle(){ double s = x*x + y*y + z*z; double ax = x / s; double ay = y / s; double az = z / s; double theta = 2 * Math.acos(w); double[] aa = {ax,ay,az,theta}; return aa; } /** * get a quaternion from axis and angle. */ public static pQuaternion fromAxisAngle(double ax,double ay,double az,double theta){ double s = Math.sin(theta/2); return new pQuaternion(Math.cos(theta/2),s*ax,s*ay,s*az); } /** * return the inverse */ public pQuaternion conjugate(){ return new pQuaternion(w,-x,-y,-z); } /** * Qr = Q1.Q2 = ( w1.w2 - v1.v2, w1.v2 + w2.v1 + v1 x v2 ) */ public pQuaternion mult(pQuaternion q){ pQuaternion a = new pQuaternion(this); return mult(a,q); } public static pQuaternion mult(pQuaternion A,pQuaternion B){ pQuaternion C = new pQuaternion(); C.x = A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y; C.y = A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x; C.z = A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w; C.w = A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z; return C; } /** * from angles */ public pQuaternion fromEulerAngles(double ax,double ay,double az){ pQuaternion qx,qy,qz,qt; qx = fromAxisAngle(1,0,0,ax); qy = fromAxisAngle(0,1,0,ay); qz = fromAxisAngle(0,0,1,az); return qx.mult(qy).mult(qz); } /** * render the thing */ public String toString(){ return "["+w+",<"+x+","+y+","+z+">]"; } }