Chemical Data Processing Library C++ API - Version 1.4.0
AffineTransform.hpp
Go to the documentation of this file.
1 /*
2  * AffineTransform.hpp
3  *
4  * Copyright (C) 2003 Thomas Seidel <thomas.seidel@univie.ac.at>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library; see the file COPYING. If not, write to
18  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
27 #ifndef CDPL_MATH_AFFINETRANSFORM_HPP
28 #define CDPL_MATH_AFFINETRANSFORM_HPP
29 
30 #include <algorithm>
31 #include <cmath>
32 #include <limits>
33 #include <cstddef>
34 #include <vector>
35 #include <utility>
36 
37 #include "CDPL/Math/Check.hpp"
38 #include "CDPL/Math/Expression.hpp"
39 #include "CDPL/Base/Exceptions.hpp"
40 
41 
42 namespace CDPL
43 {
44 
45  namespace Math
46  {
47 
48  template <typename V>
49  class MatrixReference;
50  template <typename T, typename A>
51  class Vector;
52  template <typename T, typename A>
53  class Matrix;
54 
64  template <typename T>
65  class RotationMatrix : public MatrixContainer<RotationMatrix<T> >
66  {
67 
69 
70  public:
72  typedef T ValueType;
74  typedef const T Reference;
76  typedef const T ConstReference;
78  typedef std::size_t SizeType;
80  typedef std::ptrdiff_t DifferenceType;
89 
96  template <typename E>
98  size(n)
99  {
100  set(q);
101  }
102 
115  template <typename T1, typename T2, typename T3, typename T4>
116  RotationMatrix(SizeType n, const T1& w, const T2& ux, const T3& uy, const T4& uz):
117  size(n)
118  {
119  set(w, ux, uy, uz);
120  }
121 
127  size(m.size)
128  {
129  std::copy(m.data, m.data + 4, data);
130  }
131 
137  template <typename E>
139  {
140  data[0] = q().getC1();
141  data[1] = q().getC2();
142  data[2] = q().getC3();
143  data[3] = q().getC4();
144  }
145 
157  template <typename T1, typename T2, typename T3, typename T4>
158  void set(const T1& w, const T2& ux, const T3& uy, const T4& uz)
159  {
160  data[0] = std::cos(w / 2.0);
161  data[1] = std::sin(w / 2.0) * ux;
162  data[2] = std::sin(w / 2.0) * uy;
163  data[3] = std::sin(w / 2.0) * uz;
164  }
165 
174  {
175  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
176 
177  if (i >= 3 || i >= size || j >= 3 || j >= size)
178  return (i == j ? ValueType(1) : ValueType());
179 
180  switch (i) {
181 
182  case 0:
183  switch (j) {
184 
185  case 0:
186  // a2 + b2 - c2 - d2
187  return (data[0] * data[0] + data[1] * data[1] - data[2] * data[2] - data[3] * data[3]);
188 
189  case 1:
190  // 2(bc - ad)
191  return 2 * (data[1] * data[2] - data[0] * data[3]);
192 
193  case 2:
194  // 2(bd + ac)
195  return 2 * (data[1] * data[3] + data[0] * data[2]);
196 
197  default:
198  return ValueType();
199  }
200 
201  case 1:
202  switch (j) {
203 
204  case 0:
205  // 2(bc + ad)
206  return 2 * (data[1] * data[2] + data[0] * data[3]);
207 
208  case 1:
209  // a2 - b2 + c2 - d2
210  return (data[0] * data[0] - data[1] * data[1] + data[2] * data[2] - data[3] * data[3]);
211 
212  case 2:
213  // 2(cd - ab)
214  return 2 * (data[2] * data[3] - data[0] * data[1]);
215 
216  default:
217  return ValueType();
218  }
219 
220  case 2:
221  switch (j) {
222 
223  case 0:
224  // 2(bd - ac)
225  return 2 * (data[1] * data[3] - data[0] * data[2]);
226 
227  case 1:
228  // 2(cd + ab)
229  return 2 * (data[2] * data[3] + data[0] * data[1]);
230 
231  case 2:
232  // a2 - b2 - c2 + d2
233  return (data[0] * data[0] - data[1] * data[1] - data[2] * data[2] + data[3] * data[3]);
234 
235  default:
236  return ValueType();
237  }
238 
239  default:
240  return (i == j ? ValueType(1) : ValueType());
241  }
242  }
243 
248  bool isEmpty() const
249  {
250  return (size == 0);
251  }
252 
258  {
259  return size;
260  }
261 
267  {
268  return size;
269  }
270 
276  {
277  return std::numeric_limits<SizeType>::max();
278  }
279 
285  {
286  return std::numeric_limits<SizeType>::max();
287  }
288 
295  {
296  if (this != &m) {
297  std::copy(m.data, m.data + 4, data);
298  size = m.size;
299  }
300 
301  return *this;
302  }
303 
309  {
310  if (this != &m) {
311  std::swap_ranges(data, data + 4, m.data);
312  std::swap(size, m.size);
313  }
314  }
315 
321  friend void swap(RotationMatrix& m1, RotationMatrix& m2)
322  {
323  m1.swap(m2);
324  }
325 
330  void resize(SizeType n)
331  {
332  size = n;
333  }
334 
335  private:
336  typedef ValueType ArrayType[4];
337 
338  SizeType size;
339  ArrayType data;
340  };
341 
350  template <typename T>
351  class ScalingMatrix : public MatrixContainer<ScalingMatrix<T> >
352  {
353 
354  typedef ScalingMatrix<T> SelfType;
355 
356  public:
358  typedef T ValueType;
360  typedef const T Reference;
362  typedef const T ConstReference;
364  typedef std::size_t SizeType;
366  typedef std::ptrdiff_t DifferenceType;
375 
383  explicit ScalingMatrix(SizeType n, const ValueType& sx = ValueType(1),
384  const ValueType& sy = ValueType(1), const ValueType& sz = ValueType(1)):
385  size(n)
386  {
387  set(sx, sy, sz);
388  }
389 
395  size(m.size)
396  {
397  std::copy(m.data, m.data + 3, data);
398  }
399 
406  void set(const ValueType& sx = ValueType(1), const ValueType& sy = ValueType(1),
407  const ValueType& sz = ValueType(1))
408  {
409  data[0] = sx;
410  data[1] = sy;
411  data[2] = sz;
412  }
413 
422  {
423  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
424 
425  if (i != j)
426  return ValueType();
427 
428  if (i < size && i < 3)
429  return data[i];
430 
431  return ValueType(1);
432  }
433 
438  bool isEmpty() const
439  {
440  return (size == 0);
441  }
442 
448  {
449  return size;
450  }
451 
457  {
458  return size;
459  }
460 
466  {
467  return std::numeric_limits<SizeType>::max();
468  }
469 
475  {
476  return std::numeric_limits<SizeType>::max();
477  }
478 
485  {
486  if (this != &m) {
487  std::copy(m.data, m.data + 3, data);
488  size = m.size;
489  }
490 
491  return *this;
492  }
493 
499  {
500  if (this != &m) {
501  std::swap_ranges(data, data + 3, m.data);
502  std::swap(size, m.size);
503  }
504  }
505 
511  friend void swap(ScalingMatrix& m1, ScalingMatrix& m2)
512  {
513  m1.swap(m2);
514  }
515 
520  void resize(SizeType n)
521  {
522  size = n;
523  }
524 
525  private:
526  typedef ValueType ArrayType[3];
527 
528  SizeType size;
529  ArrayType data;
530  };
531 
541  template <typename T>
542  class TranslationMatrix : public MatrixContainer<TranslationMatrix<T> >
543  {
544 
546 
547  public:
549  typedef T ValueType;
551  typedef const T Reference;
553  typedef const T ConstReference;
555  typedef std::size_t SizeType;
557  typedef std::ptrdiff_t DifferenceType;
566 
574  explicit TranslationMatrix(SizeType n, const ValueType& tx = ValueType(),
575  const ValueType& ty = ValueType(), const ValueType& tz = ValueType()):
576  size(n)
577  {
578  set(tx, ty, tz);
579  }
580 
586  size(m.size)
587  {
588  std::copy(m.data, m.data + 3, data);
589  }
590 
597  void set(const ValueType& tx = ValueType(), const ValueType& ty = ValueType(),
598  const ValueType& tz = ValueType())
599  {
600  data[0] = tx;
601  data[1] = ty;
602  data[2] = tz;
603  }
604 
613  {
614  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
615 
616  if (i == j)
617  return ValueType(1);
618 
619  if (j == (size - 1) && i < size && i < 3)
620  return data[i];
621 
622  return ValueType();
623  }
624 
629  bool isEmpty() const
630  {
631  return (size == 0);
632  }
633 
639  {
640  return size;
641  }
642 
648  {
649  return size;
650  }
651 
657  {
658  return std::numeric_limits<SizeType>::max();
659  }
660 
666  {
667  return std::numeric_limits<SizeType>::max();
668  }
669 
676  {
677  if (this != &m) {
678  std::copy(m.data, m.data + 3, data);
679  size = m.size;
680  }
681 
682  return *this;
683  }
684 
690  {
691  if (this != &m) {
692  std::swap_ranges(data, data + 3, m.data);
693  std::swap(size, m.size);
694  }
695  }
696 
703  {
704  m1.swap(m2);
705  }
706 
711  void resize(SizeType n)
712  {
713  size = n;
714  }
715 
716  private:
717  typedef ValueType ArrayType[3];
718 
719  SizeType size;
720  ArrayType data;
721  };
722 
727 
732 
737  } // namespace Math
738 } // namespace CDPL
739 
740 #endif // CDPL_MATH_AFFINETRANSFORM_HPP
Definition of exception classes.
Definition of various preprocessor macros for error checking.
#define CDPL_MATH_CHECK(expr, msg, e)
Throws the exception e with message msg when the boolean expression expr evaluates to false.
Definition: Check.hpp:47
Definition of basic expression types.
Thrown to indicate that an index is out of range.
Definition: Base/Exceptions.hpp:152
Refinement of Math::MatrixExpression marking the derived type as a concrete (writable) matrix contain...
Definition: Expression.hpp:250
Lightweight matrix expression that proxies a reference to an underlying matrix container.
Definition: Matrix.hpp:64
Dynamically-sized dense row-major matrix with configurable underlying storage.
Definition: Matrix.hpp:455
CRTP base class for all quaternion expression types.
Definition: Expression.hpp:142
rotation matrix backed by a unit quaternion (or an axis-angle representation).
Definition: AffineTransform.hpp:66
void swap(RotationMatrix &m)
Swaps the dimension and the underlying quaternion components with m.
Definition: AffineTransform.hpp:308
const MatrixReference< const SelfType > ConstClosureType
Constant closure type used when this matrix appears inside another expression.
Definition: AffineTransform.hpp:84
void resize(SizeType n)
Resizes the matrix dimension to n (the underlying quaternion is left unchanged).
Definition: AffineTransform.hpp:330
void set(const T1 &w, const T2 &ux, const T3 &uy, const T4 &uz)
Sets the rotation from an axis-angle representation.
Definition: AffineTransform.hpp:158
SizeType getSize1() const
Returns the dimension N (the row count).
Definition: AffineTransform.hpp:257
friend void swap(RotationMatrix &m1, RotationMatrix &m2)
ADL-enabled free-function form of swap().
Definition: AffineTransform.hpp:321
SizeType getMaxSize1() const
Returns the maximum representable row count.
Definition: AffineTransform.hpp:275
RotationMatrix(SizeType n, const QuaternionExpression< E > &q)
Constructs an rotation matrix from the unit quaternion q.
Definition: AffineTransform.hpp:97
RotationMatrix & operator=(const RotationMatrix &m)
Copy-assigns the dimension and the underlying quaternion components from m.
Definition: AffineTransform.hpp:294
std::size_t SizeType
The unsigned size type.
Definition: AffineTransform.hpp:78
MatrixReference< SelfType > ClosureType
Closure type used when this matrix appears inside another expression.
Definition: AffineTransform.hpp:82
bool isEmpty() const
Tells whether the matrix is empty (size zero).
Definition: AffineTransform.hpp:248
RotationMatrix(const RotationMatrix &m)
Constructs a copy of the rotation matrix m.
Definition: AffineTransform.hpp:126
const T Reference
Reference type (always a const reference — elements are computed).
Definition: AffineTransform.hpp:74
void set(const QuaternionExpression< E > &q)
Sets the rotation from the unit quaternion q.
Definition: AffineTransform.hpp:138
const T ConstReference
Constant reference type to an element.
Definition: AffineTransform.hpp:76
RotationMatrix(SizeType n, const T1 &w, const T2 &ux, const T3 &uy, const T4 &uz)
Constructs an rotation matrix from an axis-angle representation.
Definition: AffineTransform.hpp:116
SizeType getMaxSize2() const
Returns the maximum representable column count.
Definition: AffineTransform.hpp:284
Matrix< T, std::vector< T > > MatrixTemporaryType
Concrete temporary matrix type used by expression-template machinery.
Definition: AffineTransform.hpp:86
T ValueType
The scalar value type.
Definition: AffineTransform.hpp:72
Vector< T, std::vector< T > > VectorTemporaryType
Concrete temporary vector type used when assembling vectors from this matrix.
Definition: AffineTransform.hpp:88
std::ptrdiff_t DifferenceType
The signed difference type.
Definition: AffineTransform.hpp:80
SizeType getSize2() const
Returns the dimension N (the column count).
Definition: AffineTransform.hpp:266
ConstReference operator()(SizeType i, SizeType j) const
Returns the rotation-matrix entry at (i, j).
Definition: AffineTransform.hpp:173
diagonal scaling matrix.
Definition: AffineTransform.hpp:352
void resize(SizeType n)
Resizes the matrix dimension to n (the scale factors are left unchanged).
Definition: AffineTransform.hpp:520
ScalingMatrix(const ScalingMatrix &m)
Constructs a copy of the scaling matrix m.
Definition: AffineTransform.hpp:394
Matrix< T, std::vector< T > > MatrixTemporaryType
Concrete temporary matrix type used by expression-template machinery.
Definition: AffineTransform.hpp:372
SizeType getMaxSize2() const
Returns the maximum representable column count.
Definition: AffineTransform.hpp:474
Vector< T, std::vector< T > > VectorTemporaryType
Concrete temporary vector type used when assembling vectors from this matrix.
Definition: AffineTransform.hpp:374
const MatrixReference< const SelfType > ConstClosureType
Constant closure type used when this matrix appears inside another expression.
Definition: AffineTransform.hpp:370
friend void swap(ScalingMatrix &m1, ScalingMatrix &m2)
ADL-enabled free-function form of swap().
Definition: AffineTransform.hpp:511
bool isEmpty() const
Tells whether the matrix is empty (size zero).
Definition: AffineTransform.hpp:438
std::ptrdiff_t DifferenceType
The signed difference type.
Definition: AffineTransform.hpp:366
std::size_t SizeType
The unsigned size type.
Definition: AffineTransform.hpp:364
ConstReference operator()(SizeType i, SizeType j) const
Returns the scaling-matrix entry at (i, j).
Definition: AffineTransform.hpp:421
MatrixReference< SelfType > ClosureType
Closure type used when this matrix appears inside another expression.
Definition: AffineTransform.hpp:368
SizeType getSize2() const
Returns the dimension N (the column count).
Definition: AffineTransform.hpp:456
T ValueType
The scalar value type.
Definition: AffineTransform.hpp:358
SizeType getSize1() const
Returns the dimension N (the row count).
Definition: AffineTransform.hpp:447
ScalingMatrix & operator=(const ScalingMatrix &m)
Copy-assigns the dimension and the per-axis scale factors from m.
Definition: AffineTransform.hpp:484
SizeType getMaxSize1() const
Returns the maximum representable row count.
Definition: AffineTransform.hpp:465
void swap(ScalingMatrix &m)
Swaps the dimension and the per-axis scale factors with m.
Definition: AffineTransform.hpp:498
void set(const ValueType &sx=ValueType(1), const ValueType &sy=ValueType(1), const ValueType &sz=ValueType(1))
Sets the per-axis scale factors.
Definition: AffineTransform.hpp:406
ScalingMatrix(SizeType n, const ValueType &sx=ValueType(1), const ValueType &sy=ValueType(1), const ValueType &sz=ValueType(1))
Constructs an scaling matrix with the supplied per-axis scale factors.
Definition: AffineTransform.hpp:383
const T ConstReference
Constant reference type to an element.
Definition: AffineTransform.hpp:362
const T Reference
Reference type (always a const reference — elements are computed).
Definition: AffineTransform.hpp:360
translation matrix in homogeneous coordinates.
Definition: AffineTransform.hpp:543
const MatrixReference< const SelfType > ConstClosureType
Constant closure type used when this matrix appears inside another expression.
Definition: AffineTransform.hpp:561
friend void swap(TranslationMatrix &m1, TranslationMatrix &m2)
ADL-enabled free-function form of swap().
Definition: AffineTransform.hpp:702
std::ptrdiff_t DifferenceType
The signed difference type.
Definition: AffineTransform.hpp:557
const T Reference
Reference type (always a const reference — elements are computed).
Definition: AffineTransform.hpp:551
SizeType getSize1() const
Returns the dimension N (the row count).
Definition: AffineTransform.hpp:638
Vector< T, std::vector< T > > VectorTemporaryType
Concrete temporary vector type used when assembling vectors from this matrix.
Definition: AffineTransform.hpp:565
const T ConstReference
Constant reference type to an element.
Definition: AffineTransform.hpp:553
TranslationMatrix(const TranslationMatrix &m)
Constructs a copy of the translation matrix m.
Definition: AffineTransform.hpp:585
TranslationMatrix & operator=(const TranslationMatrix &m)
Copy-assigns the dimension and the translation components from m.
Definition: AffineTransform.hpp:675
bool isEmpty() const
Tells whether the matrix is empty (size zero).
Definition: AffineTransform.hpp:629
std::size_t SizeType
The unsigned size type.
Definition: AffineTransform.hpp:555
TranslationMatrix(SizeType n, const ValueType &tx=ValueType(), const ValueType &ty=ValueType(), const ValueType &tz=ValueType())
Constructs an translation matrix with the supplied per-axis translation components.
Definition: AffineTransform.hpp:574
void set(const ValueType &tx=ValueType(), const ValueType &ty=ValueType(), const ValueType &tz=ValueType())
Sets the per-axis translation components.
Definition: AffineTransform.hpp:597
void resize(SizeType n)
Resizes the matrix dimension to n (the translation components are left unchanged).
Definition: AffineTransform.hpp:711
Matrix< T, std::vector< T > > MatrixTemporaryType
Concrete temporary matrix type used by expression-template machinery.
Definition: AffineTransform.hpp:563
T ValueType
The scalar value type.
Definition: AffineTransform.hpp:549
SizeType getMaxSize1() const
Returns the maximum representable row count.
Definition: AffineTransform.hpp:656
ConstReference operator()(SizeType i, SizeType j) const
Returns the translation-matrix entry at (i, j).
Definition: AffineTransform.hpp:612
void swap(TranslationMatrix &m)
Swaps the dimension and the translation components with m.
Definition: AffineTransform.hpp:689
SizeType getSize2() const
Returns the dimension N (the column count).
Definition: AffineTransform.hpp:647
MatrixReference< SelfType > ClosureType
Closure type used when this matrix appears inside another expression.
Definition: AffineTransform.hpp:559
SizeType getMaxSize2() const
Returns the maximum representable column count.
Definition: AffineTransform.hpp:665
Dynamically-sized dense vector with configurable underlying storage.
Definition: Vector.hpp:430
constexpr unsigned int T
Specifies Hydrogen (Tritium).
Definition: AtomType.hpp:67
constexpr unsigned int m
Specifies that the stereocenter has m configuration.
Definition: CIPDescriptor.hpp:116
ScalingMatrix< float > FScalingMatrix
Definition: AffineTransform.hpp:723
RotationMatrix< float > FRotationMatrix
Definition: AffineTransform.hpp:728
TranslationMatrix< long > LTranslationMatrix
Definition: AffineTransform.hpp:735
ScalingMatrix< long > LScalingMatrix
Definition: AffineTransform.hpp:725
RotationMatrix< double > DRotationMatrix
Definition: AffineTransform.hpp:729
ScalingMatrix< double > DScalingMatrix
Definition: AffineTransform.hpp:724
TranslationMatrix< double > DTranslationMatrix
Definition: AffineTransform.hpp:734
TranslationMatrix< unsigned long > ULTranslationMatrix
Definition: AffineTransform.hpp:736
TranslationMatrix< float > FTranslationMatrix
Definition: AffineTransform.hpp:733
ScalingMatrix< unsigned long > ULScalingMatrix
Definition: AffineTransform.hpp:726
RotationMatrix< unsigned long > ULRotationMatrix
Definition: AffineTransform.hpp:731
RotationMatrix< long > LRotationMatrix
Definition: AffineTransform.hpp:730
The namespace of the Chemical Data Processing Library.