//package Applet3D; public class cQuat implements java.io.Serializable { static final long serialVersionUID = -4375060109944420639L; public cQuat(double d, double d1, double d2, double d3) { double d4 = 1.0D / Math.sqrt(d * d + d1 * d1 + d2 * d2 + d3 * d3); x = d * d4; y = d1 * d4; z = d2 * d4; w = d3 * d4; } public cQuat(double ad[]) { double d = 1.0D / Math.sqrt(ad[0] * ad[0] + ad[1] * ad[1] + ad[2] * ad[2] + ad[3] * ad[3]); x = ad[0] * d; y = ad[1] * d; z = ad[2] * d; w = ad[3] * d; } public cQuat(cQuat quat) { x = quat.x; y = quat.y; z = quat.z; w = quat.w; } public cQuat() { } public cQuat(cVector axe, double angle) { set(axe, angle); } public cQuat(cVector pA, cVector pB) { setRotation(pA, pB); } public void setRotation(cVector pA, cVector pB) { if (pA == null || pB == null) { x = y = z = 0.0D; w = 1.0D; return; } cVector lA = new cVector(pA); cVector lB = new cVector(pB); if (lA.length() > 0) lA.normalize(); if (lB.length() > 0) lB.normalize(); double lDot = lA.dot(lB); cVector lCP = new cVector(); lCP.cross(lA, lB); if (lCP.length() > 0) lCP.normalize(); else if (lDot < 0.0D) { lCP.cross(lA, cVector.Y); if (lCP.length() > 0) { lCP.normalize(); } else { lCP.cross(lA, cVector.X); lCP.normalize(); } } double lTmp = (lDot + 1.0D) / 2D; double lCos = Math.sqrt(lTmp); double lSin = Math.sqrt(1.0D - lTmp); x = (double)lCP.x * lSin; y = (double)lCP.y * lSin; z = (double)lCP.z * lSin; w = lCos; } public void set(cVector axe, double angle) { double s = Math.sin(angle/2); double c = Math.cos(angle/2); axe.normalize(); x = axe.x * s; y = axe.y * s; z = axe.z * s; w = c; } public void conjugate(cQuat quat) { x = -quat.x; y = -quat.y; z = -quat.z; w = quat.w; } public void conjugate() { x = -x; y = -y; z = -z; } public void mul(cQuat quat, cQuat quat1) { if (this != quat && this != quat1) { w = quat.w * quat1.w - quat.x * quat1.x - quat.y * quat1.y - quat.z * quat1.z; x = (quat.w * quat1.x + quat1.w * quat.x + quat.y * quat1.z) - quat.z * quat1.y; y = ((quat.w * quat1.y + quat1.w * quat.y) - quat.x * quat1.z) + quat.z * quat1.x; z = (quat.w * quat1.z + quat1.w * quat.z + quat.x * quat1.y) - quat.y * quat1.x; } else { double d2 = quat.w * quat1.w - quat.x * quat1.x - quat.y * quat1.y - quat.z * quat1.z; double d = (quat.w * quat1.x + quat1.w * quat.x + quat.y * quat1.z) - quat.z * quat1.y; double d1 = ((quat.w * quat1.y + quat1.w * quat.y) - quat.x * quat1.z) + quat.z * quat1.x; z = (quat.w * quat1.z + quat1.w * quat.z + quat.x * quat1.y) - quat.y * quat1.x; w = d2; x = d; y = d1; } } public void mul(cQuat quat) { double d2 = w * quat.w - x * quat.x - y * quat.y - z * quat.z; double d = (w * quat.x + quat.w * x + y * quat.z) - z * quat.y; double d1 = ((w * quat.y + quat.w * y) - x * quat.z) + z * quat.x; z = (w * quat.z + quat.w * z + x * quat.y) - y * quat.x; w = d2; x = d; y = d1; } public void rotate(cVector p) { double m00 = w*w + x*x - y*y - z*z; double m01 = 2*(x*y - w*z); double m02 = 2*(w*y + x*z); double m10 = 2*(w*z + x*y); double m11 = w*w - x*x + y*y - z*z; double m12 = 2*(y*z - w*x); double m20 = 2*(x*z - w*y); double m21 = 2*(w*x + y*z); double m22 = w*w - x*x - y*y + z*z; double fx = p.x*m00 + p.y*m01 + p.z*m02; double fy = p.x*m10 + p.y*m11 + p.z*m12; double fz = p.x*m20 + p.y*m21 + p.z*m22; /* double tx = p.x*x; double ty = p.y*x; double tz = p.z*x; double fx = x*tx + y*ty + z*tz; tx = p.x*y; ty = p.y*y; tz = p.z*y; double fy = x*tx + y*ty + z*tz; tx = p.x*z; ty = p.y*z; tz = p.z*z; double fz = x*tx + y*ty + z*tz; */ p.x = (double)fx; p.y = (double)fy; p.z = (double)fz; } public void mulInverse(cQuat quat, cQuat quat1) { cQuat quat2 = new cQuat(quat1); quat2.inverse(); mul(quat, quat2); } public void mulInverse(cQuat quat) { cQuat quat1 = new cQuat(quat); quat1.inverse(); mul(quat1); } public void inverse(cQuat quat) { double d = 1.0D / (quat.w * quat.w + quat.x * quat.x + quat.y * quat.y + quat.z * quat.z); w = d * quat.w; x = -d * quat.x; y = -d * quat.y; z = -d * quat.z; } public void inverse() { double d = 1.0D / (w * w + x * x + y * y + z * z); w *= d; x *= -d; y *= -d; z *= -d; } public void normalize(cQuat quat) { double d = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w; if (d > 0.0D) { d = 1.0D / Math.sqrt(d); x = d * quat.x; y = d * quat.y; z = d * quat.z; w = d * quat.w; } else { x = 0.0D; y = 0.0D; z = 0.0D; w = 0.0D; } } public void normalize() { double d = x * x + y * y + z * z + w * w; if (d > 0.0D) { d = 1.0D / Math.sqrt(d); x *= d; y *= d; z *= d; w *= d; } else { x = 0.0D; y = 0.0D; z = 0.0D; w = 0.0D; } } /* public final void set(Matrix4f matrix4f) { double d = 0.25D * (double)(matrix4f.m00 + matrix4f.m11 + matrix4f.m22 + matrix4f.m33); if (d >= 0.0D) { if (d >= 1.0000000000000001E-30D) { w = Math.sqrt(d); d = 0.25D / w; x = (double)(matrix4f.m21 - matrix4f.m12) * d; y = (double)(matrix4f.m02 - matrix4f.m20) * d; z = (double)(matrix4f.m10 - matrix4f.m01) * d; return; } } else { w = 0.0D; x = 0.0D; y = 0.0D; z = 1.0D; return; } w = 0.0D; d = -0.5D * (double)(matrix4f.m11 + matrix4f.m22); if (d >= 0.0D) { if (d >= 1.0000000000000001E-30D) { x = Math.sqrt(d); d = 1.0D / (2D * x); y = (double)matrix4f.m10 * d; z = (double)matrix4f.m20 * d; return; } } else { x = 0.0D; y = 0.0D; z = 1.0D; return; } x = 0.0D; d = 0.5D * (1.0D - (double)matrix4f.m22); if (d >= 1.0000000000000001E-30D) { y = Math.sqrt(d); z = (double)matrix4f.m21 / (2D * y); return; } else { y = 0.0D; z = 1.0D; return; } } public final void set(Matrix4d matrix4d) { double d = 0.25D * (matrix4d.m00 + matrix4d.m11 + matrix4d.m22 + matrix4d.m33); if (d >= 0.0D) { if (d >= 1.0000000000000001E-30D) { w = Math.sqrt(d); d = 0.25D / w; x = (matrix4d.m21 - matrix4d.m12) * d; y = (matrix4d.m02 - matrix4d.m20) * d; z = (matrix4d.m10 - matrix4d.m01) * d; return; } } else { w = 0.0D; x = 0.0D; y = 0.0D; z = 1.0D; return; } w = 0.0D; d = -0.5D * (matrix4d.m11 + matrix4d.m22); if (d >= 0.0D) { if (d >= 1.0000000000000001E-30D) { x = Math.sqrt(d); d = 0.5D / x; y = matrix4d.m10 * d; z = matrix4d.m20 * d; return; } } else { x = 0.0D; y = 0.0D; z = 1.0D; return; } x = 0.0D; d = 0.5D * (1.0D - matrix4d.m22); if (d >= 1.0000000000000001E-30D) { y = Math.sqrt(d); z = matrix4d.m21 / (2D * y); return; } else { y = 0.0D; z = 1.0D; return; } } public final void set(Matrix3f matrix3f) { double d = 0.25D * ((double)(matrix3f.m00 + matrix3f.m11 + matrix3f.m22) + 1.0D); if (d >= 0.0D) { if (d >= 1.0000000000000001E-30D) { w = Math.sqrt(d); d = 0.25D / w; x = (double)(matrix3f.m21 - matrix3f.m12) * d; y = (double)(matrix3f.m02 - matrix3f.m20) * d; z = (double)(matrix3f.m10 - matrix3f.m01) * d; return; } } else { w = 0.0D; x = 0.0D; y = 0.0D; z = 1.0D; return; } w = 0.0D; d = -0.5D * (double)(matrix3f.m11 + matrix3f.m22); if (d >= 0.0D) { if (d >= 1.0000000000000001E-30D) { x = Math.sqrt(d); d = 0.5D / x; y = (double)matrix3f.m10 * d; z = (double)matrix3f.m20 * d; return; } } else { x = 0.0D; y = 0.0D; z = 1.0D; return; } x = 0.0D; d = 0.5D * (1.0D - (double)matrix3f.m22); if (d >= 1.0000000000000001E-30D) { y = Math.sqrt(d); z = (double)matrix3f.m21 / (2D * y); } y = 0.0D; z = 1.0D; } public final void set(Matrix3d matrix3d) { double d = 0.25D * (matrix3d.m00 + matrix3d.m11 + matrix3d.m22 + 1.0D); if (d >= 0.0D) { if (d >= 1.0000000000000001E-30D) { w = Math.sqrt(d); d = 0.25D / w; x = (matrix3d.m21 - matrix3d.m12) * d; y = (matrix3d.m02 - matrix3d.m20) * d; z = (matrix3d.m10 - matrix3d.m01) * d; return; } } else { w = 0.0D; x = 0.0D; y = 0.0D; z = 1.0D; return; } w = 0.0D; d = -0.5D * (matrix3d.m11 + matrix3d.m22); if (d >= 0.0D) { if (d >= 1.0000000000000001E-30D) { x = Math.sqrt(d); d = 0.5D / x; y = matrix3d.m10 * d; z = matrix3d.m20 * d; return; } } else { x = 0.0D; y = 0.0D; z = 1.0D; return; } x = 0.0D; d = 0.5D * (1.0D - matrix3d.m22); if (d >= 1.0000000000000001E-30D) { y = Math.sqrt(d); z = matrix3d.m21 / (2D * y); return; } else { y = 0.0D; z = 1.0D; return; } } public final void set(AxisAngle4f axisangle4f) { double d1 = Math.sqrt(axisangle4f.x * axisangle4f.x + axisangle4f.y * axisangle4f.y + axisangle4f.z * axisangle4f.z); if (d1 < 9.9999999999999995E-07D) { w = 0.0D; x = 0.0D; y = 0.0D; z = 0.0D; } else { double d = Math.sin((double)axisangle4f.angle / 2D); d1 = 1.0D / d1; w = Math.cos((double)axisangle4f.angle / 2D); x = (double)axisangle4f.x * d1 * d; y = (double)axisangle4f.y * d1 * d; z = (double)axisangle4f.z * d1 * d; } } public final void set(AxisAngle4d axisangle4d) { double d1 = Math.sqrt(axisangle4d.x * axisangle4d.x + axisangle4d.y * axisangle4d.y + axisangle4d.z * axisangle4d.z); if (d1 < 9.9999999999999995E-07D) { w = 0.0D; x = 0.0D; y = 0.0D; z = 0.0D; } else { d1 = 1.0D / d1; double d = Math.sin(axisangle4d.angle / 2D); w = Math.cos(axisangle4d.angle / 2D); x = axisangle4d.x * d1 * d; y = axisangle4d.y * d1 * d; z = axisangle4d.z * d1 * d; } } */ public void interpolate(cQuat quat, double d) { double d1 = x * quat.x + y * quat.y + z * quat.z + w * quat.w; if (d1 < 0.0D) { quat.x = -quat.x; quat.y = -quat.y; quat.z = -quat.z; quat.w = -quat.w; } double d2; double d3; if (1.0D - Math.abs(d1) > 9.9999999999999995E-07D) { double d4 = Math.acos(d1); double d5 = Math.sin(d4); d2 = Math.sin((1.0D - d) * d4) / d5; d3 = Math.sin(d * d4) / d5; } else { d2 = 1.0D - d; d3 = d; } w = d2 * w + d3 * quat.w; x = d2 * x + d3 * quat.x; y = d2 * y + d3 * quat.y; z = d2 * z + d3 * quat.z; } public void interpolate(cQuat quat, cQuat quat1, double d) { double d1 = quat1.x * quat.x + quat1.y * quat.y + quat1.z * quat.z + quat1.w * quat.w; if (d1 < 0.0D) { quat.x = -quat.x; quat.y = -quat.y; quat.z = -quat.z; quat.w = -quat.w; } double d2; double d3; if (1.0D - Math.abs(d1) > 9.9999999999999995E-07D) { double d4 = Math.acos(d1); double d5 = Math.sin(d4); d2 = Math.sin((1.0D - d) * d4) / d5; d3 = Math.sin(d * d4) / d5; } else { d2 = 1.0D - d; d3 = d; } w = d2 * quat.w + d3 * quat1.w; x = d2 * quat.x + d3 * quat1.x; y = d2 * quat.y + d3 * quat1.y; z = d2 * quat.z + d3 * quat1.z; } //static final long serialVersionUID = 0x69289dcfL; //static final double EPS = 9.9999999999999995E-07D; //static final double EPS2 = 1.0000000000000001E-30D; //static final double PIO2 = 1.57079632679D; double x,y,z,w; }