/* * $Id$ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc * * Copyright (c) 2000-2012 Stephane GALLAND. * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, * Universite de Technologie de Belfort-Montbeliard. * Copyright (c) 2013-2016 The original authors, and other authors. * * Licensed 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.arakhne.afc.math.geometry.d3; import java.io.Serializable; import org.eclipse.xtext.xbase.lib.Pure; import org.arakhne.afc.math.geometry.coordinatesystem.CoordinateSystem3D; import org.arakhne.afc.math.geometry.d3.d.Vector3d; import org.arakhne.afc.math.matrix.Matrix3d; import org.arakhne.afc.math.matrix.Matrix4d; /** A 4 element unit quaternion represented by x, y, z, w coordinates. * The quaternion is always normalized. * * <h3>Other Rotation Representations</h3> * * <p>Other representations of an rotation are available from this class: * axis-angle, and Euler angles. * * <h4>Axis Angles</h4> * The axis–angle representation of a rotation parameterizes a rotation in a three-dimensional * Euclidean space by two values: a unit vector, indicating the direction of an axis of rotation, and * an angle describing the magnitude of the rotation about the axis. * The rotation occurs in the sense prescribed by the (left/right)-hand rule. * <img src="doc-files/axis_angle.png" alt="[Axis-Angle Representation]"> * * <h4>Euler Angles</h4> * The term "Euler Angle" is used for any representation of 3 dimensional * rotations where the rotation is decomposed into 3 separate angles. * * <p>There is no single set of conventions and standards in this area, * therefore the following conventions was choosen:<ul> * <li>angle applied first: heading;</li> * <li>angle applied second: attitude;</li> * <li>angle applied last: bank</li> * </ul> * * <p>Examples: NASA aircraft standard and telescope standard * <img src="doc-files/euler_plane.gif" alt="[NASA Aircraft Standard]"> * <img src="doc-files/euler_telescop.gif" alt="[Telescope Standard]"> * * @author $Author: sgalland$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ public interface Quaternion extends Cloneable, Serializable { /** Replies the X coordinate. * * @return x */ @Pure double getX(); /** Set the X coordinate. * * @param x x coordinate. */ void setX(double x); /** Replies the Y coordinate. * * @return y */ @Pure double getY(); /** Set the Y coordinate. * * @param y y coordinate. */ void setY(double y); /** Replies the Z coordinate. * * @return z */ @Pure double getZ(); /** Set the Z coordinate. * * @param z z coordinate. */ void setZ(double z); /** Replies the W coordinate. * * @return w */ @Pure double getW(); /** Set the W coordinate. * * @param w w coordinate. */ void setW(double w); /** * Returns true if the L-infinite distance between this tuple * and tuple t1 is less than or equal to the epsilon parameter, * otherwise returns false. The L-infinite * distance is equal to MAX[abs(x1-x2), abs(y1-y2)]. * @param t1 the tuple to be compared to this tuple * @param epsilon the threshold value * @return true or false */ @Pure boolean epsilonEquals(Quaternion t1, double epsilon); /** * Sets the value of this quaternion to the conjugate of quaternion q1. * @param q1 the source vector */ void conjugate(Quaternion q1); /** * Sets the value of this quaternion to the conjugate of itself. */ void conjugate(); /** * Sets the value of this quaternion to the quaternion product of * quaternions q1 and q2 (this = q1 * q2). * Note that this is safe for aliasing (e.g. this can be q1 or q2). * @param q1 the first quaternion * @param q2 the second quaternion */ void mul(Quaternion q1, Quaternion q2); /** * Sets the value of this quaternion to the quaternion product of * itself and q1 (this = this * q1). * @param q1 the other quaternion */ void mul(Quaternion q1); /** * Multiplies quaternion q1 by the inverse of quaternion q2 and places * the value into this quaternion. The value of both argument quaternions * is preservered (this = q1 * q2^-1). * @param q1 the first quaternion * @param q2 the second quaternion */ void mulInverse(Quaternion q1, Quaternion q2); /** * Multiplies this quaternion by the inverse of quaternion q1 and places * the value into this quaternion. The value of the argument quaternion * is preserved (this = this * q^-1). * @param q1 the other quaternion */ void mulInverse(Quaternion q1); /** * Sets the value of this quaternion to quaternion inverse of quaternion q1. * @param q1 the quaternion to be inverted */ void inverse(Quaternion q1); /** * Sets the value of this quaternion to the quaternion inverse of itself. */ void inverse(); /** * Sets the value of this quaternion to the normalized value * of quaternion q1. * @param q1 the quaternion to be normalized. */ void normalize(Quaternion q1); /** * Normalizes the value of this quaternion in place. */ void normalize(); /** * Sets the value of this quaternion to the rotational component of * the passed matrix. * @param m1 the Matrix4f */ void setFromMatrix(Matrix4d m1); /** * Sets the value of this quaternion to the rotational component of * the passed matrix. * @param m1 the Matrix3f */ void setFromMatrix(Matrix3d m1); /** Set the quaternion coordinates. * * @param x x coordinate. * @param y y coordinate. * @param z z coordinate. * @param w w coordinate. */ void set(double x, double y, double z, double w); /** Set the quaternion coordinates. * * @param quat the quaternion to copy. */ void set(Quaternion quat); /** * Sets the value of this quaternion to the equivalent rotation * of the Axis-Angle arguments. * @param axis is the axis of rotation. * @param angle is the rotation around the axis. */ void setAxisAngle(Vector3D<?, ?> axis, double angle); /** * Sets the value of this quaternion to the equivalent rotation * of the Axis-Angle arguments. * @param x1 is the x coordinate of the rotation axis * @param y1 is the y coordinate of the rotation axis * @param z1 is the z coordinate of the rotation axis * @param angle is the rotation around the axis. */ void setAxisAngle(double x1, double y1, double z1, double angle); /** Replies the rotation axis-angle represented by this quaternion. * * @return the rotation axis-angle. */ @Pure Vector3D<?, ?> getAxis(); /** Replies the rotation angle represented by this quaternion. * * @return the rotation axis * @see #setAxisAngle(Vector3D, double) * @see #setAxisAngle(double, double, double, double) * @see #getAxis() */ @Pure double getAngle(); /** Replies the rotation axis represented by this quaternion. * * @return the rotation axis * @see #setAxisAngle(Vector3D, double) * @see #setAxisAngle(double, double, double, double) * @see #getAngle() */ @Pure AxisAngle getAxisAngle(); /** * Performs a great circle interpolation between this quaternion * and the quaternion parameter and places the result into this * quaternion. * @param q1 the other quaternion * @param alpha the alpha interpolation parameter */ void interpolate(Quaternion q1, double alpha); /** * Performs a great circle interpolation between quaternion q1 * and quaternion q2 and places the result into this quaternion. * @param q1 the first quaternion * @param q2 the second quaternion * @param alpha the alpha interpolation parameter */ void interpolate(Quaternion q1, Quaternion q2, double alpha); /** Set the quaternion with the Euler angles. * * @param angles the Euler angles. * @see <a href="http://en.wikipedia.org/wiki/Euler_angles">Euler Angles</a> * @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm">Euler to Quaternion</a> */ void setEulerAngles(EulerAngles angles); /** Set the quaternion with the Euler angles. * The {@link CoordinateSystem3D#getDefaultCoordinateSystem() default coordinate system} * is used from applying the Euler angles. * * @param attitude is the rotation around left vector. * @param bank is the rotation around front vector. * @param heading is the rotation around top vector. * @see CoordinateSystem3D#getDefaultCoordinateSystem() * @see <a href="http://en.wikipedia.org/wiki/Euler_angles">Euler Angles</a> * @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm">Euler to Quaternion</a> */ void setEulerAngles(double attitude, double bank, double heading); /** Set the quaternion with the Euler angles. * * @param attitude is the rotation around left vector. * @param bank is the rotation around front vector. * @param heading is the rotation around top vector. * @param system the coordinate system to use for applying the Euler angles. * @see <a href="http://en.wikipedia.org/wiki/Euler_angles">Euler Angles</a> * @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm">Euler to Quaternion</a> */ void setEulerAngles(double attitude, double bank, double heading, CoordinateSystem3D system); /** * Replies the Euler's angles that corresponds to the quaternion. * The {@link CoordinateSystem3D#getDefaultCoordinateSystem() default coordinate system} * is used from applying the Euler angles. * * @return the heading, attitude and bank angles. * @see CoordinateSystem3D#getDefaultCoordinateSystem() * @see <a href="http://en.wikipedia.org/wiki/Euler_angles">Euler Angles</a> * @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm">Quaternion to Euler</a> */ @Pure EulerAngles getEulerAngles(); /** * Replies the Euler's angles that corresponds to the quaternion. * * @param system is the coordinate system used to define the up, left and front vectors. * @return the heading, attitude and bank angles. * @see <a href="http://en.wikipedia.org/wiki/Euler_angles">Euler Angles</a> * @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm">Quaternion to Euler</a> */ @Pure EulerAngles getEulerAngles(CoordinateSystem3D system); /** A representation of Euler Angles. * The term "Euler Angle" is used for any representation of 3 dimensional * rotations where the rotation is decomposed into 3 separate angles. * * <p>There is no single set of conventions and standards in this area, * therefore the following conventions was choosen:<ul> * <li>angle applied first: heading;</li> * <li>angle applied second: attitude;</li> * <li>angle applied last: bank</li> * </ul> * * <p>Examples: NASA aircraft standard and telescope standard * <img src="doc-files/euler_plane.gif" alt="[NASA Aircraft Standard]"> * <img src="doc-files/euler_telescop.gif" alt="[Telescope Standard]"> * * <p><strong>For creating an instance of this class, you must invoke * {@link Quaternion#getEulerAngles(CoordinateSystem3D)}.</strong> * * @author $Author: sgalland$ * @version $Name$ $Revision$ $Date$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ final class EulerAngles implements Cloneable, Serializable { private static final long serialVersionUID = -1532832128836084395L; private final double attitude; private final double bank; private final double heading; private final CoordinateSystem3D system; private EulerAngles(double attitude1, double bank1, double heading1, CoordinateSystem3D system1) { this.attitude = attitude1; this.bank = bank1; this.heading = heading1; this.system = system1; } /** Replies the attitude, the rotation around left vector. * * @return the attitude angle. */ @Pure public double getAttitude() { return this.attitude; } /** Replies the bank, the rotation around front vector. * * @return the bank angle. */ @Pure public double getBank() { return this.bank; } /** Replies the heading, the rotation around top vector. * * @return the heading angle. */ @Pure public double getHeading() { return this.heading; } /** Replies coordinate system used for obtaining the euler angles. * * @return the coordinate system. */ @Pure private CoordinateSystem3D getSystem() { return this.system; } } /** A representation of axis-angle. * The axis–angle representation of a rotation parameterizes a rotation in a three-dimensional * Euclidean space by two values: a unit vector, indicating the direction of an axis of rotation, and * an angle describing the magnitude of the rotation about the axis. * The rotation occurs in the sense prescribed by the (left/right)-hand rule. * <img src="doc-files/axis_angle.png" alt="[Axis-Angle Representation]"> * * <p><strong>For creating an instance of this class, you must invoke * {@link Quaternion#getAxisAngle()}.</strong> * * @author $Author: sgalland$ * @version $Name$ $Revision$ $Date$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ final class AxisAngle implements Cloneable, Serializable { private static final long serialVersionUID = -7228694369177792159L; private final double x; private final double y; private final double z; private final double angle; private AxisAngle(double x1, double y1, double z1, double angle1) { this.x = x1; this.y = y1; this.z = z1; this.angle = angle1; } /** Replies the rotation axis. * * @return the rotation axis. */ @Pure public Vector3D<?, ?> getAxis() { return new Vector3d(this.x, this.y, this.z); } /** Replies the rotation angle. * * @return the rotation angle. */ @Pure public double getAngle() { return this.angle; } } }