<?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_4.13_Rotations_and_quaternions</id>
	<title>User Manual 4.13 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_4.13_Rotations_and_quaternions"/>
	<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Rotations_and_quaternions&amp;action=history"/>
	<updated>2026-04-04T21:40:42Z</updated>
	<subtitle>Historique des versions pour cette page sur le wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Rotations_and_quaternions&amp;diff=3580&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_4.13_Rotations_and_quaternions&amp;diff=3580&amp;oldid=prev"/>
		<updated>2023-12-19T13:53:40Z</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;
| Patrius &lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/package-summary.html Package fr.cnes.sirius.patrius.math.geometry.euclidean.threed]&lt;br /&gt;
|-&lt;br /&gt;
| Patrius&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/math/complex/package-summary.html Package fr.cnes.sirius.patrius.math.complex]&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 packages :&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.complex&amp;lt;/code&amp;gt; for the Quaternion class.&lt;br /&gt;
* &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.cnesmerge.geometry.euclidean.threed&amp;lt;/code&amp;gt; for the Rotation class.&lt;br /&gt;
* &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.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 math package fr.cnes.sirius.patrius.math.geometry.euclidean.threed.&lt;br /&gt;
&lt;br /&gt;
The Rotation is represented by a [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/math/complex/Quaternion.html quaternion]: it is a unit quaternion (a quaternion of norm one).&amp;lt;br&amp;gt;&lt;br /&gt;
The [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/math/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;
=== 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;
&amp;lt;center&amp;gt;&lt;br /&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;&lt;br /&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;
&amp;lt;center&amp;gt;&lt;br /&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;&lt;br /&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;
&amp;lt;center&amp;gt;&lt;br /&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;&lt;br /&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;
====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;&lt;br /&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;&lt;br /&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;&lt;br /&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;&lt;br /&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;
&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.&amp;lt;br&amp;gt;&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;&lt;br /&gt;
&amp;lt;/center&amp;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;
&amp;lt;center&amp;gt;&lt;br /&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;
=== Rotation 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.&amp;lt;br&amp;gt;&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 [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/math/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. 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.&lt;br /&gt;
The user can also get the Cardan or Euler angles by giving a sequence, using the getAngles(RotationOrder) method.&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 [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Rotation.html Rotation javadoc].&lt;br /&gt;
&lt;br /&gt;
=== Using Rotations ===&lt;br /&gt;
The Rotation is part of the package fr.cnes.sirius.patrius.math&lt;br /&gt;
.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 [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Rotation.html Rotation class] represents an algebraic rotation (i.e. a mathematical rotation). &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 [{{JavaDoc4.13}}//fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Vector3D.html vectors] into other three dimensional [{{JavaDoc4.13}}//fr/cnes/sirius/patrius/math/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;
&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;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/math/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;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/math/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;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/RotationOrder.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.13_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>