Loading...
Searching...
No Matches
Rotation.h
1
19
20#pragma once
21#include <stdio.h>
22#include <math.h>
23#include <limits>
24#include "Vec3.h"
25
26namespace CommonMath
27{
28
31
37 class Rotation
38 {
39 double static constexpr half = double(0.5);
40 double static constexpr MIN_ANGLE = double(4.84813681e-6); // less than one arc second.
41
42 public:
43 Rotation(void)
44 {
45 }
46
48 Rotation(double a, double b, double c, double d)
49 {
50 _v[0] = a;
51 _v[1] = b;
52 _v[2] = c;
53 _v[3] = d;
54 }
55
57 Rotation(Rotation const &in)
58 {
59 _v[0] = double(in[0]);
60 _v[1] = double(in[1]);
61 _v[2] = double(in[2]);
62 _v[3] = double(in[3]);
63 }
64
65 static inline Rotation Identity(void)
66 {
67 return Rotation(1, 0, 0, 0);
68 }
69
70 Rotation Inverse(void) const
71 {
72 return Rotation(_v[0], -_v[1], -_v[2], -_v[3]);
73 }
74
76 void Normalise(void)
77 {
78 double n = sqrt(_v[0] * _v[0] + _v[1] * _v[1] + _v[2] * _v[2] + _v[3] * _v[3]);
79 if (n < 1.0e-6)
80 {
81 (*this) = Identity();
82 }
83 else
84 {
85 for (int i = 0; i < 4; i++)
86 _v[i] /= n;
87 }
88 }
89
93 static Rotation FromRotationVector(const Vec3 rotVec)
94 {
95 const double theta = rotVec.GetNorm2();
96 if (theta < MIN_ANGLE)
97 return Identity(); // less than one arc second :)
98 return FromAxisAngle(rotVec / theta, theta);
99 }
100
104 static inline Rotation FromAxisAngle(const Vec3 &unitVector, const double &angle)
105 {
106 return Rotation(cos(angle * half), sin(angle * half) * unitVector.x, sin(angle * half) * unitVector.y,
107 sin(angle * half) * unitVector.z);
108 }
109
111 static Rotation FromEulerYPR(const double &y, const double &p, const double &r)
112 { // NB! rotation: 3-2-1 yaw,pitch,roll
113 Rotation rot;
114 rot[0] = cos(half * y) * cos(half * p) * cos(half * r) + sin(half * y) * sin(half * p) * sin(half * r);
115 rot[1] = cos(half * y) * cos(half * p) * sin(half * r) - sin(half * y) * sin(half * p) * cos(half * r);
116 rot[2] = cos(half * y) * sin(half * p) * cos(half * r) + sin(half * y) * cos(half * p) * sin(half * r);
117 rot[3] = sin(half * y) * cos(half * p) * cos(half * r) - cos(half * y) * sin(half * p) * sin(half * r);
118 return rot;
119 }
120
122 static Rotation FromVectorPartOfQuaternion(const Vec3 in)
123 {
124 double tmp = in.GetNorm2Squared();
125 if (tmp > 1.0f)
126 return Rotation::Identity();
127 double a0 = sqrt(1 - tmp);
128 return Rotation(a0, in.x, in.y, in.z);
129 }
130
131 inline Rotation &operator=(const Rotation &other)
132 {
133 if (this != &other)
134 {
135 _v[0] = other[0];
136 _v[1] = other[1];
137 _v[2] = other[2];
138 _v[3] = other[3];
139 }
140 return *this;
141 }
142
144 Rotation operator*(const Rotation &r1) const
145 {
146 double c0 = r1[0] * _v[0] - r1[1] * _v[1] - r1[2] * _v[2] - r1[3] * _v[3];
147 double c1 = r1[1] * _v[0] + r1[0] * _v[1] + r1[3] * _v[2] - r1[2] * _v[3];
148 double c2 = r1[2] * _v[0] - r1[3] * _v[1] + r1[0] * _v[2] + r1[1] * _v[3];
149 double c3 = r1[3] * _v[0] + r1[2] * _v[1] - r1[1] * _v[2] + r1[0] * _v[3];
150
151 return Rotation(c0, c1, c2, c3);
152 }
153
155 Vec3 operator*(const Vec3 &vec) const
156 {
157 return Rotate(vec);
158 }
159
165 {
166 const Vec3 n = ToVectorPartOfQuaternion();
167 const double norm = n.GetNorm2();
168 const double angle = asin(norm) * 2;
169 if (angle < MIN_ANGLE)
170 {
171 return Vec3(0, 0, 0); // less than one arc second
172 }
173
174 return n * (angle / norm);
175 }
176
179 {
180 // makes first component positive
181 if (_v[0] > 0)
182 return Vec3(_v[1], _v[2], _v[3]);
183 else
184 return Vec3(-_v[1], -_v[2], -_v[3]);
185 }
186
188 void ToEulerYPR(double &y, double &p, double &r) const
189 {
190 y = atan2(double(2.0) * _v[1] * _v[2] + double(2.0) * _v[0] * _v[3],
191 _v[1] * _v[1] + _v[0] * _v[0] - _v[3] * _v[3] - _v[2] * _v[2]);
192 p = -asin(double(2.0) * _v[1] * _v[3] - double(2.0) * _v[0] * _v[2]);
193 r = atan2(double(2.0) * _v[2] * _v[3] + double(2.0) * _v[0] * _v[1],
194 _v[3] * _v[3] - _v[2] * _v[2] - _v[1] * _v[1] + _v[0] * _v[0]);
195 }
196
198 Vec3 ToEulerYPR(void) const
199 {
200 Vec3 out;
201 ToEulerYPR(out.x, out.y, out.z);
202 return out;
203 }
204
207 {
208 double R[9];
210 for (int i = 0; i < 3; i++)
211 {
212 for (int j = 0; j < 3; j++)
213 {
214 printf("%.3f\t", (double)R[i * 3 + j]);
215 }
216 printf("\n");
217 }
218 }
219
220 double &operator[](unsigned const i)
221 {
222 return _v[i];
223 }
224 const double &operator[](unsigned const i) const
225 {
226 return _v[i];
227 }
228
235 void GetRotationMatrix(double R[9]) const
236 {
237 const double r0 = _v[0] * _v[0];
238 const double r1 = _v[1] * _v[1];
239 const double r2 = _v[2] * _v[2];
240 const double r3 = _v[3] * _v[3];
241
242 R[0] = r0 + r1 - r2 - r3;
243 R[1] = 2 * _v[1] * _v[2] - 2 * _v[0] * _v[3];
244 R[2] = 2 * _v[1] * _v[3] + 2 * _v[0] * _v[2];
245
246 R[3] = 2 * _v[1] * _v[2] + 2 * _v[0] * _v[3];
247 R[4] = r0 - r1 + r2 - r3;
248 R[5] = 2 * _v[2] * _v[3] - 2 * _v[0] * _v[1];
249
250 R[6] = 2 * _v[1] * _v[3] - 2 * _v[0] * _v[2];
251 R[7] = 2 * _v[2] * _v[3] + 2 * _v[0] * _v[1];
252 R[8] = r0 - r1 - r2 + r3;
253 }
254
255 private:
256 Vec3 Rotate(const Vec3 &in) const
257 {
258 double R[9];
260
261 Vec3 ret(R[0] * in.x + R[1] * in.y + R[2] * in.z, R[3] * in.x + R[4] * in.y + R[5] * in.z,
262 R[6] * in.x + R[7] * in.y + R[8] * in.z);
263
264 return ret;
265 }
266
267 Vec3 RotateBackwards(const Vec3 &in) const
268 {
269 double R[9];
270 Inverse().GetRotationMatrix(R);
271
272 Vec3 ret(R[0] * in.x + R[1] * in.y + R[2] * in.z, R[3] * in.x + R[4] * in.y + R[5] * in.z,
273 R[6] * in.x + R[7] * in.y + R[8] * in.z);
274
275 return ret;
276 }
277
278 double _v[4];
279 };
280} // namespace CommonMath
Vec3 ToEulerYPR(void) const
Returns the Euler angles yaw, pitch, and roll representing this rotation.
Definition Rotation.h:198
Rotation operator*(const Rotation &r1) const
Rotation multiplication: r2*r1, corresponds to a rotation r1 followed by rotation r2.
Definition Rotation.h:144
void GetRotationMatrix(double R[9]) const
Definition Rotation.h:235
Rotation(double a, double b, double c, double d)
Constructor given a unit quaternion.
Definition Rotation.h:48
static Rotation FromRotationVector(const Vec3 rotVec)
Definition Rotation.h:93
Rotation(Rotation const &in)
Copy constructor.
Definition Rotation.h:57
Vec3 operator*(const Vec3 &vec) const
Rotate a vector forward.
Definition Rotation.h:155
Vec3 ToRotationVector(void) const
Definition Rotation.h:164
static Rotation FromEulerYPR(const double &y, const double &p, const double &r)
Returns a Rotation object given Euler angles yaw, pitch, and roll.
Definition Rotation.h:111
static Rotation FromVectorPartOfQuaternion(const Vec3 in)
Returns a Rotation object given the three elements of the vector part of a unit quaternion.
Definition Rotation.h:122
static Rotation FromAxisAngle(const Vec3 &unitVector, const double &angle)
Definition Rotation.h:104
void Normalise(void)
This makes sure the quaternion is a unit quaternion.
Definition Rotation.h:76
void PrintRotationMatrix(void)
For debugging.
Definition Rotation.h:206
Vec3 ToVectorPartOfQuaternion(void) const
Returns the vector part of the quaternion representing this rotation.
Definition Rotation.h:178
void ToEulerYPR(double &y, double &p, double &r) const
Returns the Euler angles yaw, pitch, and roll representing this rotation.
Definition Rotation.h:188
3D vector class with common vector operations.
Definition Vec3.h:36
double GetNorm2Squared(void) const
Calculate the Euclidean norm of the vector, squared (= sum of squared elements).
Definition Vec3.h:109
double GetNorm2(void) const
Calculate the Euclidean norm of the vector.
Definition Vec3.h:115
double z
the three components of the vector
Definition Vec3.h:38