zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Quaternion.hxx
Go to the documentation of this file.
1 /* This file is part of the Zenipex Library (zenilib).
2  * Copyright (C) 2011 Mitchell Keith Bloch (bazald).
3  *
4  * zenilib is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * zenilib is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with zenilib. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef ZENI_QUATERNION_HXX
19 #define ZENI_QUATERNION_HXX
20 
21 // HXXed below
22 #include <Zeni/Coordinate.h>
23 #include <Zeni/Matrix4f.h>
24 #include <Zeni/Vector3f.h>
25 
26 #include <Zeni/Quaternion.h>
27 
28 // Not HXXed
29 #include <cassert>
30 #include <cmath>
31 
32 namespace Zeni {
33 
34  Quaternion::Quaternion(const bool &degenerate_)
35  : time(1.0f),
36  space(0.0f, 0.0f, 0.0f),
37  degenerate(degenerate_)
38  {
39  }
40 
42  return Quaternion(time + rhs.time, space + rhs.space, degenerate || rhs.degenerate);
43  }
44 
46  return Quaternion(time - rhs.time, space - rhs.space, degenerate || rhs.degenerate);
47  }
48 
50  time += rhs.time;
51  space += rhs.space;
52  degenerate |= rhs.degenerate;
53  return *this;
54  }
55 
57  time -= rhs.time;
58  space -= rhs.space;
59  degenerate |= rhs.degenerate;
60  return *this;
61  }
62 
64  return grassman_product(rhs);
65  }
66 
68  return *this = grassman_product(rhs);
69  }
70 
72  return Quaternion(time * rhs.time - space * rhs.space, time * rhs.space + rhs.time * space + space % rhs.space, degenerate || rhs.degenerate);
73  }
74 
76  return Quaternion(time * rhs.time - space * rhs.space, time * rhs.space + space * rhs.time, degenerate || rhs.degenerate);
77  }
78 
80  return Quaternion(0.0f, space % rhs.space, degenerate || rhs.degenerate);
81  }
82 
84  return Quaternion(time * rhs.time + space * rhs.space, time * rhs.space - space * rhs.time - space % rhs.space, degenerate || rhs.degenerate);
85  }
86 
88  return Quaternion(time * rhs.time + space * rhs.space, Vector3f(), degenerate || rhs.degenerate);
89  }
90 
92  return Quaternion(0.0f, time * rhs.space - space * rhs.time - space % rhs.space, degenerate || rhs.degenerate);
93  }
94 
95  Quaternion Quaternion::operator*(const float &rhs) const {
96  return Quaternion(time * rhs, space * rhs, degenerate);
97  }
98 
99  Quaternion Quaternion::operator/(const float &rhs) const {
100  return Quaternion(time / rhs, space / rhs, degenerate);
101  }
102 
103  Quaternion & Quaternion::operator*=(const float &rhs) {
104  time *= rhs;
105  space *= rhs;
106  return *this;
107  }
108 
109  Quaternion & Quaternion::operator/=(const float &rhs) {
110  time /= rhs;
111  space /= rhs;
112  return *this;
113  }
114 
116  return Quaternion(time * -1, space * -1, degenerate);
117  }
118 
119  float Quaternion::magnitude2() const {
120  return time * time + space * space;
121  }
122 
123  float Quaternion::magnitude() const {
124  return float(sqrt(magnitude2()));
125  }
126 
128  return Quaternion(time, -space, degenerate);
129  }
130 
132  Quaternion star = conjugate();
133  return star / (*this * star).time;
134  }
135 
137  return Quaternion(magnitude(), Vector3f(), degenerate);
138  }
139 
142  }
143 
145  const float temp = magnitude2();
146  return Quaternion(temp * temp, Vector3f(), degenerate);
147  }
148 
150  return conjugate() * norm();
151  }
152 
154  const float &a = time;
155  const float &b = space.i;
156  const float &c = space.j;
157  const float &d = space.k;
158  const float &v1 = rhs.i;
159  const float &v2 = rhs.j;
160  const float &v3 = rhs.k;
161 
162  // http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
163  // dependent on Quaternion being pre-normalized
164 
165  const float t2 = a * b;
166  const float t3 = a * c;
167  const float t4 = a * d;
168  const float t5 = -b * b;
169  const float t6 = b * c;
170  const float t7 = b * d;
171  const float t8 = -c * c;
172  const float t9 = c * d;
173  const float t10 = -d * d;
174 
175  const float v1new = 2.0f * ((t8 + t10) * v1 + (t6 - t4) * v2 + (t3 + t7) * v3) + v1;
176  const float v2new = 2.0f * ((t4 + t6) * v1 + (t5 + t10) * v2 + (t9 - t2) * v3) + v2;
177  const float v3new = 2.0f * ((t7 - t3) * v1 + (t2 + t9) * v2 + (t5 + t8) * v3) + v3;
178 
179  return Vector3f(v1new, v2new, v3new, degenerate || rhs.degenerate);
180  }
181 
182  std::pair<Vector3f, float> Quaternion::get_rotation() const {
183  Quaternion q = normalized();
184 
185  if(q.time < -1.0f)
186  q.time = -1.0f;
187  else if(q.time > 1.0f)
188  q.time = 1.0f;
189 
190  const float angle = 2.0f * float(acos(q.time));
191  float s = float(sqrt(1.0f - q.time * q.time));
192 
193  if(fabs(s) < 0.001f)
194  return std::make_pair(q.space, angle);
195 
196  return std::make_pair(q.space / s, angle);
197  }
198 
200  const float x2 = space.i * space.i;
201  const float y2 = space.j * space.j;
202  const float z2 = space.k * space.k;
203  const float xy = space.i * space.j;
204  const float xz = space.i * space.k;
205  const float yz = space.j * space.k;
206  const float wx = time * space.i;
207  const float wy = time * space.j;
208  const float wz = time * space.k;
209 
210  return Matrix4f(
211  1.0f - 2.0f * (y2 + z2),
212  2.0f * (xy - wz),
213  2.0f * (xz + wy),
214  0.0f,
215 
216  2.0f * (xy + wz),
217  1.0f - 2.0f * (x2 + z2),
218  2.0f * (yz - wx),
219  0.0f,
220 
221  2.0f * (xz - wy),
222  2.0f * (yz + wx),
223  1.0f - 2.0f * (x2 + y2),
224  0.0f,
225 
226  0.0f, 0.0f, 0.0f, 1.0f);
227  }
228 
229  const float & Quaternion::operator[](const int &index) const {
230  assert(-1 < index && index < 4);
231  const float * const ptr = &time;
232  return ptr[index];
233  }
234 
235  float & Quaternion::operator[](const int &index) {
236  assert(-1 < index && index < 4);
237  float * const ptr = &time;
238  return ptr[index];
239  }
240 
241 }
242 
243 #include <Zeni/Coordinate.hxx>
244 #include <Zeni/Matrix4f.hxx>
245 #include <Zeni/Vector3f.hxx>
246 
247 #endif
Quaternion & operator+=(const Quaternion &rhs)
Set equal to the sum.
Definition: Quaternion.hxx:49
Quaternion absolute_value() const
Definition: Quaternion.hxx:136
GLdouble s
Definition: glew.h:1376
Quaternion adjoint() const
Definition: Quaternion.hxx:149
GLfloat GLfloat v1
Definition: glew.h:1838
Quaternion reciprocal() const
Definition: Quaternion.hxx:131
t2
Definition: e_log.c:151
GLclampf f
Definition: glew.h:3390
GLdouble angle
Definition: glew.h:8396
Vector3f space
Definition: Quaternion.h:105
GLfloat GLfloat GLfloat GLfloat v3
Definition: glew.h:1846
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
Matrix4f get_matrix() const
Get the matrix form of the rotation in row-major order.
Definition: Quaternion.hxx:199
Quaternion euclidean_product(const Quaternion &rhs) const
Get the Euclidean product.
Definition: Quaternion.hxx:83
Quaternion grassman_odd_product(const Quaternion &rhs) const
Get the Grassman odd/outer-product.
Definition: Quaternion.hxx:79
return Display return Display Bool Bool int d
Definition: SDL_x11sym.h:30
#define assert(x)
Definition: SDL_malloc.c:1234
GLfixed GLfixed GLfixed y2
Definition: glext.h:4559
Quaternion euclidean_even_product(const Quaternion &rhs) const
Get the Euclidean even/inner-product.
Definition: Quaternion.hxx:87
Quaternion operator+(const Quaternion &rhs) const
Get the sum.
Definition: Quaternion.hxx:41
Quaternion euclidean_odd_product(const Quaternion &rhs) const
Get the Euclidean odd/outer-product.
Definition: Quaternion.hxx:91
A Featureful 3-Space Vector Class.
Definition: Vector3f.h:58
bool degenerate
Definition: Vector3f.h:123
std::pair< Vector3f, float > get_rotation() const
Get the rotation in radians left about an axis.
Definition: Quaternion.hxx:182
Quaternion normalized() const
Get the normalized vector.
Definition: Quaternion.cpp:140
Quaternion conjugate() const
Get the spacial conjugation.
Definition: Quaternion.hxx:127
Quaternion grassman_product(const Quaternion &rhs) const
Get the Grassman-product.
Definition: Quaternion.hxx:71
const GLfloat * c
Definition: glew.h:14913
Quaternion & operator/=(const float &rhs)
Set equal to the scalar something.
Definition: Quaternion.hxx:109
A Featureful Quaternion Class.
Definition: Quaternion.h:44
Quaternion & operator-=(const Quaternion &rhs)
Set equal to the difference.
Definition: Quaternion.hxx:56
GLuint index
Definition: glew.h:1800
Quaternion norm() const
Definition: Quaternion.hxx:140
Quaternion operator*(const Quaternion &rhs) const
Get the grassman_product.
Definition: Quaternion.hxx:63
float magnitude() const
Get the magnitude of the vector.
Definition: Quaternion.hxx:123
const float & operator[](const int &index) const
Get &#39;index&#39;.
Definition: Quaternion.hxx:229
Quaternion operator*=(const Quaternion &rhs)
Get the grassman_odd_product.
Definition: Quaternion.hxx:67
Quaternion determinant() const
Definition: Quaternion.hxx:144
Quaternion operator/(const float &rhs) const
Get the scalar... something.
Definition: Quaternion.hxx:99
GLdouble GLdouble GLdouble GLdouble q
Definition: glew.h:1400
GLfixed GLfixed x2
Definition: glext.h:4559
Quaternion(const bool &degenerate_=false)
Definition: Quaternion.hxx:34
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
A Featureful 4-Space Matrix Class.
Definition: Matrix4f.h:47
Quaternion operator-() const
Get the negation.
Definition: Quaternion.hxx:115
float magnitude2() const
Get the &#39;magnitude squared&#39; of the vector.
Definition: Quaternion.hxx:119
Quaternion grassman_even_product(const Quaternion &rhs) const
Get the Grassman even/inner-product.
Definition: Quaternion.hxx:75
double fabs(double x)
Definition: s_fabs.c:29
GLfloat GLfloat GLfloat v2
Definition: glew.h:1842