Easy3D 2.5.3
Quat< FT > Class Template Reference

The Quaternion class represents 3D rotations and orientations. More...

#include <easy3d/core/quat.h>

Public Types

typedef Vec< 3, FT > Vec3
 
typedef Quat< FT > thisclass
 

Public Member Functions

 Quat ()
 Default constructor, builds an identity rotation.
 
 Quat (const Mat3< FT > &m)
 Constructor from rotation matrix. See also set_from_rotation_matrix().
 
 Quat (const Vec3 &axis, FT angle)
 Constructor from rotation axis (non null) and angle (in radians). See also set_axis_angle().
 
 Quat (const Vec3 &from, const Vec3 &to)
 Constructs a quaternion that will rotate from the from direction to the to direction. More...
 
 Quat (FT q0, FT q1, FT q2, FT q3)
 Constructor from the four values of a Quaternion. First three values are axis*std::sin(angle/2) and the last one is std::cos(angle/2). More...
 
 Quat (const thisclass &Q)
 
Quatoperator= (const thisclass &Q)
 
void set_axis_angle (const Vec3 &axis, FT angle)
 
void set_value (FT q0, FT q1, FT q2, FT q3)
 
void set_from_rotation_matrix (const Mat3< FT > &m)
 Set the Quaternion from a (supposedly correct) 3x3 rotation matrix. The matrix is expressed in European format: its three columns are the images by the rotation of the three vectors of an orthogonal basis. See http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm.
 
void set_from_rotated_basis (const Vec3 &X, const Vec3 &Y, const Vec3 &Z)
 Set a Quaternion from the three axis of a rotated frame. It actually fills the three columns of a matrix with these rotated basis vectors and calls this method.
 
Vec3 axis () const
 Returns the normalized axis direction of the rotation represented by the Quaternion. It is null for an identity Quaternion. See also angle() and get_axis_angle().
 
FT angle () const
 Returns the angle (in radians) of the rotation represented by the Quaternion. This value is always in the range [0-pi]. Larger rotational angles are obtained by inverting the axis() direction. See also axis() and get_axis_angle().
 
void get_axis_angle (Vec3 &axis, FT &angle) const
 Returns the axis vector and the angle (in radians) of the rotation represented by the Quaternion.
 
FT operator[] (int i) const
 Bracket operator, with a constant return value. i must range in [0..3].
 
FT & operator[] (int i)
 Bracket operator returning an l-value. i must range in [0..3].
 
Quatoperator*= (const Quat &q)
 Quaternion rotation is composed with q. See operator*(), since this is equivalent to this = this * q. More...
 
Vec3 rotate (const Vec3 &v) const
 Returns the image of v by the Quaternion rotation. More...
 
Vec3 inverse_rotate (const Vec3 &v) const
 Returns the image of v by the Quaternion inverse() rotation. rotate() performs an inverse transformation. Same as inverse().rotate(v).
 
Quat inverse () const
 Inversion. Returns the inverse Quaternion (inverse rotation). Result has a negated axis() direction and the same angle(). A composition (see operator*()) of a Quaternion and its inverse() results in an identity function. Use invert() to actually modify the Quaternion.
 
void invert ()
 Inverses the Quaternion (same rotation angle(), but negated axis()). More...
 
void negate ()
 Negates all the coefficients of the Quaternion. This results in an other representation of the same rotation (opposite rotation angle, but with a negated axis direction: the two cancel out). However, note that the results of axis() and angle() are unchanged after a call to this method since angle() always returns a value in [0,pi]. This method is mainly useful for Quaternion interpolation, so that the spherical interpolation takes the shortest path on the unit sphere. See slerp() for details.
 
FT length () const
 Return the length of the quaternion.
 
FT normalize ()
 Normalizes the Quaternion coefficients. This method should not need to be called since we only deal with unit Quaternions. This is however useful to prevent numerical drifts, especially with small rotational increments. More...
 
Quat normalized () const
 Returns a normalized version of the Quaternion. More...
 
Mat4< FT > matrix () const
 Returns the Quaternion associated 4x4 rotation matrix. Use glMultMatrixf(q.matrix()) to apply the rotation represented by Quaternion q to the current OpenGL matrix.
 
Mat4< FT > inverse_matrix () const
 Returns the associated 4x4 inverse rotation matrix. This is simply the matrix() of the inverse().
 
Quat log ()
 Returns the logarithm of the Quaternion. See also exp().
 
Quat exp ()
 Returns the exponential of the Quaternion. See also log().
 

Static Public Member Functions

static Quat slerp (const Quat< FT > &a, const Quat< FT > &b, FT t, bool allowFlip=true)
 Slerp(Spherical Linear intERPolation) interpolation. Returns the slerp interpolation of Quaternions a and b, at time t. t should range in [0,1]. Result is a when t=0 and b when t=1. When allowFlip is true (default) the slerp interpolation will always use the "shortest path" between the Quaternions' orientations, by "flipping" the source Quaternion if needed (see negate()). More...
 
static Quat squad (const Quat< FT > &a, const Quat< FT > &tgA, const Quat< FT > &tgB, const Quat< FT > &b, FT t)
 Returns the slerp interpolation of the two Quaternions a and b, at time t, using tangents tgA and tgB. The resulting Quaternion is "between" a and b (result is a when t=0 and b for t=1). Use squad_tangent() to define the Quaternion tangents tgA and tgB.
 
static FT dot (const Quat< FT > &a, const Quat< FT > &b)
 Returns the "dot" product of a and b: a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3].
 
static Quat ln_dif (const Quat< FT > &a, const Quat< FT > &b)
 Returns log(a. inverse() * b). Useful for squad_tangent().
 
static Quat squad_tangent (const Quat< FT > &before, const Quat< FT > &center, const Quat< FT > &after)
 Returns a tangent Quaternion for center, defined by before and after Quaternions. Useful for smooth spline interpolation of Quaternion with squad() and slerp().
 
static thisclass random_quat ()
 Returns a random unit Quaternion. You can create a randomly directed unit vector using: More...
 

Public Attributes

union {
   struct {
      FT   x
 
      FT   y
 
      FT   z
 
      FT   w
 
   } 
 
   FT   _q [4]
 
}; 
 

Friends

Quat operator* (const Quat &a, const Quat &b)
 Returns the composition of the a and b rotations. The order is important. When applied to a Vec v (see operator*(const Quaternion&, const Vec&) and rotate()) the resulting Quaternion acts as if b was applied first and then a was applied. This is obvious since the image v' of v by the composited rotation satisfies: v'= (a*b) * v = a * (b*v) Note that a*b usually differs from b*a. More...
 
Vec3 operator* (const Quat &q, const Vec3 &v)
 Returns the image of v by the rotation q. Same as q.rotate(v). More...
 

Detailed Description

template<typename FT>
class easy3d::Quat< FT >

The Quaternion class represents 3D rotations and orientations.

The Quaternion is an appropriate (although not very intuitive) representation for 3D rotations and orientations. Many tools are provided to ease the definition of a Quaternion: see constructors, set_axis_angle(), set_from_rotation_matrix(), set_from_rotated_basis().

You can apply the rotation represented by the Quaternion to 3D points using rotate() and inverse_rotate().

You can apply the Quaternion q rotation to the OpenGL matrices using glMultMatrixd(q.matrix()); which is equivalent to glRotate(q.angle()*180.0/M_PI, q.axis().x, q.axis().y, q.axis().z);

Internal representation The internal representation of a Quaternion is a set of 4 numbers, [x y z w], which represents rotations the following way: x = axis.x * std::sin(angle / 2) y = axis.y * std::sin(angle / 2) z = axis.z * std::sin(angle / 2) w = std::cos(angle / 2) \NOTE:

  • the angle is in radians and the axis is a unit vector.
  • certain implementations place the cosine term in the first position (instead of last).

A Quaternion is always normalized, so that its inverse() is actually its conjugate.

Euler angles VS Quaternion

Euler angles are the easiest way to represent rotation. This representation simply stores the three rotation angles around the X, Y and Z axes. These 3 rotations are then applied successively, usually in this order: first Y, then Z, then X (but not necessarily). Using a different order yields different results. Euler angles are usually used to set a character's orientation since game characters only rotate on the vertical axis. Therefore, it is easier to write, understand and maintain "float direction" than 3 different orientations. Another good use of Euler angles is an FPS camera: you have one angle for heading (Y), and one for up/down (X). However, when things get more complex, Euler angle will be hard to work with, eg.,:

  • Interpolating smoothly between 2 orientations is hard. Naively interpolating the X, Y, and Z angles will be ugly.
  • Applying several rotations is complicated and unprecise: you have to compute the final rotation matrix, and guess the Euler angles from this matrix.
  • A well-known problem, the "Gimbal Lock", will sometimes block your rotations, and other singularities which will flip your model upside-down.
  • Different angles make the same rotation (-180 and 180 degrees, for instance)
  • It is a mess - as said above, usually the right order is YZX, but if you also use a library with a different order, you'll be in trouble.
  • Some operations are complicated, e.g., rotation of N degrees around a specific axis. Quaternions are a tool to represent rotations, which solves these problems.

Constructor & Destructor Documentation

◆ Quat() [1/3]

Quat ( const Vec3 from,
const Vec3 to 
)

Constructs a quaternion that will rotate from the from direction to the to direction.

Note
This rotation is not uniquely defined. The selected axis is usually orthogonal to from and to, minimizing the rotation angle. This method is robust and can handle small or almost identical vectors.

◆ Quat() [2/3]

Quat ( FT  q0,
FT  q1,
FT  q2,
FT  q3 
)
inline

Constructor from the four values of a Quaternion. First three values are axis*std::sin(angle/2) and the last one is std::cos(angle/2).

Attention
The identity Quaternion is Quat(0,0,0,1) and not Quat(0,0,0,0) (which is not unitary). The default Quat() creates such identity Quaternion.

◆ Quat() [3/3]

Quat ( const thisclass Q)
inline

brief Copy constructor.

Member Function Documentation

◆ invert()

void invert ( )
inline

Inverses the Quaternion (same rotation angle(), but negated axis()).

See also
also inverse().

◆ normalize()

FT normalize ( )
inline

Normalizes the Quaternion coefficients. This method should not need to be called since we only deal with unit Quaternions. This is however useful to prevent numerical drifts, especially with small rotational increments.

See also
normalized().

◆ normalized()

Quat normalized ( ) const
inline

Returns a normalized version of the Quaternion.

See also
normalize().

◆ operator*=()

Quat & operator*= ( const Quat< FT > &  q)
inline

Quaternion rotation is composed with q. See operator*(), since this is equivalent to this = this * q.

Note
For efficiency reasons, the resulting Quaternion is not normalized. You may normalize() it after each application in case of numerical drift.

◆ operator=()

Quat & operator= ( const thisclass Q)
inline

brief Equal operator.

◆ random_quat()

Quat< FT > random_quat
static

Returns a random unit Quaternion. You can create a randomly directed unit vector using:

Vec randomDir = Quat::random_quat() * Vec(1.0, 0.0, 0.0); // or any other Vec
static thisclass random_quat()
Returns a random unit Quaternion. You can create a randomly directed unit vector using:
Definition: quat.h:742
Note
This function uses rand() to create pseudo-random numbers and the random number generator can be initialized using srand().

◆ rotate()

Quat< FT >::Vec3 rotate ( const Vec3 v) const

Returns the image of v by the Quaternion rotation.

See also
inverse_rotate() and operator*(const Quat&, const Vec&).

◆ set_axis_angle()

void set_axis_angle ( const Vec3 axis,
FT  angle 
)

brief Sets the Quaternion as a rotation of axis and angle (in radians). axis does not need to be normalized. A null axis will result in an identity Quaternion.

◆ set_value()

void set_value ( FT  q0,
FT  q1,
FT  q2,
FT  q3 
)
inline

brief Sets the Quaternion value.

◆ slerp()

Quat< FT > slerp ( const Quat< FT > &  a,
const Quat< FT > &  b,
FT  t,
bool  allowFlip = true 
)
static

Slerp(Spherical Linear intERPolation) interpolation. Returns the slerp interpolation of Quaternions a and b, at time t. t should range in [0,1]. Result is a when t=0 and b when t=1. When allowFlip is true (default) the slerp interpolation will always use the "shortest path" between the Quaternions' orientations, by "flipping" the source Quaternion if needed (see negate()).

Interpolate between 2 quaternions

Friends And Related Function Documentation

◆ operator* [1/2]

Quat operator* ( const Quat< FT > &  a,
const Quat< FT > &  b 
)
friend

Returns the composition of the a and b rotations. The order is important. When applied to a Vec v (see operator*(const Quaternion&, const Vec&) and rotate()) the resulting Quaternion acts as if b was applied first and then a was applied. This is obvious since the image v' of v by the composited rotation satisfies: v'= (a*b) * v = a * (b*v) Note that a*b usually differs from b*a.

Attention
For efficiency reasons, the resulting Quaternion is not normalized. Use normalize() in case of numerical drift with small rotation composition.

◆ operator* [2/2]

Vec3 operator* ( const Quat< FT > &  q,
const Vec3 v 
)
friend

Returns the image of v by the rotation q. Same as q.rotate(v).

See also
rotate() and inverse_rotate().

The documentation for this class was generated from the following files: