Cafu Engine
Angles.hpp
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
6 
7 #ifndef CAFU_MATH_ANGLES_HPP_INCLUDED
8 #define CAFU_MATH_ANGLES_HPP_INCLUDED
9 
10 #include "Vector3.hpp"
11 
12 
13 namespace cf
14 {
15  namespace math
16  {
17  template<class T> class Matrix3x3T;
18  template<class T> class QuaternionT;
19 
20 
21  /*
22  * TODO: AnglesT should no longer derive from Vector3T, but rather have a private Vector3T member.
23  * Then, AnglesT should only expose a Heading, Pitch and Bank interface, and nothing with
24  * x, y or z, so that the meaning of things is always clear.
25  */
26 
27  /*
28  * TODO: Some tests would be nice, e.g. these two are enough for testing all combinations:
29  * assert(TestAngles == AnglesT(Matrix3x3T(QuaternionT(TestAngles))))
30  * assert(TestAngles == AnglesT(QuaternionT(Matrix3x3T(TestAngles))))
31  */
32 
33  /// This class represents a triple of angles.
34  /// The class keeps the angles in degrees, not in radians.
35  ///
36  /// The angles are typically used to describe an orientation. Generally, the orientation is achieved
37  /// by composing three elemental rotations about the principal axes by the given angles.
38  /// For this purpose, all related code in Cafu (e.g. the matrix and quaternion classes) uses the
39  /// following conventions:
40  ///
41  /// - As everywhere in Cafu, a right-handed coordinate system is used: In world space, the x-axis
42  /// points right, the y-axis points forward, and the z-axis points up.
43  /// However, note that our entities and cameras, as detailed below, "look along" their x-axis,
44  /// so that for them, the x-axis points forward, the y-axis points left, and the z-axis points up.
45  /// It is this orientation that the following definitions of angles refer to.
46  ///
47  /// - The rotations are done
48  /// - first about the z-axis (by the "heading" or "yaw" angle),
49  /// - then about the rotated y-axis (by the "pitch" angle),
50  /// - then about the rotated x-axis (by the "bank" or "roll" angle).
51  /// This order is explained in greater detail in the references listed below.
52  ///
53  /// - Positive angles rotate counter-clockwise (the "right-hand rule").
54  ///
55  /// - North is along the x-axis, West is along the y-axis.
56  /// This does *not* follow the compase-rose analogy (that we had normally preferred), where North is
57  /// along the y-axis, East is along the x-axis, and positive rotation is clockwise, but was accepted
58  /// for conformance with the broader conventions (e.g. DIN 9300) given in the references below.
59  ///
60  /// References (in German, as the English editions don't have the relevant math):
61  ///
62  /// - http://de.wikipedia.org/wiki/Eulersche_Winkel
63  /// Especially section "z, y', x''-Konvention in der Fahrzeugtechnik" has a very well explained
64  /// derivation of a rotation matrix from Euler angles. Note, however, that the resulting matrix
65  /// transforms from world-to-model space, whereas we're more interested in the transpose, in order
66  /// to transform from model-to-world space.
67  ///
68  /// - http://de.wikipedia.org/wiki/Roll-Nick-Gier-Winkel
69  /// Section "Z, Y', X'' Konvention" complements the above, where the model-to-world space matrix
70  /// is readily given, and the math for converting back to Euler angles as well.
71  template<class T> class AnglesT : public Vector3T<T>
72  {
73  public:
74 
75  /// The default constructor. It initializes all angles to zero.
76  AnglesT() : Vector3T<T>() { }
77 
78  /// This constructor initializes the angles from x_, y_ and z_ respectively.
79  AnglesT(T x_, T y_, T z_) : Vector3T<T>(x_, y_, z_) { }
80 
81  /// A constructor for initializing an Angles instance from a Vector3T.
82  AnglesT(const Vector3T<T>& v) : Vector3T<T>(v) { }
83 
84  /// Constructs a set of angles that describe the same orientation as the given matrix.
85  AnglesT(const Matrix3x3T<T>& M);
86 
87  /// Constructs a set of angles that describe the same orientation as the given quaternion.
88  AnglesT(const QuaternionT<T>& Quat);
89 
90 
91  // The "this->" cannot be omitted here, or else g++ 4.2.3 complains that "'x' was not declared in this scope".
92  T& pitch() { return this->x; } ///< Provides the alias for the angle of rotation around the x-axis. TODO: The impl. should actually use y, not x here!
93  const T& pitch() const { return this->x; } ///< Provides the alias for the angle of rotation around the x-axis.
94 
95  T& roll() { return this->y; } ///< Provides the alias for the angle of rotation around the y-axis. TODO: The impl. should actually use x, not y here!
96  const T& roll() const { return this->y; } ///< Provides the alias for the angle of rotation around the y-axis.
97 
98  T& yaw() { return this->z; } ///< Provides the alias for the angle of rotation around the z-axis.
99  const T& yaw() const { return this->z; } ///< Provides the alias for the angle of rotation around the z-axis.
100 
101 
102  static const double PI; ///< This is PI.
103  static T RadToDeg(const T Angle) { return Angle*T(180.0/PI); } ///< Converts the given angle from radians to degrees.
104  static T DegToRad(const T Angle) { return Angle*T(PI/180.0); } ///< Converts the given angle from degrees to radians.
105 
106 
107  private:
108 
109  void Init(const Matrix3x3T<T>& M);
110  };
111 
112 
113  /// Typedef for an AnglesT of floats.
114  typedef AnglesT<float> AnglesfT;
115 
116  /// Typedef for an Angles of doubles.
117  typedef AnglesT<double> AnglesdT;
118  }
119 }
120 
121 #endif
T & yaw()
Provides the alias for the angle of rotation around the z-axis.
Definition: Angles.hpp:98
This class represents a triple of angles.
Definition: Angles.hpp:71
T & roll()
Provides the alias for the angle of rotation around the y-axis. TODO: The impl. should actually use x...
Definition: Angles.hpp:95
static T DegToRad(const T Angle)
Converts the given angle from degrees to radians.
Definition: Angles.hpp:104
AnglesT(const Vector3T< T > &v)
A constructor for initializing an Angles instance from a Vector3T.
Definition: Angles.hpp:82
T y
The y-component of this vector.
Definition: Vector3.hpp:41
T & pitch()
Provides the alias for the angle of rotation around the x-axis. TODO: The impl. should actually use y...
Definition: Angles.hpp:92
This class represents a polymorphic 3-dimensional vector.
Definition: Misc.hpp:11
const T & roll() const
Provides the alias for the angle of rotation around the y-axis.
Definition: Angles.hpp:96
AnglesT()
The default constructor. It initializes all angles to zero.
Definition: Angles.hpp:76
AnglesT(T x_, T y_, T z_)
This constructor initializes the angles from x_, y_ and z_ respectively.
Definition: Angles.hpp:79
const T & yaw() const
Provides the alias for the angle of rotation around the z-axis.
Definition: Angles.hpp:99
const T & pitch() const
Provides the alias for the angle of rotation around the x-axis.
Definition: Angles.hpp:93
static const double PI
This is PI.
Definition: Angles.hpp:102
T z
The z-component of this vector.
Definition: Vector3.hpp:42
This class represents a quaternion.
Definition: Angles.hpp:18
T x
The x-component of this vector.
Definition: Vector3.hpp:40
static T RadToDeg(const T Angle)
Converts the given angle from radians to degrees.
Definition: Angles.hpp:103
This class represents a generic 3x3 matrix.
Definition: Angles.hpp:17