<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://patrius.cnes.fr/index.php?action=history&amp;feed=atom&amp;title=User_Manual_3.4.1_Rotations_and_quaternions</id>
	<title>User Manual 3.4.1 Rotations and quaternions - Historique des versions</title>
	<link rel="self" type="application/atom+xml" href="https://patrius.cnes.fr/index.php?action=history&amp;feed=atom&amp;title=User_Manual_3.4.1_Rotations_and_quaternions"/>
	<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_3.4.1_Rotations_and_quaternions&amp;action=history"/>
	<updated>2026-04-11T06:30:07Z</updated>
	<subtitle>Historique des versions pour cette page sur le wiki</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_3.4.1_Rotations_and_quaternions&amp;diff=1415&amp;oldid=prev</id>
		<title>Admin : Page créée avec « __NOTOC__  == Introduction == === Scope === This section describes rotation and quaternions.  === Javadoc === The relevant packages are documented here :  {| class=&quot;wikita... »</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_3.4.1_Rotations_and_quaternions&amp;diff=1415&amp;oldid=prev"/>
		<updated>2018-03-05T09:07:04Z</updated>

		<summary type="html">&lt;p&gt;Page créée avec « __NOTOC__  == Introduction == === Scope === This section describes rotation and quaternions.  === Javadoc === The relevant packages are documented here :  {| class=&amp;quot;wikita... »&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nouvelle page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes rotation and quaternions.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The relevant packages are documented here :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
| Commons Math &lt;br /&gt;
|[{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/package-summary.html Package org.apache.commons.math3.geometry.euclidean.threed]&lt;br /&gt;
|-&lt;br /&gt;
| Commons Math addons&lt;br /&gt;
|[{{JavaDoc3.4.1}}/org/apache/commons/math3/complex/package-summary.html Package org.apache.commons.math3.complex]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The relevant functionality can be found in the following commons-math packages :&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;org.apache.commons.math3.complex&amp;lt;/code&amp;gt; for the Quaternion class.&lt;br /&gt;
* &amp;lt;code&amp;gt;org.apache.commons.math3.cnesmerge.geometry.euclidean.threed&amp;lt;/code&amp;gt; for the Rotation class.&lt;br /&gt;
* &amp;lt;code&amp;gt;org.apache.commons.math3.geometry.euclidean.threed&amp;lt;/code&amp;gt; for the RotationOrder class.&lt;br /&gt;
&lt;br /&gt;
[[File:PATRIMOINESIRIUSSUMDiagQuatRot.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Rotations ===&lt;br /&gt;
The Rotation is part of the Commons-Math package org.apache.commons.math3.geometry.euclidean.threed.&lt;br /&gt;
&lt;br /&gt;
The Rotation is represented by a [{{JavaDoc3.4.1}}/org/apache/commons/math3/complex/Quaternion.html quaternion]: it is a unit quaternion (a quaternion of norm one).&lt;br /&gt;
The [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Rotation.html Rotation class] represents an algebraic rotation (i.e. a mathematical rotation).&lt;br /&gt;
&lt;br /&gt;
In a three dimensional space, a rotation &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; is a function that maps vectors to vectors &amp;lt;math&amp;gt;r: \vec{v} \mapsto \vec{w}&amp;lt;/math&amp;gt;. The rotation can be defined by one angle &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; and one axis &amp;lt;math&amp;gt;\vec{u}&amp;lt;/math&amp;gt;, transforming &amp;lt;math&amp;gt;\vec{v}&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;\vec{w}&amp;lt;/math&amp;gt; as described in the following figure.&lt;br /&gt;
&lt;br /&gt;
[[File:Rotations.png|center]]&lt;br /&gt;
&lt;br /&gt;
There are several ways to represent rotations. Amongst the most used are quaternions and rotation matrices. The following paragraphs aim to discuss each of them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Quaternions ===&lt;br /&gt;
An advantageous way to deal with rotations is by using quaternions (class &amp;lt;code&amp;gt;Quaternion&amp;lt;/code&amp;gt;). The quaternion that represents the rotation &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; defined by an angle &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; and a &amp;#039;&amp;#039;&amp;#039;normalized&amp;#039;&amp;#039;&amp;#039; axis &amp;lt;math&amp;gt;\vec{u}&amp;lt;/math&amp;gt; is :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;Q = \left( \begin{array}{ccc}&lt;br /&gt;
cos(\theta / 2) \\&lt;br /&gt;
  \vec{u}.sin(\theta / 2) \end{array} \right)&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With &amp;lt;math&amp;gt;\vec{u} = ( u_x, u_y, u_z )&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; can also be written as :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;Q = \left( \begin{array}{ccc}&lt;br /&gt;
cos(\theta / 2) \\&lt;br /&gt;
  u_x.sin(\theta / 2) \\&lt;br /&gt;
  u_y.sin(\theta / 2) \\&lt;br /&gt;
  u_z.sin(\theta / 2)\end{array} \right)&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quaternions that represent rotations are normalized :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;||Q|| = q_0^2 + q_1^2 + q_2^2 + q_3^2 = 1&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For normalized quaternions, the inverse quaternion &amp;lt;math&amp;gt;Q^{-1}&amp;lt;/math&amp;gt; is the same as the conjugate &amp;lt;math&amp;gt;Q^*&amp;lt;/math&amp;gt;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;Q^{-1} =Q^* = \left( \begin{array}{ccc} &lt;br /&gt;
cos(\theta / 2) \\ &lt;br /&gt;
-\vec{u}.sin(\theta / 2) \end{array} \right)&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The image &amp;lt;math&amp;gt;\vec{w}&amp;lt;/math&amp;gt; of a vector &amp;lt;math&amp;gt;\vec{v}&amp;lt;/math&amp;gt; transformed by the rotation represented by &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; is given by :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\vec{w} = Q.\vec{v}.Q^{*}&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A rotation quaternion is initialized as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// 90 deg rotation around z-axis&lt;br /&gt;
Vector3D axis = new Vector3D(0, 0, 1);&lt;br /&gt;
double angle = FastMath.PI / 2.;&lt;br /&gt;
Rotation r = new Rotation(axis, angle);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Examples of rotations and associated quaternions====&lt;br /&gt;
The rotation defined by the angle &amp;lt;math&amp;gt;\theta = \pi/2&amp;lt;/math&amp;gt; and the axis &amp;lt;math&amp;gt;\vec{u} = \vec{z}&amp;lt;/math&amp;gt; is represented by the quaternion :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;Q = \left( \begin{array}{ccc}&lt;br /&gt;
cos(\pi / 4) \\&lt;br /&gt;
  0.sin(\pi / 4) \\&lt;br /&gt;
  0.sin(\pi / 4) \\&lt;br /&gt;
  1.sin(\pi / 4)\end{array} \right) = \left( \begin{array}{ccc}&lt;br /&gt;
\sqrt 2 / 2 \\&lt;br /&gt;
  0 \\&lt;br /&gt;
  0 \\&lt;br /&gt;
  \sqrt 2 / 2\end{array} \right)&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The rotation defined by the angle &amp;lt;math&amp;gt;\theta = 2\pi/3&amp;lt;/math&amp;gt; and the axis &amp;lt;math&amp;gt;\vec{u} = (1,1,1)&amp;lt;/math&amp;gt; (witch has to be normalized) is represented by the quaternion :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;Q = \left( \begin{array}{ccc}&lt;br /&gt;
cos(\pi / 3) \\&lt;br /&gt;
  1/\sqrt 3.sin(\pi / 3) \\&lt;br /&gt;
  1/\sqrt 3.sin(\pi / 3) \\&lt;br /&gt;
  1/\sqrt 3.sin(\pi / 3)\end{array} \right) = \left( \begin{array}{ccc}&lt;br /&gt;
1 / 2 \\&lt;br /&gt;
1 / 2 \\&lt;br /&gt;
1 / 2 \\&lt;br /&gt;
1 / 2\end{array} \right)&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Rotation composition with quaternions====&lt;br /&gt;
&amp;lt;math&amp;gt;r_1: \vec{w_1} \mapsto \vec{w_2}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;r_2: \vec{w_2} \mapsto \vec{w_3}&amp;lt;/math&amp;gt; being two known rotations, the rotation composition &amp;lt;math&amp;gt;r: \vec{w_1} \mapsto \vec{w_3}&amp;lt;/math&amp;gt; can be computed as well. The quaternion corresponding to that new rotation is: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;Q = Q{_2}.Q{_1}&amp;lt;/math&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be proven as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\vec{w_2} = Q{_1}.\vec{w_1} .Q_{1}^{-1}&amp;lt;/math&amp;gt; &lt;br /&gt;
&amp;lt;math&amp;gt;\vec{w_3} = Q{_2}.\vec{w_2} .Q_{2}^{-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Substituting &amp;lt;math&amp;gt;\vec{w_2}&amp;lt;/math&amp;gt; in the expression of &amp;lt;math&amp;gt;\vec{w_3}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\vec{w_3} = Q{_2}.Q{_1}.\vec{w_1} .Q_{1}^{-1}.Q_{2}^{-1} = (Q{_2}.Q{_1}).\vec{w_1} .(Q_{2}.Q_{1})^{-1} = Q.\vec{w_1} .Q^{-1}&amp;lt;/math&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that in the expression of the quaternion &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; the rightmost quaternion is the one corresponding to the first rotation to  be performed.&lt;br /&gt;
&lt;br /&gt;
=== Rotation matrices ===&lt;br /&gt;
The matrix representation of a rotation is very intuitive altough more redundant compared to quaternions. A rotation matrix is a 3x3 (real) square matrix.&lt;br /&gt;
If the rotation &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; transforms an inital basis &amp;lt;math&amp;gt;(\vec{x}, \vec{y}, \vec{z})&amp;lt;/math&amp;gt; to a new one &amp;lt;math&amp;gt;(\vec{i}, \vec{j}, \vec{k})&amp;lt;/math&amp;gt; the columns of the rotation matrix are given by the components of the rotated basis vectors, expressed in the initial one. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;M = \left( \begin{array}{ccc}&lt;br /&gt;
i_x &amp;amp; j_x &amp;amp; k_x \\&lt;br /&gt;
i_y &amp;amp; j_y &amp;amp; k_y \\&lt;br /&gt;
i_z &amp;amp; j_z &amp;amp; k_z \end{array} \right)&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The matrix &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; has the following properties:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; is orthogonal (each column has norm 1)&lt;br /&gt;
* &amp;lt;math&amp;gt;det(M) = 1&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;M^{-1} = M^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Rotation matrix in term of quaternions====&lt;br /&gt;
Given a quaternion &amp;lt;math&amp;gt;Q = ( q_0, q_1, q_2, q_3 )&amp;lt;/math&amp;gt; the rotation matrix has the following expression in term of the components of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;M = \left( \begin{array}{ccc}&lt;br /&gt;
q_0^2 + q_1^2-q_2^2  -q_3^2  &amp;amp; 2q_1q_2 + q_0q_3 &amp;amp; 2q_0q_2 + q_1q_3 \\&lt;br /&gt;
2q_0q_3 + q_1q_2 &amp;amp; q_0^2 + q_1^2-q_2^2  -q_3^2 &amp;amp; 2q_2q_3 + q_0q_1 \\&lt;br /&gt;
2q_1q_3 + q_0q_2 &amp;amp; 2q_0q_1 + q_2q_3 &amp;amp; q_0^2 + q_1^2-q_2^2  -q_3^2 \end{array} \right)&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Building Rotations ===&lt;br /&gt;
Rotations can be represented by several different mathematical entities (matrices, axis and angle, Cardan or Euler angles, quaternions). The user can build a rotation from any of these representations, and any of these representations can be retrieved from a [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Rotation.html Rotation instance].&amp;lt;br&amp;gt;&lt;br /&gt;
In addition, a rotation can also be built implicitly from a set of vectors and their image or just a vector and its image.&lt;br /&gt;
&lt;br /&gt;
==== Rotation quaternion ====&lt;br /&gt;
&lt;br /&gt;
The rotation can be built from a rotation quaternion using one of the following constructors :&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Rotation(boolean needsNormalization, double q0, double q1, double q2, double q3)&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Rotation(boolean needsNormalization, final Quaternion quaternion)&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Rotation(boolean needsNormalization, final double[] q)&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
A rotation can be built from a normalized quaternion, i.e. a quaternion for which &amp;lt;math&amp;gt;q_0^2 + q_1^2 + q_2^2 + q_3^2 = 1&amp;lt;/math&amp;gt;. If the quaternion is not normalized, the constructor can normalize it in a preprocessing step. &lt;br /&gt;
&lt;br /&gt;
Note that some conventions put the scalar part of the quaternion as the fourth component and the vector part as the first three components. This is not Commons-Math convention. The scalar part is put as the first component.&lt;br /&gt;
&lt;br /&gt;
The rotation quaternion can be retrieve using &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;getQuaternion()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;getQi()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
==== Axis-angle representation ====&lt;br /&gt;
&lt;br /&gt;
The rotation can be built from an axis &amp;lt;math&amp;gt;(x, y, z)&amp;lt;/math&amp;gt; and an angle &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; with the following constructor : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// 90 deg rotation around z-axis&lt;br /&gt;
Vector3D axis = new Vector3D(0, 0, 1);&lt;br /&gt;
double angle = FastMath.PI / 2.;&lt;br /&gt;
Rotation r = new Rotation(axis, angle);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If necessary, the quaternion is normalized.&lt;br /&gt;
&lt;br /&gt;
The axis and the angle can be retrieved using &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;getAxis()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;getAngle()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
==== Matrix representation ====&lt;br /&gt;
The rotation can be built from a rotation matrix with the following constructor : &lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Rotation(double[][] m, double threshold) &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The rotation matrix can be retrieved using &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;getMatrix()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
==== Euler Angles ====&lt;br /&gt;
&lt;br /&gt;
===== The RotationOrder class =====&lt;br /&gt;
&lt;br /&gt;
The RotationOrder class contains static attributes, themselves being RotationOrder objects, describing every vector sequence that can be used to create a Rotation using Euler or Cardan angles.&lt;br /&gt;
&lt;br /&gt;
===== Using Euler angles in rotations =====&lt;br /&gt;
&lt;br /&gt;
A Rotation object can so be created using three angles and a RotationOrder describing the associated sequence of basis vectors.&amp;lt;br&amp;gt;&lt;br /&gt;
The user can also get the Cardan or Euler angles by giving a sequence, using the getAngles(RotationOrder) method.&amp;lt;br&amp;gt;&lt;br /&gt;
In some cases, there are singularities that make a rotation impossible to describe with a giver rotation order.&lt;br /&gt;
&lt;br /&gt;
Code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Rotation rotation = new Rotation(RotationOrder.YZX, 0.12, 0.54, 0.45);&lt;br /&gt;
double[] angles = rotation.getAngles(RotationOrder.ZXY);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Others representations ====&lt;br /&gt;
See [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Rotation.html Rotation javadoc].&lt;br /&gt;
&lt;br /&gt;
=== Using Rotations ===&lt;br /&gt;
The Rotation is part of the Commons-Math package org.apache.commons.math3.geometry.euclidean.threed.&lt;br /&gt;
&lt;br /&gt;
The Rotation is represented by a rotation quaternion : it is a unit quaternion (a quaternion of norm one).&lt;br /&gt;
The [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Rotation.html Rotation class] represents an algebraic rotation (i.e. a mathematical rotation). &lt;br /&gt;
Mettre formule quaternion angle&lt;br /&gt;
&lt;br /&gt;
==== Rotate a vector ====&lt;br /&gt;
&lt;br /&gt;
A rotation is an operator which basically rotates three dimensional [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Vector3D.html vectors] into other three dimensional [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Vector3D.html vectors] using &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;applyTo()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// vector A&lt;br /&gt;
Vector3D a = new Vector3D(1, 0, 0);&lt;br /&gt;
// build rotation r1&lt;br /&gt;
Vector3D u1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta1 = FastMath.PI / 2. ;&lt;br /&gt;
Rotation r1 = new Rotation(u1, theta1);&lt;br /&gt;
// vector B, image of A by r1&lt;br /&gt;
Vector3D b = r1.applyTo(a);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Compose rotations ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since a rotation is basically a vectorial operator, several rotations can be composed together and the composite operation r = r2 o r1 is also a rotation. r1 is applied before r2 and the operator &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;applyTo()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// build rotation r1&lt;br /&gt;
Vector3D u1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta1 = FastMath.PI / 2. ;&lt;br /&gt;
Rotation r1 = new Rotation(u1, theta1);&lt;br /&gt;
// build rotation r2&lt;br /&gt;
Vector3D u2 = new Vector3D(1, 0, 0);&lt;br /&gt;
double theta2 = FastMath.PI / 2. ;&lt;br /&gt;
Rotation r2 = new Rotation(u2, theta2);&lt;br /&gt;
// build r2 o r1&lt;br /&gt;
Rotation r2_o_r1 = r2.applyTo(r1);&lt;br /&gt;
// vector D, image of A by r2 o r1&lt;br /&gt;
Vector3D d = r2_o_r1.applyTo(a);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Change the basis of a vector ====&lt;br /&gt;
&lt;br /&gt;
The rotation could be used to change the basis of a vector using &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;applyInverseTo()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Define frame R2 by building the rotation r12 in frame R1&lt;br /&gt;
Vector3D u12_R1 = new Vector3D(1, 1, 1);&lt;br /&gt;
double theta12 = FastMath.PI* 3. / 2.;&lt;br /&gt;
Rotation r12_R1 = new Rotation(u12_R1, theta12);&lt;br /&gt;
// vector A, expressed in R1&lt;br /&gt;
Vector3D a_R1 = new Vector3D(0.5, 0.5, 0);&lt;br /&gt;
// vector A, expressed in R2&lt;br /&gt;
Vector3D a_R2 = r12_R1.applyInverseTo(a_R1);&lt;br /&gt;
        &lt;br /&gt;
// Build rotation r, in R1 frame&lt;br /&gt;
Vector3D u_R1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta = FastMath.PI;&lt;br /&gt;
Rotation r_R1 = new Rotation(u_R1, theta);&lt;br /&gt;
// Vector B, image of A by the rotation r, expressed in R1&lt;br /&gt;
Vector3D b_R1 = r_R1.applyTo(a_R1);&lt;br /&gt;
// Vector B, changed of basis, expressed in R2&lt;br /&gt;
Vector3D b_R2 = r12_R1.applyInverseTo(b_R1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Change the basis of a rotation ====&lt;br /&gt;
&lt;br /&gt;
Let be r a rotation built from the coordinates of its rotation axis. This vector is expressed in a frame &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; ; the rotation is supported only in this frame.&lt;br /&gt;
Let be &amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt; the rotation from &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;R_2&amp;lt;/math&amp;gt;, i.e. the image of the axis &amp;lt;math&amp;gt;x_1&amp;lt;/math&amp;gt; expressed in &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; using the rotation &amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt; is the axis  &amp;lt;math&amp;gt;x_2&amp;lt;/math&amp;gt; expressed in &amp;lt;math&amp;gt;R_2&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt;r_12(x_1) = x_2&amp;lt;/math&amp;gt; with &amp;lt;math&amp;gt;x_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt; expressed in &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The rotation r, changed of basis to be expressed in &amp;lt;math&amp;gt;R_2&amp;lt;/math&amp;gt; is obtained by &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt;.applyTo(r.revert())&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Define frame R2 by building the rotation r12 in frame R1&lt;br /&gt;
Vector3D u12_R1 = new Vector3D(1, 1, 1);&lt;br /&gt;
double theta12 = FastMath.PI* 3. / 2.;&lt;br /&gt;
Rotation r12_R1 = new Rotation(u12_R1, theta12);&lt;br /&gt;
// Build rotation r, in R1 frame&lt;br /&gt;
Vector3D u_R1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta = FastMath.PI;&lt;br /&gt;
Rotation r_R1 = new Rotation(u_R1, theta);&lt;br /&gt;
// Change the basis of r&lt;br /&gt;
Rotation r_R2 = r12_R1.applyTo(r_R1.revert());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using Quaternions ===&lt;br /&gt;
The &amp;lt;code&amp;gt;Quaternion&amp;lt;/code&amp;gt; class provides all elementary operations on quaternions: sum, product, inverse, conjugate, norm, dot product, etc.&lt;br /&gt;
Below are some examples of use:&lt;br /&gt;
&lt;br /&gt;
* Computing the product of two quaternions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Quaternion qA = new Quaternion(qA0,qA1,qA2,qA3);&lt;br /&gt;
Quaternion qB = new Quaternion(qB0,qB1,qB2,qB3);&lt;br /&gt;
Quaternion qProduct = Quaternion.multiply(qA,qB);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Getting the inverse of a quaternion :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Quaternion q = new Quaternion(0,5.1,4,8);&lt;br /&gt;
Quaternion qInverse = q.getInverse();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using Rotations interpolation ===&lt;br /&gt;
There are two implemented rotations interpolation methods :&lt;br /&gt;
&lt;br /&gt;
- LERP&amp;lt;br&amp;gt;&lt;br /&gt;
- SLERP&lt;br /&gt;
&lt;br /&gt;
=== LERP ===&lt;br /&gt;
&lt;br /&gt;
The LERP (linear interpolation method) is a method of curve fitting using linear polynomials. It is used for rotation interpolation goal in the PATRIUS library and relies on quaternion properties.&lt;br /&gt;
Let &amp;lt;math&amp;gt;q_{0}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;q_{1}&amp;lt;/math&amp;gt; be two normed quaternions and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; an interpolation parameter in the [0;1] range. We can defined &amp;lt;math&amp;gt;q_{t}&amp;lt;/math&amp;gt; as the interpolated quaternion so as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{t}= q_{0} + t\times(q_{1}- q_{0})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SLERP ===&lt;br /&gt;
&lt;br /&gt;
The SLERP (spherical linear interpolation method) refers to constant-speed motion along a unit-radius great circle arc, given the ends and an interpolation parameter between 0 and 1.It is used for rotation interpolation goal in the PATRIUS library. It relies on quaternion capabilities.&lt;br /&gt;
Let &amp;lt;math&amp;gt;q_{0}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;q_{1}&amp;lt;/math&amp;gt; be two normed quaternions and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; an interpolation parameter in the [0;1] range.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;First method:&amp;lt;/u&amp;gt;&lt;br /&gt;
We can defined &amp;lt;math&amp;gt;q_{t}&amp;lt;/math&amp;gt; as the interpolated quaternion so as :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{t} = q_{0} ( q_{0}^{-1} q_{1} )&amp;#039;&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where-prime- operation is defined such as : &amp;lt;math&amp;gt;t, q(\theta, \vec{u}): q’ = q(t \times \theta, \vec{u})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Second method:&amp;lt;/u&amp;gt;&lt;br /&gt;
Another approch is to compute qt so as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{t} = q_{0} \frac{\sin (1-t)\lambda}{\sin \lambda} + q_{1} \frac{\sin (t \lambda)}{\sin \lambda}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with lambda defined so as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cos \lambda = q_{0} . q_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This latest approach saves computing time when dealing with many SLERP computing.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Building Rotations ===&lt;br /&gt;
Rotations can be represented by several different mathematical entities (matrices, axis and angle, Cardan or Euler angles, quaternions). The user can build a rotation from any of these representations, and any of these representations can be retrieved from a [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Rotation.html Rotation instance].&lt;br /&gt;
In addition, a rotation can also be built implicitly from a set of vectors and their image or just a vector and its image.&lt;br /&gt;
&lt;br /&gt;
==== Rotation quaternion ====&lt;br /&gt;
&lt;br /&gt;
The rotation can be built from a rotation quaternion using one of the following constructors :&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Rotation(boolean needsNormalization, double q0, double q1, double q2, double q3)&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Rotation(boolean needsNormalization, final Quaternion quaternion)&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Rotation(boolean needsNormalization, final double[] q)&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
A rotation can be built from a normalized quaternion, i.e. a quaternion for which &amp;lt;math&amp;gt;q_0^2 + q_1^2 + q_2^2 + q_3^2 = 1&amp;lt;/math&amp;gt;. If the quaternion is not normalized, the constructor can normalize it in a preprocessing step. &lt;br /&gt;
&lt;br /&gt;
Note that some conventions put the scalar part of the quaternion as the fourth component and the vector part as the first three components. This is not Commons-Math convention. The scalar part is put as the first component.&lt;br /&gt;
&lt;br /&gt;
The rotation quaternion can be retrieve using&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;getQuaternion()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;getQi()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
==== Axis-angle representation ====&lt;br /&gt;
&lt;br /&gt;
The rotation can be built from an axis &amp;lt;math&amp;gt;(x, y, z)&amp;lt;/math&amp;gt; and an angle &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; with the following constructor : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// 90 deg rotation around z-axis&lt;br /&gt;
Vector3D axis = new Vector3D(0, 0, 1);&lt;br /&gt;
double angle = FastMath.PI / 2.;&lt;br /&gt;
Rotation r = new Rotation(axis, angle);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If necessary, the quaternion is normalized.&lt;br /&gt;
&lt;br /&gt;
The axis and the angle can be retrieved using &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;getAxis()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;getAngle()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
==== Matrix representation ====&lt;br /&gt;
The rotation can be built from a rotation matrix with the following constructor : &lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Rotation(double[][] m, double threshold) &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The rotation matrix can be retrieved using&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;getMatrix()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
==== Euler Angles ====&lt;br /&gt;
&lt;br /&gt;
===== The RotationOrder class =====&lt;br /&gt;
&lt;br /&gt;
The RotationOrder class contains static attributes, themselves being RotationOrder objects, describing every vector sequence that can be used to create a Rotation using Euler or Cardan angles.&lt;br /&gt;
&lt;br /&gt;
===== Using Euler angles in rotations =====&lt;br /&gt;
&lt;br /&gt;
A Rotation object can so be created using three angles and a RotationOrder describing the associated sequence of basis vectors.&amp;lt;br&amp;gt;&lt;br /&gt;
The user can also get the Cardan or Euler angles by giving a sequence, using the getAngles(RotationOrder) method.&amp;lt;br&amp;gt;&lt;br /&gt;
In some cases, there are singularities that make a rotation impossible to describe with a giver rotation order.&lt;br /&gt;
&lt;br /&gt;
Code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Rotation rotation = new Rotation(RotationOrder.YZX, 0.12, 0.54, 0.45);&lt;br /&gt;
double[] angles = rotation.getAngles(RotationOrder.ZXY);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Others representations ====&lt;br /&gt;
See [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Rotation.html Rotation javadoc].&lt;br /&gt;
&lt;br /&gt;
=== Using Rotations ===&lt;br /&gt;
The Rotation is part of the Commons-Math package org.apache.commons.math3.geometry.euclidean.threed.&lt;br /&gt;
&lt;br /&gt;
The Rotation is represented by a rotation quaternion : it is a unit quaternion (a quaternion of norm one).&amp;lt;br&amp;gt;&lt;br /&gt;
The [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Rotation.html Rotation class] represents an algebraic rotation (i.e. a mathematical rotation). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Rotate a vector ====&lt;br /&gt;
&lt;br /&gt;
A rotation is an operator which basically rotates three dimensional [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Vector3D.html vectors] into other three dimensional [{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Vector3D.html vectors] using &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;applyTo()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// vector A&lt;br /&gt;
Vector3D a = new Vector3D(1, 0, 0);&lt;br /&gt;
// build rotation r1&lt;br /&gt;
Vector3D u1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta1 = FastMath.PI / 2. ;&lt;br /&gt;
Rotation r1 = new Rotation(u1, theta1);&lt;br /&gt;
// vector B, image of A by r1&lt;br /&gt;
Vector3D b = r1.applyTo(a);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Compose rotations ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since a rotation is basically a vectorial operator, several rotations can be composed together and the composite operation r = r2 o r1 is also a rotation. r1 is applied before r2 and the operator&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;applyTo()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// build rotation r1&lt;br /&gt;
Vector3D u1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta1 = FastMath.PI / 2. ;&lt;br /&gt;
Rotation r1 = new Rotation(u1, theta1);&lt;br /&gt;
// build rotation r2&lt;br /&gt;
Vector3D u2 = new Vector3D(1, 0, 0);&lt;br /&gt;
double theta2 = FastMath.PI / 2. ;&lt;br /&gt;
Rotation r2 = new Rotation(u2, theta2);&lt;br /&gt;
// build r2 o r1&lt;br /&gt;
Rotation r2_o_r1 = r2.applyTo(r1);&lt;br /&gt;
// vector D, image of A by r2 o r1&lt;br /&gt;
Vector3D d = r2_o_r1.applyTo(a);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Change the basis of a vector ====&lt;br /&gt;
&lt;br /&gt;
The rotation could be used to change the basis of a vector using &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;applyInverseTo()&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Define frame R2 by building the rotation r12 in frame R1&lt;br /&gt;
Vector3D u12_R1 = new Vector3D(1, 1, 1);&lt;br /&gt;
double theta12 = FastMath.PI* 3. / 2.;&lt;br /&gt;
Rotation r12_R1 = new Rotation(u12_R1, theta12);&lt;br /&gt;
// vector A, expressed in R1&lt;br /&gt;
Vector3D a_R1 = new Vector3D(0.5, 0.5, 0);&lt;br /&gt;
// vector A, expressed in R2&lt;br /&gt;
Vector3D a_R2 = r12_R1.applyInverseTo(a_R1);&lt;br /&gt;
        &lt;br /&gt;
// Build rotation r, in R1 frame&lt;br /&gt;
Vector3D u_R1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta = FastMath.PI;&lt;br /&gt;
Rotation r_R1 = new Rotation(u_R1, theta);&lt;br /&gt;
// Vector B, image of A by the rotation r, expressed in R1&lt;br /&gt;
Vector3D b_R1 = r_R1.applyTo(a_R1);&lt;br /&gt;
// Vector B, changed of basis, expressed in R2&lt;br /&gt;
Vector3D b_R2 = r12_R1.applyInverseTo(b_R1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Change the basis of a rotation ====&lt;br /&gt;
&lt;br /&gt;
Let be r a rotation built from the coordinates of its rotation axis. This vector is expressed in a frame &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; ; the rotation is supported only in this frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Let be &amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt; the rotation from &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;R_2&amp;lt;/math&amp;gt;, i.e. the image of the axis &amp;lt;math&amp;gt;x_1&amp;lt;/math&amp;gt; expressed in &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; using the rotation &amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt; is the axis  &amp;lt;math&amp;gt;x_2&amp;lt;/math&amp;gt; expressed in &amp;lt;math&amp;gt;R_2&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt;r_12(x_1) = x_2&amp;lt;/math&amp;gt; with &amp;lt;math&amp;gt;x_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt; expressed in &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The rotation r, changed of basis to be expressed in &amp;lt;math&amp;gt;R_2&amp;lt;/math&amp;gt; is obtained by &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt;.applyTo(r.revert())&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Define frame R2 by building the rotation r12 in frame R1&lt;br /&gt;
Vector3D u12_R1 = new Vector3D(1, 1, 1);&lt;br /&gt;
double theta12 = FastMath.PI* 3. / 2.;&lt;br /&gt;
Rotation r12_R1 = new Rotation(u12_R1, theta12);&lt;br /&gt;
// Build rotation r, in R1 frame&lt;br /&gt;
Vector3D u_R1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta = FastMath.PI;&lt;br /&gt;
Rotation r_R1 = new Rotation(u_R1, theta);&lt;br /&gt;
// Change the basis of r&lt;br /&gt;
Rotation r_R2 = r12_R1.applyTo(r_R1.revert());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using Quaternions ===&lt;br /&gt;
The &amp;lt;code&amp;gt;Quaternion&amp;lt;/code&amp;gt; class provides all elementary operations on quaternions: sum, product, inverse, conjugate, norm, dot product, etc.&lt;br /&gt;
Below are some examples of use:&lt;br /&gt;
&lt;br /&gt;
* Computing the product of two quaternions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Quaternion qA = new Quaternion(qA0,qA1,qA2,qA3);&lt;br /&gt;
Quaternion qB = new Quaternion(qB0,qB1,qB2,qB3);&lt;br /&gt;
Quaternion qProduct = Quaternion.multiply(qA,qB);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Getting the inverse of a quaternion :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Quaternion q = new Quaternion(0,5.1,4,8);&lt;br /&gt;
Quaternion qInverse = q.getInverse();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using Rotations interpolation ===&lt;br /&gt;
&lt;br /&gt;
===== LERP Use case =====&lt;br /&gt;
&lt;br /&gt;
Here is an exemple on how one can compute LERP in Java language using PATRIUS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final Vector3D axis = new Vector3D(1,1,1);&lt;br /&gt;
final Rotation r1 = new Rotation(axis,FastMath.PI/6.);&lt;br /&gt;
final Rotation r2 = new Rotation(axis,FastMath.PI/3.);&lt;br /&gt;
&lt;br /&gt;
final Rotation r = Rotation.lerp(r1, r2, 0.5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then one can retrieve corresponding rotation angle and axis:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final double rangle = r.getAngle();&lt;br /&gt;
final Vector3D raxis = r.getAxis();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Same example given in Scilab using Celestlab macros library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scilab&amp;quot;&amp;gt;&lt;br /&gt;
alpha1 = CL_deg2rad(30.);&lt;br /&gt;
q1 = CL_rot_axAng2quat([1;1;1],alpha1);&lt;br /&gt;
alpha2 = CL_deg2rad(60.);&lt;br /&gt;
q2 = CL_rot_axAng2quat([1;1;1],alpha2);&lt;br /&gt;
q = q1 + 0.5* (q2 - q1);&lt;br /&gt;
q = (1/norm(q))* q&lt;br /&gt;
[axis, angle] = CL_rot_quat2axAng(q)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== SLERP Use example ====&lt;br /&gt;
&lt;br /&gt;
Here is an exemple on how one can compute LERP in Java language using PATRIUS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final Vector3D axis = new Vector3D(1,1,1);&lt;br /&gt;
final Rotation r1 = new Rotation(axis,FastMath.PI/6.);&lt;br /&gt;
final Rotation r2 = new Rotation(axis,FastMath.PI/3.);&lt;br /&gt;
&lt;br /&gt;
final Rotation r = Rotation.slerp(r1, r2, 0.5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then one can retrieve corresponding rotation angle and axis:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final double rangle = r.getAngle();&lt;br /&gt;
final Vector3D raxis = r.getAxis();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Same example given in Scilab using Celestlab macros library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scilab&amp;quot;&amp;gt;&lt;br /&gt;
alpha1 = CL_deg2rad(30.);&lt;br /&gt;
q1 = CL_rot_axAng2quat([1;1;1],alpha1);&lt;br /&gt;
alpha2 = CL_deg2rad(60.);&lt;br /&gt;
q2 = CL_rot_axAng2quat([1;1;1],alpha2);&lt;br /&gt;
q = CL_rot_quatSlerp(q1,q2,.5);&lt;br /&gt;
&lt;br /&gt;
[axis, angle] = CL_rot_quat2axAng(q)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
The relevant classes are :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;Quaternion&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|This class implements quaternions.&lt;br /&gt;
|[{{JavaDoc3.4.1}}/org/apache/commons/math3/complex/Quaternion.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;Rotation&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|This class implements rotations in a three-dimensional space.&lt;br /&gt;
|[{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/Rotation.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;#039;&amp;#039;&amp;#039;RotationOrder&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|This class is a utility representing a rotation order specification for Cardan or Euler angles specification.&lt;br /&gt;
|[{{JavaDoc3.4.1}}/org/apache/commons/math3/geometry/euclidean/threed/RotationOrder.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_3.4.1_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>