private void assertEquals(Quaterniond expected, Quaterniond actual) { // This works because we're only dealing with unit quaternions // See: https://gamedev.stackexchange.com/questions/75072/how-can-i-compare-two-quaternions-for-logical-equality Assert.assertEquals(1, Math.abs(expected.dot(actual)), EPSILON); }
/** * Returns the dot product of this quaternion with another one. * * @param q The quaternion to calculate the dot product with * @return The dot product of the two quaternions */ public double dot(Quaterniond q) { return dot(q.x, q.y, q.z, q.w); }
/** * Returns the dot product of this quaternion with another one. * * @param q The quaternion to calculate the dot product with * @return The dot product of the two quaternions */ public double dot(Quaterniond q) { return dot(q.x, q.y, q.z, q.w); }
/** * Returns the dot product of this quaternion with the float components of another one. * * @param x The x (imaginary) component of the quaternion to calculate the dot product with * @param y The y (imaginary) component of the quaternion to calculate the dot product with * @param z The z (imaginary) component of the quaternion to calculate the dot product with * @param w The w (real) component of the quaternion to calculate the dot product with * @return The dot product of the two quaternions */ public double dot(float x, float y, float z, float w) { return dot((double) x, (double) y, (double) z, (double) w); }
/** * Returns the dot product of this quaternion with the float components of another one. * * @param x The x (imaginary) component of the quaternion to calculate the dot product with * @param y The y (imaginary) component of the quaternion to calculate the dot product with * @param z The z (imaginary) component of the quaternion to calculate the dot product with * @param w The w (real) component of the quaternion to calculate the dot product with * @return The dot product of the two quaternions */ public double dot(float x, float y, float z, float w) { return dot((double) x, (double) y, (double) z, (double) w); }
/** * Interpolates a quaternion between two others using spherical linear interpolation. * * @param a The first quaternion * @param b The second quaternion * @param percent The percent for the interpolation, between 0 and 1 inclusively * @return The interpolated quaternion */ public static Quaterniond slerp(Quaterniond a, Quaterniond b, double percent) { final double inverted; double cosineTheta = a.dot(b); if (cosineTheta < 0) { cosineTheta = -cosineTheta; inverted = -1; } else { inverted = 1; } if (1 - cosineTheta < GenericMath.DBL_EPSILON) { return a.mul(1 - percent).add(b.mul(percent * inverted)); } final double theta = (double) TrigMath.acos(cosineTheta); final double sineTheta = TrigMath.sin(theta); final double coefficient1 = TrigMath.sin((1 - percent) * theta) / sineTheta; final double coefficient2 = TrigMath.sin(percent * theta) / sineTheta * inverted; return a.mul(coefficient1).add(b.mul(coefficient2)); }
/** * Interpolates a quaternion between two others using spherical linear interpolation. * * @param a The first quaternion * @param b The second quaternion * @param percent The percent for the interpolation, between 0 and 1 inclusively * @return The interpolated quaternion */ public static Quaterniond slerp(Quaterniond a, Quaterniond b, double percent) { final double inverted; double cosineTheta = a.dot(b); if (cosineTheta < 0) { cosineTheta = -cosineTheta; inverted = -1; } else { inverted = 1; } if (1 - cosineTheta < GenericMath.DBL_EPSILON) { return a.mul(1 - percent).add(b.mul(percent * inverted)); } final double theta = (double) TrigMath.acos(cosineTheta); final double sineTheta = TrigMath.sin(theta); final double coefficient1 = TrigMath.sin((1 - percent) * theta) / sineTheta; final double coefficient2 = TrigMath.sin(percent * theta) / sineTheta * inverted; return a.mul(coefficient1).add(b.mul(coefficient2)); }