ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/math/Quaternion.hpp
Revision: 1603
Committed: Tue Oct 19 21:28:55 2004 UTC (19 years, 8 months ago) by tim
File size: 11490 byte(s)
Log Message:
more bugs get fixed at math library

File Contents

# Content
1 /*
2 * Copyright (C) 2000-2004 Object Oriented Parallel Simulation Engine (OOPSE) project
3 *
4 * Contact: oopse@oopse.org
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 * All we ask is that proper credit is given for our work, which includes
11 * - but is not limited to - adding the above copyright notice to the beginning
12 * of your source code files, and to any copyright notice that you may distribute
13 * with programs based on this work.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 */
25
26 /**
27 * @file Quaternion.hpp
28 * @author Teng Lin
29 * @date 10/11/2004
30 * @version 1.0
31 */
32
33 #ifndef MATH_QUATERNION_HPP
34 #define MATH_QUATERNION_HPP
35
36 #include "math/Vector.hpp"
37 #include "math/SquareMatrix.hpp"
38
39 namespace oopse{
40
41 /**
42 * @class Quaternion Quaternion.hpp "math/Quaternion.hpp"
43 * Quaternion is a sort of a higher-level complex number.
44 * It is defined as Q = w + x*i + y*j + z*k,
45 * where w, x, y, and z are numbers of type T (e.g. double), and
46 * i*i = -1; j*j = -1; k*k = -1;
47 * i*j = k; j*k = i; k*i = j;
48 */
49 template<typename Real>
50 class Quaternion : public Vector<Real, 4> {
51 public:
52 Quaternion() : Vector<Real, 4>() {}
53
54 /** Constructs and initializes a Quaternion from w, x, y, z values */
55 Quaternion(Real w, Real x, Real y, Real z) {
56 data_[0] = w;
57 data_[1] = x;
58 data_[2] = y;
59 data_[3] = z;
60 }
61
62 /** Constructs and initializes a Quaternion from a Vector<Real,4> */
63 Quaternion(const Vector<Real,4>& v)
64 : Vector<Real, 4>(v){
65 }
66
67 /** copy assignment */
68 Quaternion& operator =(const Vector<Real, 4>& v){
69 if (this == & v)
70 return *this;
71
72 Vector<Real, 4>::operator=(v);
73
74 return *this;
75 }
76
77 /**
78 * Returns the value of the first element of this quaternion.
79 * @return the value of the first element of this quaternion
80 */
81 Real w() const {
82 return data_[0];
83 }
84
85 /**
86 * Returns the reference of the first element of this quaternion.
87 * @return the reference of the first element of this quaternion
88 */
89 Real& w() {
90 return data_[0];
91 }
92
93 /**
94 * Returns the value of the first element of this quaternion.
95 * @return the value of the first element of this quaternion
96 */
97 Real x() const {
98 return data_[1];
99 }
100
101 /**
102 * Returns the reference of the second element of this quaternion.
103 * @return the reference of the second element of this quaternion
104 */
105 Real& x() {
106 return data_[1];
107 }
108
109 /**
110 * Returns the value of the thirf element of this quaternion.
111 * @return the value of the third element of this quaternion
112 */
113 Real y() const {
114 return data_[2];
115 }
116
117 /**
118 * Returns the reference of the third element of this quaternion.
119 * @return the reference of the third element of this quaternion
120 */
121 Real& y() {
122 return data_[2];
123 }
124
125 /**
126 * Returns the value of the fourth element of this quaternion.
127 * @return the value of the fourth element of this quaternion
128 */
129 Real z() const {
130 return data_[3];
131 }
132 /**
133 * Returns the reference of the fourth element of this quaternion.
134 * @return the reference of the fourth element of this quaternion
135 */
136 Real& z() {
137 return data_[3];
138 }
139
140 /**
141 * Tests if this quaternion is equal to other quaternion
142 * @return true if equal, otherwise return false
143 * @param q quaternion to be compared
144 */
145 inline bool operator ==(const Quaternion<Real>& q) {
146
147 for (unsigned int i = 0; i < 4; i ++) {
148 if (!equal(data_[i], q[i])) {
149 return false;
150 }
151 }
152
153 return true;
154 }
155
156 /**
157 * Returns the inverse of this quaternion
158 * @return inverse
159 * @note since quaternion is a complex number, the inverse of quaternion
160 * q = w + xi + yj+ zk is inv_q = (w -xi - yj - zk)/(|q|^2)
161 */
162 Quaternion<Real> inverse() {
163 Quaternion<Real> q;
164 Real d = this->lengthSquare();
165
166 q.w() = w() / d;
167 q.x() = -x() / d;
168 q.y() = -y() / d;
169 q.z() = -z() / d;
170
171 return q;
172 }
173
174 /**
175 * Sets the value to the multiplication of itself and another quaternion
176 * @param q the other quaternion
177 */
178 void mul(const Quaternion<Real>& q) {
179 Quaternion<Real> tmp(*this);
180
181 data_[0] = (tmp[0]*q[0]) -(tmp[1]*q[1]) - (tmp[2]*q[2]) - (tmp[3]*q[3]);
182 data_[1] = (tmp[0]*q[1]) + (tmp[1]*q[0]) + (tmp[2]*q[3]) - (tmp[3]*q[2]);
183 data_[2] = (tmp[0]*q[2]) + (tmp[2]*q[0]) + (tmp[3]*q[1]) - (tmp[1]*q[3]);
184 data_[3] = (tmp[0]*q[3]) + (tmp[3]*q[0]) + (tmp[1]*q[2]) - (tmp[2]*q[1]);
185 }
186
187 void mul(const Real& s) {
188 data_[0] *= s;
189 data_[1] *= s;
190 data_[2] *= s;
191 data_[3] *= s;
192 }
193
194 /** Set the value of this quaternion to the division of itself by another quaternion */
195 void div(Quaternion<Real>& q) {
196 mul(q.inverse());
197 }
198
199 void div(const Real& s) {
200 data_[0] /= s;
201 data_[1] /= s;
202 data_[2] /= s;
203 data_[3] /= s;
204 }
205
206 Quaternion<Real>& operator *=(const Quaternion<Real>& q) {
207 mul(q);
208 return *this;
209 }
210
211 Quaternion<Real>& operator *=(const Real& s) {
212 mul(s);
213 return *this;
214 }
215
216 Quaternion<Real>& operator /=(Quaternion<Real>& q) {
217 *this *= q.inverse();
218 return *this;
219 }
220
221 Quaternion<Real>& operator /=(const Real& s) {
222 div(s);
223 return *this;
224 }
225 /**
226 * Returns the conjugate quaternion of this quaternion
227 * @return the conjugate quaternion of this quaternion
228 */
229 Quaternion<Real> conjugate() {
230 return Quaternion<Real>(w(), -x(), -y(), -z());
231 }
232
233 /**
234 * Returns the corresponding rotation matrix (3x3)
235 * @return a 3x3 rotation matrix
236 */
237 SquareMatrix<Real, 3> toRotationMatrix3() {
238 SquareMatrix<Real, 3> rotMat3;
239
240 Real w2;
241 Real x2;
242 Real y2;
243 Real z2;
244
245 if (!isNormalized())
246 normalize();
247
248 w2 = w() * w();
249 x2 = x() * x();
250 y2 = y() * y();
251 z2 = z() * z();
252
253 rotMat3(0, 0) = w2 + x2 - y2 - z2;
254 rotMat3(0, 1) = 2.0 * ( x() * y() + w() * z() );
255 rotMat3(0, 2) = 2.0 * ( x() * z() - w() * y() );
256
257 rotMat3(1, 0) = 2.0 * ( x() * y() - w() * z() );
258 rotMat3(1, 1) = w2 - x2 + y2 - z2;
259 rotMat3(1, 2) = 2.0 * ( y() * z() + w() * x() );
260
261 rotMat3(2, 0) = 2.0 * ( x() * z() + w() * y() );
262 rotMat3(2, 1) = 2.0 * ( y() * z() - w() * x() );
263 rotMat3(2, 2) = w2 - x2 -y2 +z2;
264
265 return rotMat3;
266 }
267
268 };//end Quaternion
269
270
271 /**
272 * Returns the vaule of scalar multiplication of this quaterion q (q * s).
273 * @return the vaule of scalar multiplication of this vector
274 * @param q the source quaternion
275 * @param s the scalar value
276 */
277 template<typename Real, unsigned int Dim>
278 Quaternion<Real> operator * ( const Quaternion<Real>& q, Real s) {
279 Quaternion<Real> result(q);
280 result.mul(s);
281 return result;
282 }
283
284 /**
285 * Returns the vaule of scalar multiplication of this quaterion q (q * s).
286 * @return the vaule of scalar multiplication of this vector
287 * @param s the scalar value
288 * @param q the source quaternion
289 */
290 template<typename Real, unsigned int Dim>
291 Quaternion<Real> operator * ( const Real& s, const Quaternion<Real>& q ) {
292 Quaternion<Real> result(q);
293 result.mul(s);
294 return result;
295 }
296
297 /**
298 * Returns the multiplication of two quaternion
299 * @return the multiplication of two quaternion
300 * @param q1 the first quaternion
301 * @param q2 the second quaternion
302 */
303 template<typename Real>
304 inline Quaternion<Real> operator *(const Quaternion<Real>& q1, const Quaternion<Real>& q2) {
305 Quaternion<Real> result(q1);
306 result *= q2;
307 return result;
308 }
309
310 /**
311 * Returns the division of two quaternion
312 * @param q1 divisor
313 * @param q2 dividen
314 */
315
316 template<typename Real>
317 inline Quaternion<Real> operator /( Quaternion<Real>& q1, Quaternion<Real>& q2) {
318 return q1 * q2.inverse();
319 }
320
321 /**
322 * Returns the value of the division of a scalar by a quaternion
323 * @return the value of the division of a scalar by a quaternion
324 * @param s scalar
325 * @param q quaternion
326 * @note for a quaternion q, 1/q = q.inverse()
327 */
328 template<typename Real>
329 Quaternion<Real> operator /(const Real& s, Quaternion<Real>& q) {
330
331 Quaternion<Real> x;
332 x = q.inverse();
333 x *= s;
334 return x;
335 }
336
337 template <class T>
338 inline bool operator==(const Quaternion<T>& lhs, const Quaternion<T>& rhs) {
339 return equal(lhs[0] ,rhs[0]) && equal(lhs[1] , rhs[1]) && equal(lhs[2], rhs[2]) && equal(lhs[3], rhs[3]);
340 }
341
342 typedef Quaternion<double> Quat4d;
343 }
344 #endif //MATH_QUATERNION_HPP

Properties

Name Value
svn:executable *