Developer Documentation
Loading...
Searching...
No Matches
DualQuaternionT_impl.hh
1/*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40\*===========================================================================*/
41
42
43
44//=============================================================================
45//
46// CLASS DualQuaternionT - IMPLEMENTATION
47//
48//=============================================================================
49
50
51#define ACG_DUALQUATERNIONT_C
52
53
54//== INCLUDES =================================================================
55
56
57#include "DualQuaternionT.hh"
58#include <iostream>
59
60//== IMPLEMENTATION ==========================================================
61
62
63namespace ACG {
64
65 //-----------------------------------------------------------------------------
66
68 template <typename Scalar>
70 *this = DualQuaternion::identity();
71 }
72
73 //-----------------------------------------------------------------------------
74
76 template <typename Scalar>
78 real_ = _other.real_;
79 dual_ = _other.dual_;
80 }
81
82 template <typename Scalar>
83 DualQuaternionT<Scalar>& DualQuaternionT<Scalar>::operator=(const DualQuaternion& _other) {
84 real_ = _other.real_;
85 dual_ = _other.dual_;
86 return(*this);
87 }
88
89 //-----------------------------------------------------------------------------
90
92 template <typename Scalar>
94 real_ = _real;
95 dual_ = _dual;
96 }
97
98 //-----------------------------------------------------------------------------
99
101 template <typename Scalar>
102 DualQuaternionT<Scalar>::DualQuaternionT(Scalar _Rw, Scalar _Rx, Scalar _Ry, Scalar _Rz,
103 Scalar _Dw, Scalar _Dx, Scalar _Dy, Scalar _Dz){
104 real_ = Quaternion(_Rw, _Rx, _Ry, _Rz);
105 dual_ = Quaternion(_Dw, _Dx, _Dy, _Dz);
106 }
107
108 //-----------------------------------------------------------------------------
109
111 template <typename Scalar>
113 real_ = _rotation;
114 dual_ = Quaternion(0.0,0.0,0.0,0.0);
115 }
116
117 //-----------------------------------------------------------------------------
118
120 template <typename Scalar>
122 real_.identity();
123 dual_ = Quaternion( 0.0, 0.5 * _translation[0], 0.5 * _translation[1], 0.5 * _translation[2] );
124 }
125
126 //-----------------------------------------------------------------------------
127
129 template <typename Scalar>
130 DualQuaternionT<Scalar>::DualQuaternionT(const Vec3& _translation, const Quaternion& _rotation){
131
132 real_ = _rotation;
133 dual_ = Quaternion( 0.0, 0.5 * _translation[0], 0.5 * _translation[1], 0.5 * _translation[2] );
134
135 dual_ *= real_;
136 }
137
138 //-----------------------------------------------------------------------------
139
141 template <typename Scalar>
143 real_ = Quaternion(_transformation); //the quaternion constructor ignores the translation
144 dual_ = Quaternion( 0.0, 0.5 * _transformation(0,3), 0.5 * _transformation(1,3), 0.5 * _transformation(2,3) );
145
146 dual_ *= real_;
147 }
148
149 //-----------------------------------------------------------------------------
150
152 template <typename Scalar>
154
155 Quaternion real;
156 real.identity();
157
158 Quaternion dual = Quaternion(0.0, 0.0, 0.0, 0.0);
159
160 return DualQuaternion( real, dual );
161 }
162
163 //-----------------------------------------------------------------------------
164
166 template <typename Scalar>
168
169 Quaternion real = Quaternion(0.0, 0.0, 0.0, 0.0);
170 Quaternion dual = Quaternion(0.0, 0.0, 0.0, 0.0);
171
172 return DualQuaternion( real, dual );
173 }
174
175 //-----------------------------------------------------------------------------
176
178 template <typename Scalar>
180 return DualQuaternion( real_.conjugate(), dual_.conjugate() );
181 }
182
183 //-----------------------------------------------------------------------------
184
186 template <typename Scalar>
188
189 double sqrLen0 = real_.sqrnorm();
190 double sqrLenE = 2.0 * (real_ | dual_);
191
192 if ( sqrLen0 > 0.0 ){
193
194 double invSqrLen0 = 1.0/sqrLen0;
195 double invSqrLenE = -sqrLenE/(sqrLen0*sqrLen0);
196
197 DualQuaternion conj = conjugate();
198
199 conj.real_ = invSqrLen0 * conj.real_;
200 conj.dual_ = invSqrLen0 * conj.dual_ + invSqrLenE * conj.real_;
201
202 return conj;
203
204 } else
205 return DualQuaternion::zero();
206 }
207
208 //-----------------------------------------------------------------------------
209
211 template <typename Scalar>
213
214 const double magn = 1.0/real_.norm();
215 const double magnSqr = 1.0/real_.sqrnorm();
216
217 // normalize rotation
218 real_ *= magn;
219 dual_ *= magn;
220
221 // normalize the rest
222 dual_ -= ((real_| dual_)* magnSqr) * real_;
223
224 }
225
226 //-----------------------------------------------------------------------------
227
229 template <typename Scalar>
231 return (_other.real_ == real_) && (_other.dual_ == dual_);
232 }
233
234 //-----------------------------------------------------------------------------
235
237 template <typename Scalar>
239 return (_other.real_ != real_) || (_other.dual_ != dual_);
240 }
241
242 //-----------------------------------------------------------------------------
243
245 template <typename Scalar>
247 return DualQuaternion( real_ + _other.real_, dual_ + _other.dual_ );
248 }
249
250 //-----------------------------------------------------------------------------
251
253 template <typename Scalar>
255 real_ = real_ + _other.real_;
256 dual_ = dual_ + _other.dual_;
257
258 return (*this);
259 }
260
261 //-----------------------------------------------------------------------------
262
264 template <typename Scalar>
266 return DualQuaternion( real_ - _other.real_, dual_ - _other.dual_ );
267 }
268
269 //-----------------------------------------------------------------------------
270
272 template <typename Scalar>
274 real_ -= _other.real_;
275 dual_ -= _other.dual_;
276
277 return (*this);
278 }
279
280 //-----------------------------------------------------------------------------
281
283 template <typename Scalar>
285 return DualQuaternion( real_ * _q.real_, real_ * _q.dual_ + dual_ * _q.real_ );
286 }
287
288 //-----------------------------------------------------------------------------
289
291 template <typename Scalar>
293 dual_ = real_ * _q.dual_ + dual_ * _q.real_;
294 real_ *= _q.real_;
295
296 return (*this);
297 }
298
299 //-----------------------------------------------------------------------------
300
302 template <typename Scalar>
305
306 q.real_ = real_ * _scalar;
307 q.dual_ = dual_ * _scalar;
308
309 return q;
310 }
311
312 //-----------------------------------------------------------------------------
313
314 template <typename Scalar>
315 Scalar& DualQuaternionT<Scalar>::operator [](const unsigned int& b) {
316 if ( b < 4 ) {
317 return real_[b];
318 } else if ( b < 8 ) {
319 return dual_[b - 4];
320 } else {
321 // Invalid operation, write error and return anything.
322 std::cerr << "Error in Dualquaternion operator[], index b out of range [0...7]" << std::endl;
323 return real_[0];
324 }
325 }
326
327
328 //-----------------------------------------------------------------------------
329
331 template <typename Scalar> template<typename VectorType>
332 DualQuaternionT<Scalar> DualQuaternionT<Scalar>::interpolate(VectorType& _weights, const std::vector<DualQuaternion>& _dualQuaternions)
333 {
334 if ( (_weights.size() != _dualQuaternions.size()) || (_weights.size() == 0) ){
335 std::cerr << "Cannot interpolate dual quaternions ( weights: " << _weights.size() << ", DQs: " << _dualQuaternions.size() << std::endl;
336 return DualQuaternionT::zero();
337 }
338
339 // Find max weight for pivoting to that quaternion,
340 // so shortest arc is taken (see: 'coping antipodality' in the paper )
341 uint pivotID = 0;
342
343 for (uint i=1; i<_dualQuaternions.size(); i++)
344 if (_weights[pivotID] < _weights[i])
345 pivotID = i;
346
347 DualQuaternion pivotDQ = _dualQuaternions[ pivotID ];
348 Quaternion pivotQ = pivotDQ.real_;
349
350 DualQuaternion res = DualQuaternion::zero();
351
352 for (uint i=0; i<_dualQuaternions.size(); i++){
353
354 DualQuaternion currentDQ = _dualQuaternions[i];
355 Quaternion currentQ = currentDQ.real_;
356
357 // Make sure dot product is >= 0
358 if ( ( currentQ | pivotQ ) < 0.0 )
359 _weights[i] = -_weights[i];
360
361 res += _dualQuaternions[i] * _weights[i];
362 }
363
364 res.normalize();
365
366 return res;
367 }
368
369 //-----------------------------------------------------------------------------
370
372 template <typename Scalar>
374 {
376
377 // for details about the calculation see the paper (algorithm 1)
378
379 Vec3 p(_point);
380
381 double r = real_[0];
382 Vec3 rv = Vec3(real_[1], real_[2], real_[3]);
383
384 double d = dual_[0];
385 Vec3 dv = Vec3(dual_[1], dual_[2], dual_[3]);
386
387 Vec3 tempVec = (rv % p) + r * p;
388 p+=2.0*(rv % tempVec);
389
390 Vec3 t = dv % rv;
391 t+= d * rv;
392 t+= -r*dv;
393 p+=-2.0*t;
394
395 return p;
396 }
397
398 //-----------------------------------------------------------------------------
399
401 template <typename Scalar>
403 {
405
406 // for details about the calculation see the paper (algorithm 1)
407
408 Vec3 p(_point);
409
410 double r = real_[0];
411 Vec3 rv = Vec3(real_[1], real_[2], real_[3]);
412
413 Vec3 tempVec = (rv % p) + r * p;
414 p+=2.0*(rv % tempVec);
415
416 return p;
417}
418
419 //-----------------------------------------------------------------------------
420
422 template <typename Scalar>
424
425 std::cerr << "Real Part:" << std::endl;
426 real_.print_info();
427 std::cerr << "Dual Part:" << std::endl;
428 dual_.print_info();
429 }
430
431 //-----------------------------------------------------------------------------
432
433//=============================================================================
434} // namespace ACG
435//=============================================================================
DualQuaternion class for representing rigid motions in 3d.
DualQuaternion operator*(const DualQuaternion &_q) const
dualQuaternion * dualQuaternion
static DualQuaternion interpolate(VectorType &_weights, const std::vector< DualQuaternion > &_dualQuaternions)
linear interpolation of dual quaternions. Result is normalized afterwards
DualQuaternion & operator-=(const DualQuaternion &_other)
substraction
DualQuaternion invert() const
invert dual quaternion
Vec3 transform_point(const Vec3 &_point) const
Transform a point with the dual quaternion.
Quaternion real_
real and dual quaternion parts
static DualQuaternion identity()
identity dual quaternion [ R(1, 0, 0, 0), D(0,0,0,0) ]
DualQuaternion conjugate() const
conjugate dual quaternion
DualQuaternion operator-(const DualQuaternion &_other) const
substraction
Vec3 transform_vector(const Vec3 &_point) const
Transform a vector with the dual quaternion.
DualQuaternion & operator*=(const DualQuaternion &_q)
dualQuaternion *= dualQuaternion
void normalize()
normalize dual quaternion
void printInfo()
print some info about the DQ
static DualQuaternion zero()
zero dual quaternion [ R(0, 0, 0, 0), D(0,0,0,0) ]
DualQuaternion operator+(const DualQuaternion &_other) const
addition
bool operator!=(const DualQuaternion &_other) const
dual quaternion comparison
DualQuaternion & operator+=(const DualQuaternion &_other)
addition
bool operator==(const DualQuaternion &_other) const
dual quaternion comparison
Scalar & operator[](const unsigned int &b)
Access as one big vector.
DualQuaternionT()
Default constructor ( constructs an identity dual quaternion )
void identity()
identity rotation
Namespace providing different geometric functions concerning angles.