All Classes Files Functions Variables Typedefs Pages
QuaternionCore.hpp
Go to the documentation of this file.
1 #pragma once
2 
11 #include <cmath>
12 
13 namespace lumina{
14 
24 template <typename T>
25 struct Quaternion {
26  T w, x, y, z;
27 
28  Quaternion(T w, T x, T y, T z)
29  : w(w), x(x), y(y), z(z) {
30  }
31 
32  Quaternion()
33  : Quaternion(static_cast<T>(0),
34  static_cast<T>(0),
35  static_cast<T>(0),
36  static_cast<T>(0)) {
37  }
38 
39  /***** Set operations *********************************************************/
40  bool operator==(const Quaternion<T>& other) const {
41  return
42  this->w == other.w &&
43  this->x == other.x &&
44  this->y == other.y &&
45  this->z == other.z;
46  }
47 
48  bool operator!=(const Quaternion<T>& other) const {
49  return !(*this == other);
50  }
51 
52  /***** Vector space operations ************************************************/
53  Quaternion<T> operator+() const {
54  return *this;
55  }
56 
57  Quaternion<T> operator-() const {
58  return Quaternion(-w, -x, -y, -z);
59  }
60 
61  template <typename OT>
62  Quaternion<T>& operator+=(const Quaternion<OT> q) {
63  this->w += q.w;
64  this->x += q.x;
65  this->y += q.y;
66  this->z += q.z;
67 
68  return *this;
69  }
70 
71  template <typename OT>
72  Quaternion<T>& operator-=(const Quaternion<OT>& q) {
73  return *this += -q;
74  }
75 
76  template <typename S>
77  Quaternion<T>& operator*=(S s) {
78  this->w *= s;
79  this->x *= s;
80  this->y *= s;
81  this->z *= s;
82 
83  return *this;
84  }
85 
86  template <typename S>
87  Quaternion<T>& operator/=(S s) {
88  return *this *= 1/s;
89  }
90 
91  /***** Properties of the Banach space *****************************************/
92  T lengthSquared() const {
93  return w*w + x*x + y*y + z*z;
94  }
95 
96  template <typename Tout = decltype(std::sqrt(T(0)))>
97  Tout length() const {
98  return static_cast<Tout>(std::sqrt(lengthSquared()));
99  }
100 
101  Quaternion<T>& normalize() {
102  auto lensq = lengthSquared();
103  if(lensq != 0) {
104  *this /= std::sqrt(lensq);
105  }
106  return *this;
107  }
108 
109  Quaternion<T> normalized() const {
110  return Quaternion<T>(*this).normalize();
111  }
112 
113  /***** Ring structure *********************************************************/
114  template <typename OT>
115  Quaternion<T>& operator*=(const Quaternion<OT>& q) {
116  return *this = Quaternion<T>(this->w*q.w - this->x*q.x - this->y*q.y - this->z*q.z,
117  this->w*q.x + this->x*q.w + this->y*q.z - this->z*q.y,
118  this->w*q.y - this->x*q.z + this->y*q.w + this->z*q.x,
119  this->w*q.z + this->x*q.y - this->y*q.x + this->z*q.w);
120  }
121 
122  /***** Division algebra structure *********************************************/
123  Quaternion<T>& invert() {
124  auto lensq = lengthSquared();
125  if(lensq != 0) {
126  (*this).conjugate() /= lensq;
127  }
128  return *this;
129  }
130 
131  Quaternion<T> inverse() {
132  return Quaternion<T>(*this).invert();
133  }
134 
135  Quaternion<T>& conjugate() {
136  this->x = -this->x;
137  this->y = -this->y;
138  this->z = -this->z;
139 
140  return *this;
141  }
142 
143  Quaternion<T> conjugated() {
144  return Quaternion<T>(*this).conjugate();
145  }
146 };
147 
148 // =============================================================================
149 // Definition of non member functions for Vector
150 // =============================================================================
151 
152 /***** Vector space operations ************************************************/
153 template <typename T1, typename T2>
154 auto operator+(const Quaternion<T1>& q1, const Quaternion<T2>& q2)
157  return out += q2;
158 }
159 
160 template <typename T1, typename T2>
161 auto operator-(const Quaternion<T1>& q1, const Quaternion<T2>& q2)
162  -> Quaternion<decltype(T1(0) - T2(0))> {
163  return q1 + (-q2);
164 }
165 
166 template <typename T, typename S>
167 auto operator*(const Quaternion<T>& q, S s)
168  -> Quaternion<decltype(T(0) * S(0))> {
169  Quaternion<decltype(T(0) * S(0))> out(q);
170  return out *= s;
171 }
172 
173 template <typename T, typename S>
174 auto operator*(S s, const Quaternion<T>& q)
175  -> Quaternion<decltype(T(0) * S(0))> {
176  return q * s;
177 }
178 
179 template <typename T, typename S>
180 auto operator/(const Quaternion<T>& q, S s)
181  -> Quaternion<decltype(T(0) / S(0))> {
182  return q * (1/s);
183 }
184 
185 template <typename T, typename S>
186 auto operator/(S s, const Quaternion<T>& q)
187  -> Quaternion<decltype(T(0) / S(0))> {
188  return s * q.inverse();
189 }
190 
191 }
Represents the hamilton ring H(T) for an arbitrary type T.
Definition: QuaternionCore.hpp:25