cisst-saw
Loading...
Searching...
No Matches
vctRodriguezRotation3Base.h
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3
4/*
5 Author(s): Anton Deguet
6 Created on: 2005-08-25
7
8 (C) Copyright 2005-2018 Johns Hopkins University (JHU), All Rights Reserved.
9
10--- begin cisst license - do not edit ---
11
12This software is provided "as is" under an open source license, with
13no warranty. The complete license can be found in license.txt and
14http://www.cisst.org/cisst/license.txt.
15
16--- end cisst license ---
17*/
18
19#pragma once
20#ifndef _vctRodriguezRotation3Base_h
21#define _vctRodriguezRotation3Base_h
22
27
29
32
34
35#ifndef DOXYGEN
36#ifndef SWIG
37
38// helper functions for subtemplated methods of a templated class
39template <class _rodriguezType, class _matrixType>
40void
42 const vctMatrixRotation3Base<_matrixType> & matrixRotation);
43
44template <class _rodriguezType, class _matrixType>
45void
47 const vctQuaternionRotation3Base<_matrixType> & quaternionRotation);
48
49#endif // SWIG
50#endif // DOXYGEN
51
52
66template <class _containerType>
67class vctRodriguezRotation3Base: public _containerType
68{
69public:
70 enum {DIMENSION = 3};
71 typedef _containerType BaseType;
72 typedef _containerType ContainerType;
74
75 /* no need to document, inherit doxygen documentation from vctFixedSizeVectorBase */
76 VCT_CONTAINER_TRAITS_TYPEDEFS(typename ContainerType::value_type);
78
79
80protected:
82 inline void ThrowUnlessIsNormalized(void) const CISST_THROW(std::runtime_error) {
83 if (! IsNormalized()) {
84 cmnThrow(std::runtime_error("vctRodriguezRotation3Base: This rotation is not normalized"));
85 }
86 }
87
92 template <class _inputType>
93 inline void ThrowUnlessIsNormalized(const _inputType & input) const CISST_THROW(std::runtime_error) {
94 if (! input.IsNormalized()) {
95 cmnThrow(std::runtime_error("vctRodriguezRotation3Base: Input is not normalized"));
96 }
97 }
98
99public:
100
105
109 template <stride_type __stride, class __dataPtrType>
113
116 this->Assign(x, y, z);
117 }
118
122
123 template <stride_type __stride, class __dataPtrType>
125 CISST_THROW(std::runtime_error)
126 {
127 FromRaw(vector);
128 // Always true - ThrowUnlessIsNormalized();
129 return (*this);
130 }
131
133 CISST_THROW(std::runtime_error)
134 {
135 FromRaw(x, y, z);
136 // Always true - ThrowUnlessIsNormalized();
137 return (*this);
138 }
139
140
141 template <class __vectorOwnerType>
143 CISST_THROW(std::runtime_error)
144 {
145 FromRaw(vector);
146 // Always true - ThrowUnlessIsNormalized();
147 return (*this);
148 }
149
150
151 template <class __containerType>
152 inline ThisType & From(const vctQuaternionRotation3Base<__containerType> & quaternionRotation)
153 CISST_THROW(std::runtime_error)
154 {
155 ThrowUnlessIsNormalized(quaternionRotation);
156 return FromRaw(quaternionRotation);
157 }
158
159
160 template <class __containerType>
161 inline ThisType & From(const vctMatrixRotation3Base<__containerType> & matrixRotation) {
162 ThrowUnlessIsNormalized(matrixRotation);
163 return FromRaw(matrixRotation);
164 }
165
166
167 inline ThisType & From(const vctAxisAngleRotation3<value_type> & axisAngleRotation) {
168 ThrowUnlessIsNormalized(axisAngleRotation);
169 return FromRaw(axisAngleRotation);
170 }
171
172
173
174 template <stride_type __stride, class __dataPtrType>
180
181
183 {
184 FromRaw(x, y, z);
185 return NormalizedSelf();
186 }
187
188
189 // might throw because of size
190 template <class __vectorOwnerType>
192 CISST_THROW(std::runtime_error)
193 {
194 FromRaw(vector);
195 return NormalizedSelf();
196 }
197
198
199 template <class __containerType>
201 {
202 return FromRaw(quaternionRotation.Normalized());
203 }
204
205
206 template <class __containerType>
208 return FromRaw(matrixRotation.Normalized());
209 }
210
211
212 inline ThisType & FromNormalized(const vctAxisAngleRotation3<value_type> & axisAngleRotation) {
213 return FromRaw(axisAngleRotation.Normalized());
214 }
215
216
217
218
219
220 template <stride_type __stride, class __dataPtrType>
222 {
223 this->Assign(vector);
224 return *this;
225 }
226
227
229 {
230 this->Assign(static_cast<value_type>(x), static_cast<value_type>(y), static_cast<value_type>(z));
231 return *this;
232 }
233
234
235 template <class __vectorOwnerType>
237 {
238 if (vector.size() != 3) {
239 cmnThrow(std::runtime_error("vctRodriguezRotation3Base: From requires a vector of size 3"));
240 }
241 this-Assign(vector);
242 return *this;
243 }
244
245
246 template <class __containerType>
247 inline ThisType & FromRaw(const vctQuaternionRotation3Base<__containerType> & quaternionRotation) {
248 vctRodriguezRotation3BaseFromRaw(*this, quaternionRotation);
249 return *this;
250 }
251
252
253 template <class __containerType>
255 vctRodriguezRotation3BaseFromRaw(*this, matrixRotation);
256 return *this;
257 }
258
259
260 inline ThisType & FromRaw(const vctAxisAngleRotation3<value_type> & axisAngleRotation) {
261 this->Assign(axisAngleRotation.Axis());
262 this->Multiply(value_type(axisAngleRotation.Angle()));
263 return *this;
264 }
265
266
267 inline ThisType & InverseSelf(void) {
268 this->NegationSelf();
269 return *this;
270 }
271
272 inline ThisType & InverseOf(const ThisType & otherRotation) {
273 this->NegationOf(otherRotation);
274 return *this;
275 }
276
277 inline ThisType Inverse(void) const {
278 ThisType result;
279 result.NegationOf(*this);
280 return result;
281 }
282
284 inline ThisType & NormalizedSelf(void) {
285 const NormType norm = this->Norm();
286 if (norm > (2.0 * cmnPI)) {
287 const NormType remainder = fmod(norm, (2.0 * cmnPI));
288 // const NormType quotient = (norm - remainder) / (2.0 * cmnPI);
289 this->Multiply(value_type(remainder / norm));
290 }
291 return *this;
292 }
293
295 inline ThisType & NormalizedOf(const ThisType & otherRotation) {
296 this->Assign(otherRotation);
298 return *this;
299 }
300
302 inline ThisType Normalized(void) const {
303 ThisType result(*this);
304 result.NormalizedSelf();
305 return result;
306 }
307
317 inline bool IsNormalized(value_type CMN_UNUSED(tolerance) = TypeTraits::Tolerance()) const {
318 return true;
319 }
320
321
330 inline bool AlmostEquivalent(const ThisType & other,
331 value_type tolerance = TypeTraits::Tolerance()) const {
332 const AngleType angleThis = this->Norm();
333 const AngleType angleOther = other.Norm();
334 const AngleType dotProduct = AngleType(this->DotProduct(other));
335 // two quasi null rotations
336 if ((angleThis <= tolerance) && (angleOther <= tolerance)) {
337 return true;
338 }
339 // one rotation is almost null
340 if ((angleThis <= tolerance) || (angleOther <= tolerance)) {
341 return false;
342 }
343 // both rotations are non null
344 const AngleType cosAngle = dotProduct / (angleThis * angleOther);
345 const AngleType absCosAngle = cosAngle > value_type(0.0) ? cosAngle : -cosAngle;
346 // axis don't seem aligned
347 if ((absCosAngle <= (AngleType(1.0) - tolerance))
348 || (absCosAngle >= (AngleType(1.0) + tolerance))) {
349 return false;
350 }
351 // axis are aligned
352 const AngleType angleDifference = angleThis - cosAngle * angleOther;
353 AngleType angleRemain = fmod(angleDifference, 2.0 * cmnPI);
354 if (angleRemain > cmnPI) {
355 angleRemain -= (2.0 * cmnPI);
356 } else if (angleRemain < -cmnPI) {
357 angleRemain += (2.0 *cmnPI);
358 }
359 if ((angleRemain > -tolerance) && (angleRemain < tolerance)) {
360 return true;
361 }
362 return false;
363 }
364
365};
366
367
368
369template <class _rodriguezType, class _quaternionType>
370void
372 const vctQuaternionRotation3Base<_quaternionType> & quaternionRotation)
373{
374 typedef typename _rodriguezType::value_type value_type;
375 typedef typename _rodriguezType::AngleType AngleType;
376 typedef typename _rodriguezType::NormType NormType;
377 typedef typename _rodriguezType::TypeTraits TypeTraits;
378
379 const NormType r = quaternionRotation.R();
380 const AngleType angle = acos(r) * 2;
381 AngleType oneMinusR2 = 1.0 - r * r;
382 if (oneMinusR2 < TypeTraits::Tolerance())
383 oneMinusR2 = 0.0;
384 AngleType sinAngle = sqrt(oneMinusR2);
386 rodriguezRotation.X() = (value_type)(quaternionRotation.X() / sinAngle);
387 rodriguezRotation.Y() = (value_type)(quaternionRotation.Y() / sinAngle);
388 rodriguezRotation.Z() = (value_type)(quaternionRotation.Z() / sinAngle);
389 } else {
390 rodriguezRotation.X() = quaternionRotation.X();
391 rodriguezRotation.Y() = quaternionRotation.Y();
392 rodriguezRotation.Z() = quaternionRotation.Z();
393 }
394 rodriguezRotation.Multiply((value_type) angle);
395}
396
397
398template <class _rodriguezType, class _matrixType>
399void
401 const vctMatrixRotation3Base<_matrixType> & matrixRotation)
402{
403 typedef typename _rodriguezType::value_type value_type;
404 typedef typename _rodriguezType::AngleType AngleType;
405 typedef typename _rodriguezType::NormType NormType;
406 typedef typename _rodriguezType::TypeTraits TypeTraits;
407
408 const NormType normTolerance = TypeTraits::Tolerance();
409 const NormType trace = matrixRotation.Element(0, 0) + matrixRotation.Element(1, 1) + matrixRotation.Element(2, 2); // 2 * cos(angle) + 1
410 const NormType xSin = matrixRotation.Element(2, 1) - matrixRotation.Element(1, 2); // 2 * x * sin(angle)
411 const NormType ySin = matrixRotation.Element(0, 2) - matrixRotation.Element(2, 0); // 2 * y * sin(angle)
412 const NormType zSin = matrixRotation.Element(1, 0) - matrixRotation.Element(0, 1); // 2 * z * sin(angle)
413 const NormType normSquare = xSin * xSin + ySin * ySin + zSin * zSin;
414 NormType norm;
415 if (normSquare < normTolerance) {
416 norm = 0.0;
417 } else {
418 norm = sqrt(normSquare); // 2 * |sin(angle)|
419 }
420
421 // either 0 or PI
422 if (norm == 0.0) {
423 const NormType traceMinus3 = trace - NormType(3);
424 // if the angle is 0, then cos(angle) = 1, and trace = 2*cos(angle) + 1 = 3
425 if ( (traceMinus3 > -normTolerance) && (traceMinus3 < normTolerance) ) {
426 rodriguezRotation.SetAll(value_type(0));
427 return;
428 }
429 // since norm is already 0, we are in the other case, i.e., angle-PI, but we just want
430 // to assert that trace = -1
431 assert( (trace > (NormType(-1) - normTolerance)) && (trace < (NormType(-1) + normTolerance)) );
432 // the diagonal is [k_x*k_x*v + c , k_y*k_y*v + c, k_z*k_z*v + c]
433 // c = -1 ; v = (1 - c) = 2
434 NormType xSquare = (matrixRotation.Element(0, 0) + 1) / 2;
435 NormType ySquare = (matrixRotation.Element(1, 1) + 1) / 2;
436 NormType zSquare = (matrixRotation.Element(2, 2) + 1) / 2;
437 if (xSquare < normTolerance)
438 xSquare = 0;
439 if (ySquare < normTolerance)
440 ySquare = 0;
441 if (zSquare < normTolerance)
442 zSquare = 0;
443 NormType x = sqrt(xSquare);
444 NormType y = sqrt(ySquare);
445 NormType z = sqrt(zSquare);
446 // we arbitrarily decide the k_x is positive, if it's zero then k_y is positive, and if both are zero, then k_z is positive
447 if (x > 0) {
448 if (matrixRotation.Element(1, 0) < 0) // Element(1,0) = k_x*k_y*v , where v=2, so we just need to check its sign
449 y = -y;
450 if (matrixRotation.Element(2, 0) < 0) // Element(2,0) = k_x*k_z*v
451 z = -z;
452 } else if (y > 0) {
453 if (matrixRotation.Element(2, 1) < 0) // Element(2,1) = k_y*k_z*v
454 z = -z;
455 }
456 else {
457 z = 1.0; // x and y are zero, Z has to be one
458 }
459 rodriguezRotation.Assign(value_type(x), value_type(y), value_type(z));
460 rodriguezRotation.Multiply(value_type(cmnPI));
461 return;
462 }
463
464 AngleType angle = atan2(norm / 2, (trace - 1) / 2);
465 rodriguezRotation.Assign(value_type(xSin), value_type(ySin), value_type(zSin));
466 rodriguezRotation.Multiply(value_type(angle / norm));
467}
468
469#endif // _vctRodriguezRotation3Base_h
A collection of useful information about the C++ basic types, represented in a generic programming wa...
Definition cmnTypeTraits.h:155
static Type Tolerance(void)
Definition cmnTypeTraits.h:170
_elementType value_type
Definition mtsGenericObjectProxy.h:329
Define a rotation based on an axis and an angle for a space of dimension 3.
Definition vctAxisAngleRotation3.h:93
const AxisType & Axis(void) const
Definition vctAxisAngleRotation3.h:312
ThisType Normalized(void) const
Definition vctAxisAngleRotation3.h:540
const AngleType & Angle(void) const
Definition vctAxisAngleRotation3.h:322
Definition vctForwardDeclarations.h:119
A template for a fixed length vector with fixed spacing in memory.
Definition vctFixedSizeConstVectorBase.h:108
Define a rotation matrix for a space of dimension 3.
Definition vctMatrixRotation3Base.h:71
RotationValueType Normalized(void) const
Definition vctMatrixRotation3.h:394
const_reference R(void) const
Definition vctQuaternionBase.h:101
Define a rotation quaternion for a space of dimension 3.
Definition vctQuaternionRotation3Base.h:64
ThisType Normalized(void) const
Definition vctQuaternionRotation3Base.h:532
Define a rotation based on the rodriguez representation for a space of dimension 3.
Definition vctRodriguezRotation3Base.h:68
ThisType & From(const vctAxisAngleRotation3< value_type > &axisAngleRotation)
Definition vctRodriguezRotation3Base.h:167
ThisType & InverseOf(const ThisType &otherRotation)
Definition vctRodriguezRotation3Base.h:272
ContainerType ContainerType
Definition vctRodriguezRotation3Base.h:72
ThisType & From(const vctDynamicConstVectorBase< __vectorOwnerType, value_type > &vector) CISST_THROW(std
Definition vctRodriguezRotation3Base.h:142
ThisType & FromNormalized(const vctFixedSizeConstVectorBase< 3, __stride, value_type, __dataPtrType > &vector)
Definition vctRodriguezRotation3Base.h:175
ThisType & FromRaw(const vctDynamicConstVectorBase< __vectorOwnerType, value_type > &vector)
Definition vctRodriguezRotation3Base.h:236
ThisType & From(const vctQuaternionRotation3Base< __containerType > &quaternionRotation) CISST_THROW(std
Definition vctRodriguezRotation3Base.h:152
ThisType & From(const vctMatrixRotation3Base< __containerType > &matrixRotation)
Definition vctRodriguezRotation3Base.h:161
bool IsNormalized(value_type CMN_UNUSED(tolerance)=TypeTraits::Tolerance()) const
Definition vctRodriguezRotation3Base.h:317
ContainerType BaseType
Definition vctRodriguezRotation3Base.h:71
ThisType & FromNormalized(const vctMatrixRotation3Base< __containerType > &matrixRotation)
Definition vctRodriguezRotation3Base.h:207
ThisType & FromNormalized(const vctQuaternionRotation3Base< __containerType > &quaternionRotation)
Definition vctRodriguezRotation3Base.h:200
ThisType & InverseSelf(void)
Definition vctRodriguezRotation3Base.h:267
ThisType & FromRaw(value_type x, value_type y, value_type z)
Definition vctRodriguezRotation3Base.h:228
ThisType & FromNormalized(const vctDynamicConstVectorBase< __vectorOwnerType, value_type > &vector) CISST_THROW(std
Definition vctRodriguezRotation3Base.h:191
ThisType & NormalizedOf(const ThisType &otherRotation)
Definition vctRodriguezRotation3Base.h:295
cmnTypeTraits< value_type > TypeTraits
Definition vctRodriguezRotation3Base.h:77
@ DIMENSION
Definition vctRodriguezRotation3Base.h:70
void ThrowUnlessIsNormalized(void) const CISST_THROW(std
Definition vctRodriguezRotation3Base.h:82
ThisType & FromRaw(const vctFixedSizeConstVectorBase< 3, __stride, value_type, __dataPtrType > &vector)
Definition vctRodriguezRotation3Base.h:221
vctRodriguezRotation3Base(const vctFixedSizeConstVectorBase< DIMENSION, __stride, value_type, __dataPtrType > &axis)
Definition vctRodriguezRotation3Base.h:110
ThisType & FromRaw(const vctQuaternionRotation3Base< __containerType > &quaternionRotation)
Definition vctRodriguezRotation3Base.h:247
ThisType Normalized(void) const
Definition vctRodriguezRotation3Base.h:302
bool AlmostEquivalent(const ThisType &other, value_type tolerance=TypeTraits::Tolerance()) const
Definition vctRodriguezRotation3Base.h:330
ThisType & FromRaw(const vctAxisAngleRotation3< value_type > &axisAngleRotation)
Definition vctRodriguezRotation3Base.h:260
ThisType & NormalizedSelf(void)
Definition vctRodriguezRotation3Base.h:284
ThisType & From(value_type x, value_type y, value_type z) CISST_THROW(std
Definition vctRodriguezRotation3Base.h:132
ThisType & FromRaw(const vctMatrixRotation3Base< __containerType > &matrixRotation)
Definition vctRodriguezRotation3Base.h:254
static CISST_EXPORT const ThisType & Identity()
ThisType & From(const vctFixedSizeConstVectorBase< 3, __stride, value_type, __dataPtrType > &vector) CISST_THROW(std
Definition vctRodriguezRotation3Base.h:124
ThisType Inverse(void) const
Definition vctRodriguezRotation3Base.h:277
ThisType & FromNormalized(value_type x, value_type y, value_type z)
Definition vctRodriguezRotation3Base.h:182
vctRodriguezRotation3Base< ContainerType > ThisType
Definition vctRodriguezRotation3Base.h:73
ThisType & FromNormalized(const vctAxisAngleRotation3< value_type > &axisAngleRotation)
Definition vctRodriguezRotation3Base.h:212
vctRodriguezRotation3Base()
Definition vctRodriguezRotation3Base.h:102
void ThrowUnlessIsNormalized(const _inputType &input) const CISST_THROW(std
Definition vctRodriguezRotation3Base.h:93
VCT_CONTAINER_TRAITS_TYPEDEFS(typename ContainerType::value_type)
vctRodriguezRotation3Base(value_type x, value_type y, value_type z)
Definition vctRodriguezRotation3Base.h:115
static OutputElementType Operate(const InputElementType &input)
Definition vctUnaryOperations.h:86
Declaration of various constants.
const double cmnPI
Definition cmnConstants.h:38
#define CISST_EXPORT
Definition cmnExportMacros.h:50
#define CMN_UNUSED(argument)
Definition cmnPortability.h:497
#define CISST_THROW(exceptionParameter)
Somewhat portable compilation warning message. This works with very recent versions of gcc (4....
Definition cmnPortability.h:559
void cmnThrow(const _exceptionType &except, cmnLogLevel lod=CMN_LOG_LEVEL_INIT_ERROR)
Definition cmnThrow.h:76
cmnTypeTraits< value_type > TypeTraits
Definition vctDynamicConstMatrixBase.h:147
NormType Norm(void) const
Definition vctDynamicConstMatrixBase.h:467
value_type DotProduct(const vctDynamicConstVectorBase< __vectorOwnerType, _elementType > &otherVector) const
Definition vctDynamicConstVectorBase.h:633
Macros to export the symbols of cisstVector (in a Dll).
Declaration of vctFixedSizeVector.
Forward declarations and #define for cisstVector.
void vctRodriguezRotation3BaseFromRaw(vctRodriguezRotation3Base< _rodriguezType > &rodriguezRotation, const vctMatrixRotation3Base< _matrixType > &matrixRotation)
Definition vctRodriguezRotation3Base.h:400