<commit_before>= quaternion
:author: 
:revnumber: 
:revdate: 2016/03/17 20:48
:relfileprefix: ../
:imagesdir: ..
ifdef::env-github,env-browser[:outfilesuffix: .adoc]



== Quaternion

See link:http://javadoc.jmonkeyengine.org/com/jme/math/Quaternion.html[Javadoc]


=== Definition

Quaternions define a subset of a hypercomplex number system. Quaternions are defined by (i^2^ = j^2^ = k^2^ = ijk = -1). jME makes use of Quaternions because they allow for compact representations of rotations, or correspondingly, orientations, in 3D space. With only four float values, we can represent an object's orientation, where a rotation matrix would require nine. They also require fewer arithmetic operations for concatenation. 

Additional benefits of the Quaternion is reducing the chance of link:http://en.wikipedia.org/wiki/Gimbal_lock[Gimbal Lock] and allowing for easily interpolation between two rotations (spherical linear interpolation or slerp).

While Quaternions are quite difficult to fully understand, there are an exceeding number of convenience methods to allow you to use them without having to understand the math behind it. Basically, these methods involve nothing more than setting the Quaternion's x,y,z,w values using other means of representing rotations. The Quaternion is then contained in <<jme3/advanced/spatial#,Spatial>> as its local rotation component.

Quaternion *q* has the form

*q* = &lt;_w,x,y,z_&gt; = _w + xi + yj + zk_

or alternatively, it can be written as:

*q* = *s* + *v*, where *s* represents the scalar part corresponding to the w-component of *q*, and *v* represents the vector part of the (x, y, z) components of *q*.

Multiplication of Quaternions uses the distributive law and adheres to the following rules with multiplying the imaginary components (i, j, k):

`i^2^ = j^2^ = k^2^ = -1`+
`ij = -ji = k`+
`jk = -kj = i`+
`ki = -ik = j`

However, Quaternion multiplication is _not_ commutative, so we have to pay attention to order.

*q~1~q~2~* = s~1~s~2~ - *v~1~* dot *v~2~* + s~1~*v~2~* + s~2~*v~1~* + *v~1~* X *v~2~*

Quaternions also have conjugates where the conjugate of *q* is (s - *v*)

These basic operations allow us to convert various rotation representations to Quaternions.


=== Angle Axis

You might wish to represent your rotations as Angle Axis pairs. That is, you define a axis of rotation and the angle with which to rotate about this axis. Quaternion defines a method `fromAngleAxis` (and `fromAngleNormalAxis`) to create a Quaternion from this pair. This is acutally used quite a bit in jME demos to continually rotate objects. You can also obtain a Angle Axis rotation from an existing Quaternion using `toAngleAxis`.


==== Example - Rotate a Spatial Using fromAngleAxis

[source,java]
----

//rotate about the Y-Axis by approximately 1 pi
Vector3f axis = Vector3f.UNIT_Y; // this equals (0, 1, 0) and does not require to create a new object
float angle = 3.14f;
s.getLocalRotation().fromAngleAxis(angle, axis);

----


=== Three Angles

You can also represent a rotation by defining three angles. The angles represent the rotation about the individual axes. Passing in a three-element array of floats defines the angles where the first element is X, second Y and third is Z. The method provided by Quaternion is `fromAngles` and can also fill an array using `toAngles`


==== Example - Rotate a Spatial Using fromAngles

[source,java]
----

//rotate 1 radian on the x, 3 on the y and 0 on z
float[] angles = {1, 3, 0};
s.getLocalRotation().fromAngles(angles);

----


=== Three Axes

If you have three axes that define your rotation, where the axes define the left axis, up axis and directional axis respectively) you can make use of `fromAxes` to generate the Quaternion. It should be noted that this will generate a new <<jme3/matrix#,Matrix>> object that is then garbage collected, thus, this method should not be used if it will be called many times. Again, `toAxes` will populate a <<jme3/vector#,Vector3f>> array.


==== Example - Rotate a Spatial Using fromAxes

[source,java]
----

//rotate a spatial to face up ~45 degrees
Vector3f[] axes = new Vector3f[3];
axes[0] = new Vector3f(-1, 0, 0); //left
axes[1] = new Vector3f(0, 0.5f, 0.5f); //up
axes[2] = new Vector3f(0, 0.5f, 0.5f); //dir

s.getLocalRotation().fromAxes(axes);

----


=== Rotation Matrix

Commonly you might find yourself with a <<jme3/matrix#,Matrix>> defining a rotation. In fact, it's very common to contain a rotation in a <<jme3/matrix#,Matrix>> create a Quaternion, rotate the Quaternion, and then get the <<jme3/matrix#,Matrix>> back. Quaternion contains a `fromRotationMatrix` method that will create the appropriate Quaternion based on the give <<jme3/matrix#,Matrix>>. The `toRotationMatrix` will populate a given <<jme3/matrix#,Matrix>>.


==== Example - Rotate a Spatial Using a Rotation Matrix

[source,java]
----


Matrix3f mat = new Matrix3f();<commit_msg>Fixed broken link and remove unnecessary links.<commit_after>= quaternion
:author:
:revnumber:
:revdate: 2016/03/17 20:48
:relfileprefix: ../
:imagesdir: ..
ifdef::env-github,env-browser[:outfilesuffix: .adoc]



== Quaternion

See link:https://javadoc.jmonkeyengine.org/index.html?com/jme3/math/Quaternion.html[Javadoc]


=== Definition

Quaternions define a subset of a hypercomplex number system. Quaternions are defined by (i^2^ = j^2^ = k^2^ = ijk = -1). jME makes use of Quaternions because they allow for compact representations of rotations, or correspondingly, orientations, in 3D space. With only four float values, we can represent an object's orientation, where a rotation matrix would require nine. They also require fewer arithmetic operations for concatenation.

Additional benefits of the Quaternion is reducing the chance of link:http://en.wikipedia.org/wiki/Gimbal_lock[Gimbal Lock] and allowing for easily interpolation between two rotations (spherical linear interpolation or slerp).

While Quaternions are quite difficult to fully understand, there are an exceeding number of convenience methods to allow you to use them without having to understand the math behind it. Basically, these methods involve nothing more than setting the Quaternion's x,y,z,w values using other means of representing rotations. The Quaternion is then contained in <<jme3/advanced/spatial#,Spatial>> as its local rotation component.

Quaternion *q* has the form

*q* = &lt;_w,x,y,z_&gt; = _w + xi + yj + zk_

or alternatively, it can be written as:

*q* = *s* + *v*, where *s* represents the scalar part corresponding to the w-component of *q*, and *v* represents the vector part of the (x, y, z) components of *q*.

Multiplication of Quaternions uses the distributive law and adheres to the following rules with multiplying the imaginary components (i, j, k):

`i^2^ = j^2^ = k^2^ = -1`+
`ij = -ji = k`+
`jk = -kj = i`+
`ki = -ik = j`

However, Quaternion multiplication is _not_ commutative, so we have to pay attention to order.

*q~1~q~2~* = s~1~s~2~ - *v~1~* dot *v~2~* + s~1~*v~2~* + s~2~*v~1~* + *v~1~* X *v~2~*

Quaternions also have conjugates where the conjugate of *q* is (s - *v*)

These basic operations allow us to convert various rotation representations to Quaternions.


=== Angle Axis

You might wish to represent your rotations as Angle Axis pairs. That is, you define a axis of rotation and the angle with which to rotate about this axis. Quaternion defines a method `fromAngleAxis` (and `fromAngleNormalAxis`) to create a Quaternion from this pair. This is acutally used quite a bit in jME demos to continually rotate objects. You can also obtain a Angle Axis rotation from an existing Quaternion using `toAngleAxis`.


==== Example - Rotate a Spatial Using fromAngleAxis

[source,java]
----

//rotate about the Y-Axis by approximately 1 pi
Vector3f axis = Vector3f.UNIT_Y; // this equals (0, 1, 0) and does not require to create a new object
float angle = 3.14f;
s.getLocalRotation().fromAngleAxis(angle, axis);

----


=== Three Angles

You can also represent a rotation by defining three angles. The angles represent the rotation about the individual axes. Passing in a three-element array of floats defines the angles where the first element is X, second Y and third is Z. The method provided by Quaternion is `fromAngles` and can also fill an array using `toAngles`


==== Example - Rotate a Spatial Using fromAngles

[source,java]
----

//rotate 1 radian on the x, 3 on the y and 0 on z
float[] angles = {1, 3, 0};
s.getLocalRotation().fromAngles(angles);

----


=== Three Axes

If you have three axes that define your rotation, where the axes define the left axis, up axis and directional axis respectively) you can make use of `fromAxes` to generate the Quaternion. It should be noted that this will generate a new <<jme3/matrix#,Matrix>> object that is then garbage collected, thus, this method should not be used if it will be called many times. Again, `toAxes` will populate a <<jme3/vector#,Vector3f>> array.


==== Example - Rotate a Spatial Using fromAxes

[source,java]
----

//rotate a spatial to face up ~45 degrees
Vector3f[] axes = new Vector3f[3];
axes[0] = new Vector3f(-1, 0, 0); //left
axes[1] = new Vector3f(0, 0.5f, 0.5f); //up
axes[2] = new Vector3f(0, 0.5f, 0.5f); //dir

s.getLocalRotation().fromAxes(axes);

----


=== Rotation Matrix

Commonly you might find yourself with a <<jme3/matrix#,Matrix>> defining a rotation. In fact, it's very common to contain a rotation in a Matrix, create a Quaternion, rotate the Quaternion, and then get the Matrix back. Quaternion contains a `fromRotationMatrix` method that will create the appropriate Quaternion based on the given Matrix. The `toRotationMatrix` will populate a given Matrix.


==== Example - Rotate a Spatial Using a Rotation Matrix

[source,java]
----


Matrix3f mat = new Matrix3f();
{'fraction_non_alphanumeric': 0.09959183673469388, 'fraction_numerical': 0.01663265306122449, 'mean_word_length': 4.367469879518072, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2874065', 'n_tokens_mistral': 3108, 'n_tokens_neox': 2880, 'n_words': 1345}