Hermes
quaternion.h
Go to the documentation of this file.
1 
32 
33 #ifndef HERMES_HERMES_GEOMETRY_QUATERNION_H
34 #define HERMES_HERMES_GEOMETRY_QUATERNION_H
35 
37 
38 namespace hermes {
39 
40 // *********************************************************************************************************************
41 // Quaternion
42 // *********************************************************************************************************************
45 template<typename T>
46 class Quaternion {
47  static_assert(std::is_same<T, f32>::value || std::is_same<T, f64>::value ||
48  std::is_same<T, Interval<f32>>::value || std::is_same<T, Interval<f64>>::value,
49  "Quaternion must hold a float type!");
50 public:
51  // *******************************************************************************************************************
52  // STATIC METHODS
53  // *******************************************************************************************************************
57  return {{}, 1};
58  }
59  // *******************************************************************************************************************
60  // FRIEND FUNCTIONS
61  // *******************************************************************************************************************
62  // *******************************************************************************************************************
63  // CONSTRUCTORS
64  // *******************************************************************************************************************
72  HERMES_DEVICE_CALLABLE Quaternion(T x, T y, T z, T w) : v(x, y, z), r(w) {}
79  // assignment
80  // *******************************************************************************************************************
81  // OPERATORS
82  // *******************************************************************************************************************
83  // assignment
84  // access
89  HERMES_DEVICE_CALLABLE const T &operator[](int i) const { return (&v[0])[i]; }
94  HERMES_DEVICE_CALLABLE T &operator[](int i) { return (&v[0])[i]; }
95  // arithmetic
96  // boolean
97  // *******************************************************************************************************************
98  // METHODS
99  // *******************************************************************************************************************
103  Matrix4x4<T> m;
104  float Nv = v.x * v.x + v.y * v.y + v.z * v.z + r * r;
105  float s = (Nv > 0.f) ? (2.f / Nv) : 0.f;
106  float xs = v.x * s, ys = v.y * s, zs = v.z * s;
107  float wx = r * xs, wy = r * ys, wz = r * zs;
108  float xx = v.x * xs, xy = v.x * ys, xz = v.x * zs;
109  float yy = v.y * ys, yz = v.y * zs, zz = v.z * zs;
110  m[0][0] = 1.f - (yy + zz);
111  m[1][0] = xy + wz;
112  m[2][0] = xz - wy;
113  m[0][1] = xy - wz;
114  m[1][1] = 1.f - (xx + zz);
115  m[2][1] = yz + wx;
116  m[0][2] = xz + wy;
117  m[1][2] = yz - wx;
118  m[2][2] = 1.f - (xx + yy);
119  m[0][3] = m[1][3] = m[2][3] = m[3][0] = m[3][1] = m[3][2] = 0.f;
120  m[3][3] = 1.f;
121  return m;
122  }
126  T d = 1 / (r * r + v.length2());
127  return {-v * d, r * d};
128  }
132  return {-v, r};
133  }
137  return v.length2() + r * r;
138  }
142  return sqrtf(v.length2() + r * r);
143  }
147  auto d = v.length2() + r * r;
148  HERMES_CHECK_EXP(d != 0.0);
149  return *this / d;
150  }
151  // *******************************************************************************************************************
152  // PUBLIC FIELDS
153  // *******************************************************************************************************************
155  T r{0};
156 };
157 
158 // *********************************************************************************************************************
159 // ARITHMETIC
160 // *********************************************************************************************************************
166 template<typename T>
168  return {q.v / s, q.r / s};
169 }
175 template<typename T>
176 HERMES_DEVICE_CALLABLE inline Quaternion<T> operator*(const Quaternion<T> &q, T s) {
177  return {q.v * s, q.r * s};
178 }
184 template<typename T>
185 HERMES_DEVICE_CALLABLE inline Quaternion<T> operator*(T s, const Quaternion<T> &q) {
186  return {q.v * s, q.r * s};
187 }
194 template<typename T>
196  return {q.v + p.v, q.r + p.r};
197 }
204 template<typename T>
206  return {q.v - p.v, q.r - p.r};
207 }
213 template<typename T>
214 HERMES_DEVICE_CALLABLE inline Quaternion<T> operator*(const Quaternion<T> &q, const Quaternion<T> &p) {
215  return {q.r * p.v + p.r * q.v + cross(p.v, q.v), q.r * p.r - dot(q, p)};
216 }
217 
218 // *********************************************************************************************************************
219 // IO
220 // *********************************************************************************************************************
226 template<typename T>
227 std::ostream &operator<<(std::ostream &os, const Quaternion<T> &v) {
228  os << "Quaternion [(" << v[0] << " " << v[1] << " " << v[2] << "), " << v.w << "]";
229  return os;
230 }
231 
232 // *********************************************************************************************************************
233 // TYPEDEFS
234 // *********************************************************************************************************************
235 using quat = Quaternion<real_t>;
236 using quatf = Quaternion<f32>;
237 using quatd = Quaternion<f64>;
238 
239 }
240 
241 #endif //HERMES_HERMES_GEOMETRY_QUATERNION_H
242 
4x4 Matrix representation
Definition: matrix.h:121
Quaternion representation v.x i + v.y j + v.z k + r.
Definition: quaternion.h:46
HERMES_DEVICE_CALLABLE Quaternion conjugate() const
Computes conjugate of this quaternion.
Definition: quaternion.h:131
T r
scalar part
Definition: quaternion.h:155
HERMES_DEVICE_CALLABLE Quaternion(T x, T y, T z, T w)
Construct from component values.
Definition: quaternion.h:72
HERMES_DEVICE_CALLABLE Quaternion inverse() const
Computes inverse of this quaternion.
Definition: quaternion.h:125
HERMES_DEVICE_CALLABLE const T & operator[](int i) const
Get i-th component.
Definition: quaternion.h:89
hermes::Vector3< T > v
vector part
Definition: quaternion.h:154
HERMES_DEVICE_CALLABLE Quaternion(const hermes::Vector3< T > &v, T r=0)
Construct from part values.
Definition: quaternion.h:76
HERMES_DEVICE_CALLABLE Quaternion normalized() const
Computes normalized copy.
Definition: quaternion.h:146
static HERMES_DEVICE_CALLABLE Quaternion< T > I()
Creates an identity quaternion (0,0,0,1)
Definition: quaternion.h:56
HERMES_DEVICE_CALLABLE T & operator[](int i)
Get i-th component reference.
Definition: quaternion.h:94
HERMES_DEVICE_CALLABLE T length() const
Computes the norm.
Definition: quaternion.h:141
HERMES_DEVICE_CALLABLE Quaternion()
Default constructor.
Definition: quaternion.h:66
HERMES_DEVICE_CALLABLE T length2() const
Computes the squared norm.
Definition: quaternion.h:136
HERMES_DEVICE_CALLABLE Matrix4x4< T > matrix() const
Definition: quaternion.h:102
Geometric 3-dimensional vector (x, y, z)
Definition: vector.h:166
#define HERMES_DEVICE_CALLABLE
Specifies that the function can be called from both host and device sides.
Definition: defs.h:45
#define HERMES_CHECK_EXP(expr)
Warns if expression is false.
Definition: debug.h:95
HERMES_DEVICE_CALLABLE T dot(const Normal3< T > &n, const Vector3< T > &v)
Computes dot product with vector.
Definition: normal.h:237
HERMES_DEVICE_CALLABLE Quaternion< T > operator+(const Quaternion< T > &q, const Quaternion< T > &p)
Adds two quaternions.
Definition: quaternion.h:195
HERMES_DEVICE_CALLABLE Quaternion< T > operator-(const Quaternion< T > &q, const Quaternion< T > &p)
Subtracts p from q.
Definition: quaternion.h:205
HERMES_DEVICE_CALLABLE Quaternion< T > operator/(const Quaternion< T > &q, T s)
Scalar division.
Definition: quaternion.h:167
Geometric transform classes.
HERMES_DEVICE_CALLABLE T cross(const Vector2< T > &a, const Vector2< T > &b)
Computes the cross product between two vectors.
Definition: vector.h:550