public static quaternion operator *(quaternion a, quaternion b) { quaternion r = new quaternion(); r.s = a.s * b.s - (a.v * b.v); r.v = (a.s * b.v) + (a.v * b.s) + (a.v % b.v); return r; }
public vect3d transformPoint(ref vect3d p) { vect3d vecTemp = p; double mag = -(vecTemp * v); vecTemp = ((vecTemp * s) + ((v % vecTemp))); quaternion temp = new quaternion(mag, vecTemp); return (temp * conjugate()).v; }
quaternion slerp(ref quaternion q1, ref quaternion q2, double t) { double[] temp = new double[4]; double omega, cosom, sinom, scale0, scale1; quaternion rvalue; // calc cosine cosom = q1.s * q2.s + q1.v.x * q2.v.x + q1.v.y * q2.v.y + q1.v.z * q2.v.z; // adjust signs (if necessary) if (cosom < 0.0) { cosom = -1.0 * cosom; temp[0] = -1.0 * q2.s; temp[1] = -1.0 * q2.v.x; temp[2] = -1.0 * q2.v.y; temp[3] = -1.0 * q2.v.z; } else { temp[0] = q2.s; temp[1] = q2.v.x; temp[2] = q2.v.y; temp[3] = q2.v.z; } // calculate coefficients if ((1.0 - cosom) > 0.001) { // standard case (slerp) omega = System.Math.Acos(cosom); sinom = System.Math.Sin(omega); scale0 = System.Math.Sin((1.0 - t) * omega) / sinom; scale1 = System.Math.Sin(t * omega) / sinom; } else { // q1 and q2 are about 1 degree apart so use linear // interpolation to avoid division by very small numbers scale0 = 1.0 - t; scale1 = t; } // do the interpolation rvalue.s = scale0 * q1.s + scale1 * temp[0]; rvalue.v.x = scale0 * q1.v.x + scale1 * temp[1]; rvalue.v.y = scale0 * q1.v.y + scale1 * temp[2]; rvalue.v.z = scale0 * q1.v.z + scale1 * temp[3]; return rvalue; }