/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.geometry.euclidean.threed.rotation;

import java.util.Objects;

import org.apache.commons.geometry.core.internal.GeometryInternalError;
import org.apache.commons.geometry.euclidean.internal.Vectors;
import org.apache.commons.geometry.euclidean.threed.AffineTransformMatrix3D;
import org.apache.commons.geometry.euclidean.threed.Vector3D;
import org.apache.commons.numbers.angle.PlaneAngleRadians;
import org.apache.commons.numbers.arrays.LinearCombination;
import org.apache.commons.numbers.quaternion.Quaternion;
import org.apache.commons.numbers.quaternion.Slerp;

/**
 * Class using a unit-length quaternion to represent
 * <a href="https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation">rotations</a>
 * in 3-dimensional Euclidean space.
 * The underlying quaternion is in <em>positive polar form</em>: It is normalized and has a
 * non-negative scalar component ({@code w}).
 *
 * @see Quaternion
 */
public final class QuaternionRotation implements Rotation3D {
    /** Threshold value for the dot product of antiparallel vectors. If the dot product of two vectors is
     * less than this value, (adjusted for the lengths of the vectors), then the vectors are considered to be
     * antiparallel (ie, negations of each other).
     */
    private static final double ANTIPARALLEL_DOT_THRESHOLD = 2.0e-15 - 1.0;

    /** Threshold value used to identify singularities when converting from quaternions to
     * axis angle sequences.
     */
    private static final double AXIS_ANGLE_SINGULARITY_THRESHOLD = 0.9999999999;

    /** Instance used to represent the identity rotation, ie a rotation with
     * an angle of zero.
     */
    private static final QuaternionRotation IDENTITY_INSTANCE = of(Quaternion.ONE);

    /** Unit-length quaternion instance in positive polar form. */
    private final Quaternion quat;

    /** Simple constructor. The given quaternion is converted to positive polar form.
     * @param quat quaternion instance
     * @throws IllegalStateException if the the norm of the given components is zero,
     *                              NaN, or infinite
     */
    private QuaternionRotation(final Quaternion quat) {
        this.quat = quat.positivePolarForm();
    }

    /** Get the underlying quaternion instance.
     * @return the quaternion instance
     */
    public Quaternion getQuaternion() {
        return quat;
    }

    /**
     * Get the axis of rotation as a normalized {@link Vector3D}. The rotation axis
     * is not well defined when the rotation is the identity rotation, ie it has a
     * rotation angle of zero. In this case, the vector representing the positive
     * x-axis is returned.
     *
     * @return the axis of rotation
     */
    @Override
    public Vector3D getAxis() {
        final Vector3D axis = Vectors.tryNormalize(Vector3D.of(quat.getX(), quat.getY(), quat.getZ()));
        return (axis != null) ?
                axis :
                Vector3D.Unit.PLUS_X;
    }

    /**
     * Get the angle of rotation in radians. The returned value is in the range 0
     * through {@code pi}.
     *
     * @return The rotation angle in the range {@code [0, pi]}.
     */
    @Override
    public double getAngle() {
        return 2 * Math.acos(quat.getW());
    }

    /**
     * Get the inverse of this rotation. The returned rotation has the same
     * rotation angle but the opposite rotation axis. If {@code r.apply(u)}
     * is equal to {@code v}, then {@code r.negate().apply(v)} is equal
     * to {@code u}.
     *
     * @return the negation (inverse) of the rotation
     */
    @Override
    public QuaternionRotation inverse() {
        return new QuaternionRotation(quat.conjugate());
    }

    /**
     * Apply this rotation to the given vector.
     *
     * @param v vector to rotate
     * @return the rotated vector
     */
    @Override
    public Vector3D apply(final Vector3D v) {
        final double qw = quat.getW();
        final double qx = quat.getX();
        final double qy = quat.getY();
        final double qz = quat.getZ();

        final double x = v.getX();
        final double y = v.getY();
        final double z = v.getZ();

        // calculate the Hamilton product of the quaternion and vector
        final double iw = -(qx * x) - (qy * y) - (qz * z);
        final double ix = (qw * x) + (qy * z) - (qz * y);
        final double iy = (qw * y) + (qz * x) - (qx * z);
        final double iz = (qw * z) + (qx * y) - (qy * x);

        // calculate the Hamilton product of the intermediate vector and
        // the inverse quaternion

        return Vector3D.of(
                    (iw * -qx) + (ix * qw) + (iy * -qz) - (iz * -qy),
                    (iw * -qy) - (ix * -qz) + (iy * qw) + (iz * -qx),
                    (iw * -qz) + (ix * -qy) - (iy * -qx) + (iz * qw)
                );
    }

    /** {@inheritDoc}
     *
     * <p>This method simply calls {@code apply(vec)} since rotations treat
     * points and vectors similarly.</p>
     */
    @Override
    public Vector3D applyVector(final Vector3D vec) {
        return apply(vec);
    }

    /** {@inheritDoc}
     *
     * <p>This method simply returns true since rotations always preserve the orientation
     * of the space.</p>
     */
    @Override
    public boolean preservesOrientation() {
        return true;
    }

    /** {@inheritDoc} */
    @Override
    public AffineTransformMatrix3D toMatrix() {

        final double qw = quat.getW();
        final double qx = quat.getX();
        final double qy = quat.getY();
        final double qz = quat.getZ();

        // pre-calculate products that we'll need
        final double xx = qx * qx;
        final double xy = qx * qy;
        final double xz = qx * qz;
        final double xw = qx * qw;

        final double yy = qy * qy;
        final double yz = qy * qz;
        final double yw = qy * qw;

        final double zz = qz * qz;
        final double zw = qz * qw;

        final double m00 = 1.0 - (2.0 * (yy + zz));
        final double m01 = 2.0 * (xy - zw);
        final double m02 = 2.0 * (xz + yw);
        final double m03 = 0.0;

        final double m10 = 2.0 * (xy + zw);
        final double m11 = 1.0 - (2.0 * (xx + zz));
        final double m12 = 2.0 * (yz - xw);
        final double m13 = 0.0;

        final double m20 = 2.0 * (xz - yw);
        final double m21 = 2.0 * (yz + xw);
        final double m22 = 1.0 - (2.0 * (xx + yy));
        final double m23 = 0.0;

        return AffineTransformMatrix3D.of(
                    m00, m01, m02, m03,
                    m10, m11, m12, m13,
                    m20, m21, m22, m23
                );
    }

    /**
     * Multiply this instance by the given argument, returning the result as
     * a new instance. This is equivalent to the expression {@code t * q} where
     * {@code q} is the argument and {@code t} is this instance.
     *
     * <p>
     * Multiplication of quaternions behaves similarly to transformation
     * matrices in regard to the order that operations are performed.
     * For example, if <code>q<sub>1</sub></code> and <code>q<sub>2</sub></code> are unit
     * quaternions, then the quaternion <code>q<sub>r</sub> = q<sub>1</sub>*q<sub>2</sub></code>
     * will give the effect of applying the rotation in <code>q<sub>2</sub></code> followed
     * by the rotation in <code>q<sub>1</sub></code>. In other words, the rightmost element
     * in the multiplication is applied first.
     * </p>
     *
     * @param q quaternion to multiply with the current instance
     * @return the result of multiplying this quaternion by the argument
     */
    public QuaternionRotation multiply(final QuaternionRotation q) {
        final Quaternion product = quat.multiply(q.quat);
        return new QuaternionRotation(product);
    }

    /** Multiply the argument by this instance, returning the result as
     * a new instance. This is equivalent to the expression {@code q * t} where
     * {@code q} is the argument and {@code t} is this instance.
     *
     * <p>
     * Multiplication of quaternions behaves similarly to transformation
     * matrices in regard to the order that operations are performed.
     * For example, if <code>q<sub>1</sub></code> and <code>q<sub>2</sub></code> are unit
     * quaternions, then the quaternion <code>q<sub>r</sub> = q<sub>1</sub>*q<sub>2</sub></code>
     * will give the effect of applying the rotation in <code>q<sub>2</sub></code> followed
     * by the rotation in <code>q<sub>1</sub></code>. In other words, the rightmost element
     * in the multiplication is applied first.
     * </p>
     *
     * @param q quaternion to multiply by the current instance
     * @return the result of multiplying the argument by the current instance
     */
    public QuaternionRotation premultiply(final QuaternionRotation q) {
        return q.multiply(this);
    }

    /**
     * Creates a {@link Slerp} transform.
     *
     * @param end End rotation of the interpolation.
     * @return the transform.
     */
    public Slerp slerp(QuaternionRotation end) {
        return new Slerp(quat, end.quat);
    }

    /** Get a sequence of axis-angle rotations that produce an overall rotation equivalent to this instance.
     *
     * <p>
     * In most cases, the returned rotation sequence will be unique. However, at points of singularity
     * (second angle equal to {@code 0} or {@code -pi} for Euler angles and {@code +pi/2} or {@code -pi/2}
     * for Tait-Bryan angles), there are an infinite number of possible sequences that produce the same result.
     * In these cases, the result is returned that leaves the last rotation equal to 0 (in the case of a relative
     * reference frame) or the first rotation equal to 0 (in the case of an absolute reference frame).
     * </p>
     *
     * @param frame the reference frame used to interpret the positions of the rotation axes
     * @param axes the sequence of rotation axes
     * @return a sequence of axis-angle rotations equivalent to this rotation
     */
    public AxisAngleSequence toAxisAngleSequence(final AxisReferenceFrame frame, final AxisSequence axes) {
        if (frame == null) {
            throw new IllegalArgumentException("Axis reference frame cannot be null");
        }
        if (axes == null) {
            throw new IllegalArgumentException("Axis sequence cannot be null");
        }

        double[] angles = getAngles(frame, axes);

        return new AxisAngleSequence(frame, axes, angles[0], angles[1], angles[2]);
    }

    /** Get a sequence of axis-angle rotations that produce an overall rotation equivalent to this instance.
     * Each rotation axis is interpreted relative to the rotated coordinate frame (ie, intrinsic rotation).
     * @param axes the sequence of rotation axes
     * @return a sequence of relative axis-angle rotations equivalent to this rotation
     * @see #toAxisAngleSequence(AxisReferenceFrame, AxisSequence)
     */
    public AxisAngleSequence toRelativeAxisAngleSequence(final AxisSequence axes) {
        return toAxisAngleSequence(AxisReferenceFrame.RELATIVE, axes);
    }

    /** Get a sequence of axis-angle rotations that produce an overall rotation equivalent to this instance.
     * Each rotation axis is interpreted as part of an absolute, unmoving coordinate frame (ie, extrinsic rotation).
     * @param axes the sequence of rotation axes
     * @return a sequence of absolute axis-angle rotations equivalent to this rotation
     * @see #toAxisAngleSequence(AxisReferenceFrame, AxisSequence)
     */
    public AxisAngleSequence toAbsoluteAxisAngleSequence(final AxisSequence axes) {
        return toAxisAngleSequence(AxisReferenceFrame.ABSOLUTE, axes);
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return quat.hashCode();
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof QuaternionRotation)) {
            return false;
        }

        QuaternionRotation other = (QuaternionRotation) obj;
        return Objects.equals(this.quat, other.quat);
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return quat.toString();
    }

    /** Get a sequence of angles around the given axes that produce a rotation equivalent
     * to this instance.
     * @param frame the reference frame used to define the positions of the axes
     * @param axes the axis sequence
     * @return a sequence of angles around the given axes that produce a rotation equivalent
     *      to this instance
     */
    private double[] getAngles(final AxisReferenceFrame frame, final AxisSequence axes) {

        AxisSequenceType sequenceType = axes.getType();

        final Vector3D axis1 = axes.getAxis1();
        final Vector3D axis2 = axes.getAxis2();
        final Vector3D axis3 = axes.getAxis3();

        if (frame == AxisReferenceFrame.RELATIVE) {
            if (sequenceType == AxisSequenceType.TAIT_BRYAN) {
                return getRelativeTaitBryanAngles(axis1, axis2, axis3);
            } else if (sequenceType == AxisSequenceType.EULER) {
                return getRelativeEulerAngles(axis1, axis2);
            }
        } else if (frame == AxisReferenceFrame.ABSOLUTE) {
            if (sequenceType == AxisSequenceType.TAIT_BRYAN) {
                return getAbsoluteTaitBryanAngles(axis1, axis2, axis3);
            } else if (sequenceType == AxisSequenceType.EULER) {
                return getAbsoluteEulerAngles(axis1, axis2);
            }
        }

        // all possibilities should have been covered above
        throw new GeometryInternalError();
    }

    /** Get a sequence of angles around the given Tait-Bryan axes that produce a rotation equivalent
     * to this instance. The axes are interpreted as being relative to the rotated coordinate frame.
     * @param axis1 first Tait-Bryan axis
     * @param axis2 second Tait-Bryan axis
     * @param axis3 third Tait-Bryan axis
     * @return a sequence of rotation angles around the relative input axes that produce a rotation equivalent
     *      to this instance
     */
    private double[] getRelativeTaitBryanAngles(final Vector3D axis1, final Vector3D axis2, final Vector3D axis3) {

        // We can use geometry to get the first and second angles pretty easily here by analyzing the positions
        // of the transformed rotation axes. The third angle is trickier but we can get it by treating it as
        // if it were the first rotation in the inverse (which it would be).

        final Vector3D vec3 = apply(axis3);
        final Vector3D invVec1 = inverse().apply(axis1);

        final double angle2Sin = vec3.dot(axis2.cross(axis3));

        if (angle2Sin < -AXIS_ANGLE_SINGULARITY_THRESHOLD ||
                angle2Sin > AXIS_ANGLE_SINGULARITY_THRESHOLD) {

            final Vector3D vec2 = apply(axis2);

            final double angle1TanY = vec2.dot(axis1.cross(axis2));
            final double angle1TanX = vec2.dot(axis2);

            final double angle2 = angle2Sin > AXIS_ANGLE_SINGULARITY_THRESHOLD ?
                    PlaneAngleRadians.PI_OVER_TWO :
                    -PlaneAngleRadians.PI_OVER_TWO;

            return new double[] {
                Math.atan2(angle1TanY, angle1TanX),
                angle2,
                0.0
            };
        }

        final Vector3D  crossAxis13 = axis1.cross(axis3);

        final double angle1TanY = vec3.dot(crossAxis13);
        final double angle1TanX = vec3.dot(axis3);

        final double angle3TanY = invVec1.dot(crossAxis13);
        final double angle3TanX = invVec1.dot(axis1);

        return new double[] {
            Math.atan2(angle1TanY, angle1TanX),
            Math.asin(angle2Sin),
            Math.atan2(angle3TanY, angle3TanX)
        };
    }

    /** Get a sequence of angles around the given Tait-Bryan axes that produce a rotation equivalent
     * to this instance. The axes are interpreted as being part of an absolute (unmoving) coordinate frame.
     * @param axis1 first Tait-Bryan axis
     * @param axis2 second Tait-Bryan axis
     * @param axis3 third Tait-Bryan axis
     * @return a sequence of rotation angles around the absolute input axes that produce a rotation equivalent
     *      to this instance
     */
    private double[] getAbsoluteTaitBryanAngles(final Vector3D axis1, final Vector3D axis2, final Vector3D axis3) {
        // A relative axis-angle rotation sequence is equivalent to an absolute one with the rotation
        // sequence reversed, meaning we can reuse our relative logic here.
        return reverseArray(getRelativeTaitBryanAngles(axis3, axis2, axis1));
    }

    /** Get a sequence of angles around the given Euler axes that produce a rotation equivalent
     * to this instance. The axes are interpreted as being relative to the rotated coordinate frame. Only
     * the first two axes are needed since, by definition, the first Euler angle axis is repeated as the
     * third axis.
     * @param axis1 first Euler axis
     * @param axis2 second Euler axis
     * @return a sequence of rotation angles around the relative input axes that produce a rotation equivalent
     *      to this instance
     */
    private double[] getRelativeEulerAngles(final Vector3D axis1, final Vector3D axis2) {

        // Use the same overall approach as with the Tait-Bryan angles: get the first two angles by looking
        // at the transformed rotation axes and the third by using the inverse.

        final Vector3D crossAxis = axis1.cross(axis2);

        final Vector3D vec1 = apply(axis1);
        final Vector3D invVec1 = inverse().apply(axis1);

        final double angle2Cos = vec1.dot(axis1);

        if (angle2Cos < -AXIS_ANGLE_SINGULARITY_THRESHOLD ||
                angle2Cos > AXIS_ANGLE_SINGULARITY_THRESHOLD) {

            final Vector3D vec2 = apply(axis2);

            final double angle1TanY = vec2.dot(crossAxis);
            final double angle1TanX = vec2.dot(axis2);

            final double angle2 = angle2Cos > AXIS_ANGLE_SINGULARITY_THRESHOLD ? 0.0 : PlaneAngleRadians.PI;

            return new double[] {
                Math.atan2(angle1TanY, angle1TanX),
                angle2,
                0.0
            };
        }

        final double angle1TanY = vec1.dot(axis2);
        final double angle1TanX = -vec1.dot(crossAxis);

        final double angle3TanY = invVec1.dot(axis2);
        final double angle3TanX = invVec1.dot(crossAxis);

        return new double[] {
            Math.atan2(angle1TanY, angle1TanX),
            Math.acos(angle2Cos),
            Math.atan2(angle3TanY, angle3TanX)
        };
    }

    /** Get a sequence of angles around the given Euler axes that produce a rotation equivalent
     * to this instance. The axes are interpreted as being part of an absolute (unmoving) coordinate frame.
     * Only the first two axes are needed since, by definition, the first Euler angle axis is repeated as
     * the third axis.
     * @param axis1 first Euler axis
     * @param axis2 second Euler axis
     * @return a sequence of rotation angles around the absolute input axes that produce a rotation equivalent
     *      to this instance
     */
    private double[] getAbsoluteEulerAngles(final Vector3D axis1, final Vector3D axis2) {
        // A relative axis-angle rotation sequence is equivalent to an absolute one with the rotation
        // sequence reversed, meaning we can reuse our relative logic here.
        return reverseArray(getRelativeEulerAngles(axis1, axis2));
    }

    /** Create a new instance from the given quaternion. The quaternion is normalized and
     * converted to positive polar form (ie, with w &gt;= 0).
     *
     * @param quat the quaternion to use for the rotation
     * @return a new instance built from the given quaternion.
     * @throws IllegalStateException if the the norm of the given components is zero,
     *                              NaN, or infinite
     * @see Quaternion#normalize()
     * @see Quaternion#positivePolarForm()
     */
    public static QuaternionRotation of(Quaternion quat) {
        return new QuaternionRotation(quat);
    }

    /**
     * Create a new instance from the given quaternion values. The inputs are
     * normalized and converted to positive polar form (ie, with w &gt;= 0).
     *
     * @param w quaternion scalar component
     * @param x first quaternion vectorial component
     * @param y second quaternion vectorial component
     * @param z third quaternion vectorial component
     * @return a new instance containing the normalized quaterion components
     * @throws IllegalStateException if the the norm of the given components is zero,
     *                              NaN, or infinite
     * @see Quaternion#normalize()
     * @see Quaternion#positivePolarForm()
     */
    public static QuaternionRotation of(final double w,
                                        final double x,
                                        final double y,
                                        final double z) {
        return of(Quaternion.of(w, x, y, z));
    }

    /** Return an instance representing a rotation of zero.
     * @return instance representing a rotation of zero.
     */
    public static QuaternionRotation identity() {
        return IDENTITY_INSTANCE;
    }

    /** Create a new instance representing a rotation of {@code angle} radians around
     * {@code axis}.
     *
     * <p>
     * Rotation direction follows the right-hand rule, meaning that if one
     * places their right hand such that the thumb points in the direction of the vector,
     * the curl of the fingers indicates the direction of rotation.
     * </p>
     *
     * <p>
     * Note that the returned quaternion will represent the defined rotation but the values
     * returned by {@link #getAxis()} and {@link #getAngle()} may not match the ones given here.
     * This is because the axis and angle are normalized such that the axis has unit length,
     * and the angle lies in the range {@code [0, pi]}. Depending on the inputs, the axis may
     * need to be inverted in order for the angle to lie in this range.
     * </p>
     *
     * @param axis the axis of rotation
     * @param angle angle of rotation in radians
     * @return a new instance representing the defined rotation
     *
     * @throws IllegalArgumentException if the given axis cannot be normalized or the angle is NaN or infinite
     */
    public static QuaternionRotation fromAxisAngle(final Vector3D axis, final double angle) {
        // reference formula:
        // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
        final Vector3D normAxis = axis.normalize();

        if (!Double.isFinite(angle)) {
            throw new IllegalArgumentException("Invalid angle: " + angle);
        }

        final double halfAngle = 0.5 * angle;
        final double sinHalfAngle = Math.sin(halfAngle);

        final double w = Math.cos(halfAngle);
        final double x = sinHalfAngle * normAxis.getX();
        final double y = sinHalfAngle * normAxis.getY();
        final double z = sinHalfAngle * normAxis.getZ();

        return of(w, x, y, z);
    }

    /** Return an instance that rotates the first vector to the second.
     *
     * <p>Except for a possible scale factor, if the returned instance is
     * applied to vector {@code u}, it will produce the vector {@code v}. There are an
     * infinite number of such rotations; this method chooses the one with the smallest
     * associated angle, meaning the one whose axis is orthogonal to the {@code (u, v)}
     * plane. If {@code u} and {@code v} are collinear, an arbitrary rotation axis is
     * chosen.</p>
     *
     * @param u origin vector
     * @param v target vector
     * @return a new instance that rotates {@code u} to point in the direction of {@code v}
     * @throws IllegalArgumentException if either vector has a norm of zero, NaN, or infinity
     */
    public static QuaternionRotation createVectorRotation(final Vector3D u, final Vector3D v) {

        double normProduct  = Vectors.checkedNorm(u) * Vectors.checkedNorm(v);
        double dot = u.dot(v);

        if (dot < ANTIPARALLEL_DOT_THRESHOLD * normProduct) {
            // Special case where u1 = -u2:
            // create a pi angle rotation around
            // an arbitrary unit vector orthogonal to u1
            final Vector3D axis = u.orthogonal();

            return of(0,
                      axis.getX(),
                      axis.getY(),
                      axis.getZ());
        }

        // General case:
        // (u1, u2) defines a plane so rotate around the normal of the plane

        // w must equal cos(theta/2); we can calculate this directly using values
        // we already have with the identity cos(theta/2) = sqrt((1 + cos(theta)) / 2)
        // and the fact that dot = norm(u1) * norm(u2) * cos(theta).
        final double w = Math.sqrt(0.5 * (1.0 + (dot / normProduct)));

        // The cross product u1 x u2 must be normalized and then multiplied by
        // sin(theta/2) in order to set the vectorial part of the quaternion. To
        // accomplish this, we'll use the following:
        //
        // 1) norm(a x b) = norm(a) * norm(b) * sin(theta)
        // 2) sin(theta/2) = sqrt((1 - cos(theta)) / 2)
        //
        // Our full, combined normalization and sine half angle term factor then becomes:
        //
        // sqrt((1 - cos(theta)) / 2) / (norm(u1) * norm(u2) * sin(theta))
        //
        // This can be simplified to the expression below.
        final double vectorialScaleFactor = 1.0 / (2.0 * w * normProduct);
        final Vector3D axis = u.cross(v);

        return of(w,
                  vectorialScaleFactor * axis.getX(),
                  vectorialScaleFactor * axis.getY(),
                  vectorialScaleFactor * axis.getZ());
    }

    /** Return an instance that rotates the basis defined by the first two vectors into the basis
     * defined by the second two.
     *
     * <p>
     * The given basis vectors do not have to be directly orthogonal. A right-handed orthonormal
     * basis is created from each pair by normalizing the first vector, making the second vector
     * orthogonal to the first, and then taking the cross product. A rotation is then calculated
     * that rotates the first to the second.
     * </p>
     *
     * @param u1 first vector of the source basis
     * @param u2 second vector of the source basis
     * @param v1 first vector of the target basis
     * @param v2 second vector of the target basis
     * @return an instance that rotates the source basis to the target basis
     * @throws IllegalArgumentException if any of the input vectors cannot be normalized
     *      or the vectors defining either basis are colinear
     */
    public static QuaternionRotation createBasisRotation(final Vector3D u1, final Vector3D u2,
            final Vector3D v1, final Vector3D v2) {

        // calculate orthonormalized bases
        final Vector3D a = u1.normalize();
        final Vector3D b = a.orthogonal(u2);
        final Vector3D c = a.cross(b);

        final Vector3D d = v1.normalize();
        final Vector3D e = d.orthogonal(v2);
        final Vector3D f = d.cross(e);

        // create an orthogonal rotation matrix representing the change of basis; this matrix will
        // be the multiplication of the matrix composed of the column vectors d, e, f and the
        // inverse of the matrix composed of the column vectors a, b, c (which is simply the transpose since
        // it's orthogonal).
        final double m00 = LinearCombination.value(d.getX(), a.getX(), e.getX(), b.getX(), f.getX(), c.getX());
        final double m01 = LinearCombination.value(d.getX(), a.getY(), e.getX(), b.getY(), f.getX(), c.getY());
        final double m02 = LinearCombination.value(d.getX(), a.getZ(), e.getX(), b.getZ(), f.getX(), c.getZ());

        final double m10 = LinearCombination.value(d.getY(), a.getX(), e.getY(), b.getX(), f.getY(), c.getX());
        final double m11 = LinearCombination.value(d.getY(), a.getY(), e.getY(), b.getY(), f.getY(), c.getY());
        final double m12 = LinearCombination.value(d.getY(), a.getZ(), e.getY(), b.getZ(), f.getY(), c.getZ());

        final double m20 = LinearCombination.value(d.getZ(), a.getX(), e.getZ(), b.getX(), f.getZ(), c.getX());
        final double m21 = LinearCombination.value(d.getZ(), a.getY(), e.getZ(), b.getY(), f.getZ(), c.getY());
        final double m22 = LinearCombination.value(d.getZ(), a.getZ(), e.getZ(), b.getZ(), f.getZ(), c.getZ());


        return orthogonalRotationMatrixToQuaternion(
                    m00, m01, m02,
                    m10, m11, m12,
                    m20, m21, m22
                );
    }

    /** Create a new instance equivalent to the given sequence of axis-angle rotations.
     * @param sequence the axis-angle rotation sequence to convert to a quaternion rotation
     * @return instance representing a rotation equivalent to the given axis-angle sequence
     */
    public static QuaternionRotation fromAxisAngleSequence(final AxisAngleSequence sequence) {
        final AxisSequence axes = sequence.getAxisSequence();

        final QuaternionRotation q1 = fromAxisAngle(axes.getAxis1(), sequence.getAngle1());
        final QuaternionRotation q2 = fromAxisAngle(axes.getAxis2(), sequence.getAngle2());
        final QuaternionRotation q3 = fromAxisAngle(axes.getAxis3(), sequence.getAngle3());

        if (sequence.getReferenceFrame() == AxisReferenceFrame.ABSOLUTE) {
            return q3.multiply(q2).multiply(q1);
        }

        return q1.multiply(q2).multiply(q3);
    }

    /** Create an instance from an orthogonal rotation matrix.
     *
     * @param m00 matrix entry <code>m<sub>0,0</sub></code>
     * @param m01 matrix entry <code>m<sub>0,1</sub></code>
     * @param m02 matrix entry <code>m<sub>0,2</sub></code>
     * @param m10 matrix entry <code>m<sub>1,0</sub></code>
     * @param m11 matrix entry <code>m<sub>1,1</sub></code>
     * @param m12 matrix entry <code>m<sub>1,2</sub></code>
     * @param m20 matrix entry <code>m<sub>2,0</sub></code>
     * @param m21 matrix entry <code>m<sub>2,1</sub></code>
     * @param m22 matrix entry <code>m<sub>2,2</sub></code>
     * @return an instance representing the same 3D rotation as the given matrix
     */
    private static QuaternionRotation orthogonalRotationMatrixToQuaternion(
            final double m00, final double m01, final double m02,
            final double m10, final double m11, final double m12,
            final double m20, final double m21, final double m22) {

        // reference formula:
        // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/

        // The overall approach here is to take the equations for converting a quaternion to
        // a matrix along with the fact that 1 = x^2 + y^2 + z^2 + w^2 for a normalized quaternion
        // and solve for the various terms. This can theoretically be done using just the diagonal
        // terms from the matrix. However, there are a few issues with this:
        // 1) The term that we end up taking the square root of may be negative.
        // 2) It's ambiguous as to whether we should use a plus or minus for the value of the
        //    square root.
        // We'll address these concerns by only calculating a single term from one of the diagonal
        // elements and then calculate the rest from the non-diagonals, which do not involve
        // a square root. This solves the first issue since we can make sure to choose a diagonal
        // element that will not cause us to take a square root of a negative number. The second
        // issue is solved since only the relative signs between the quaternion terms are important
        // (q and -q represent the same 3D rotation). It therefore doesn't matter whether we choose
        // a plus or minus for our initial square root solution.

        final double trace = m00 + m11 + m22;

        double w;
        double x;
        double y;
        double z;

        if (trace > 0.0) {
            // let s = 4*w
            final double s = 2.0 * Math.sqrt(1.0 + trace);
            final double sinv = 1.0 / s;

            x = (m21 - m12) * sinv;
            y = (m02 - m20) * sinv;
            z = (m10 - m01) * sinv;
            w = 0.25 * s;
        } else if ((m00 > m11) && (m00 > m22)) {
            // let s = 4*x
            final double s = 2.0 * Math.sqrt(1.0 + m00 - m11 - m22);
            final double sinv = 1.0 / s;

            x = 0.25 * s;
            y = (m01 + m10) * sinv;
            z = (m02 + m20) * sinv;
            w = (m21 - m12) * sinv;
        } else if (m11 > m22) {
            // let s = 4*y
            final double s = 2.0 * Math.sqrt(1.0 + m11 - m00 - m22);
            final double sinv = 1.0 / s;

            x = (m01 + m10) * sinv;
            y = 0.25 * s;
            z = (m21 + m12) * sinv;
            w = (m02 - m20) * sinv;
        } else {
            // let s = 4*z
            final double s = 2.0 * Math.sqrt(1.0 + m22 - m00 - m11);
            final double sinv = 1.0 / s;

            x = (m02 + m20) * sinv;
            y = (m21 + m12) * sinv;
            z = 0.25 * s;
            w = (m10 - m01) * sinv;
        }

        return of(w, x, y, z);
    }

    /** Reverse the elements in {@code arr}. The array is returned.
     * @param arr the array to reverse
     * @return the input array with the elements reversed
     */
    private static double[] reverseArray(final double[] arr) {

        final int len = arr.length;
        double temp;

        int i;
        int j;

        for (i = 0, j = len - 1; i < len / 2; ++i, --j) {
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

        return arr;
    }
}
