public static Quaternion times(Quaternion result, Quaternion a, Quaternion b) { result.w = (a.w * b.w) - (a.x * b.x) - (a.y * b.y) - (a.z * b.z); result.x = (a.w * b.x) + (a.x * b.w) + (a.y * b.z) - (a.z * b.y); result.y = (a.w * b.y) - (a.x * b.z) + (a.y * b.w) + (a.z * b.x); result.z = (a.w * b.z) + (a.x * b.y) - (a.y * b.x) + (a.z * b.w); return result; }
/** * http://ogre.sourcearchive.com/documentation/1.4.5/classOgre_1_1Vector3_eeef4472ad0c4d5f34a038a9f2faa819.html#eeef4472ad0c4d5f34a038a9f2faa819 * * @param direction * @return */ public Quaternion getRotationTo(Number3D direction) { // Based on Stan Melax's article in Game Programming Gems Quaternion q = new Quaternion(); // Copy, since cannot modify local Number3D v0 = this; Number3D v1 = direction; v0.normalize(); v1.normalize(); float d = Number3D.dot(v0, v1); // If dot == 1, vectors are the same if (d >= 1.0f) { q.setIdentity(); } if (d < 0.000001f - 1.0f) { // Generate an axis Number3D axis = Number3D.cross(Number3D.getAxisVector(Axis.X), this); if (axis.length() == 0) // pick another if colinear axis = Number3D.cross(Number3D.getAxisVector(Axis.Y), this); axis.normalize(); q.fromAngleAxis(MathUtil.radiansToDegrees(MathUtil.PI), axis); } else { float s = FloatMath.sqrt((1 + d) * 2); float invs = 1f / s; Number3D c = Number3D.cross(v0, v1); q.x = c.x * invs; q.y = c.y * invs; q.z = c.z * invs; q.w = s * 0.5f; q.normalize(); } return q; }
public static Quaternion makeRotation(Quaternion result, float theta, Vector axis) { float halfTheta = theta / 2; float sinHalfTheta = GMath.sin(halfTheta); result.w = GMath.cos(halfTheta); result.x = axis.getX() * sinHalfTheta; result.y = axis.getY() * sinHalfTheta; result.z = axis.getZ() * sinHalfTheta; return result; }