Chemical Data Processing Library C++ API - Version 1.2.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 
55  template <typename T>
56  class RotationMatrix : public MatrixContainer<RotationMatrix<T> >
57  {
58 
60 
61  public:
62  typedef T ValueType;
63  typedef const T Reference;
64  typedef const T ConstReference;
65  typedef std::size_t SizeType;
66  typedef std::ptrdiff_t DifferenceType;
71 
72  template <typename E>
74  size(n)
75  {
76  set(q);
77  }
78 
79  template <typename T1, typename T2, typename T3, typename T4>
80  RotationMatrix(SizeType n, const T1& w, const T2& ux, const T3& uy, const T4& uz):
81  size(n)
82  {
83  set(w, ux, uy, uz);
84  }
85 
87  size(m.size)
88  {
89  std::copy(m.data, m.data + 4, data);
90  }
91 
92  template <typename E>
94  {
95  data[0] = q().getC1();
96  data[1] = q().getC2();
97  data[2] = q().getC3();
98  data[3] = q().getC4();
99  }
100 
101  template <typename T1, typename T2, typename T3, typename T4>
102  void set(const T1& w, const T2& ux, const T3& uy, const T4& uz)
103  {
104  data[0] = std::cos(w / 2.0);
105  data[1] = std::sin(w / 2.0) * ux;
106  data[2] = std::sin(w / 2.0) * uy;
107  data[3] = std::sin(w / 2.0) * uz;
108  }
109 
111  {
112  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
113 
114  if (i >= 3 || i >= size || j >= 3 || j >= size)
115  return (i == j ? ValueType(1) : ValueType());
116 
117  switch (i) {
118 
119  case 0:
120  switch (j) {
121 
122  case 0:
123  // a2 + b2 - c2 - d2
124  return (data[0] * data[0] + data[1] * data[1] - data[2] * data[2] - data[3] * data[3]);
125 
126  case 1:
127  // 2(bc - ad)
128  return 2 * (data[1] * data[2] - data[0] * data[3]);
129 
130  case 2:
131  // 2(bd + ac)
132  return 2 * (data[1] * data[3] + data[0] * data[2]);
133 
134  default:
135  return ValueType();
136  }
137 
138  case 1:
139  switch (j) {
140 
141  case 0:
142  // 2(bc + ad)
143  return 2 * (data[1] * data[2] + data[0] * data[3]);
144 
145  case 1:
146  // a2 - b2 + c2 - d2
147  return (data[0] * data[0] - data[1] * data[1] + data[2] * data[2] - data[3] * data[3]);
148 
149  case 2:
150  // 2(cd - ab)
151  return 2 * (data[2] * data[3] - data[0] * data[1]);
152 
153  default:
154  return ValueType();
155  }
156 
157  case 2:
158  switch (j) {
159 
160  case 0:
161  // 2(bd - ac)
162  return 2 * (data[1] * data[3] - data[0] * data[2]);
163 
164  case 1:
165  // 2(cd + ab)
166  return 2 * (data[2] * data[3] + data[0] * data[1]);
167 
168  case 2:
169  // a2 - b2 - c2 + d2
170  return (data[0] * data[0] - data[1] * data[1] - data[2] * data[2] + data[3] * data[3]);
171 
172  default:
173  return ValueType();
174  }
175 
176  default:
177  return (i == j ? ValueType(1) : ValueType());
178  }
179  }
180 
181  bool isEmpty() const
182  {
183  return (size == 0);
184  }
185 
187  {
188  return size;
189  }
190 
192  {
193  return size;
194  }
195 
197  {
198  return std::numeric_limits<SizeType>::max();
199  }
200 
202  {
203  return std::numeric_limits<SizeType>::max();
204  }
205 
207  {
208  if (this != &m) {
209  std::copy(m.data, m.data + 4, data);
210  size = m.size;
211  }
212 
213  return *this;
214  }
215 
217  {
218  if (this != &m) {
219  std::swap_ranges(data, data + 4, m.data);
220  std::swap(size, m.size);
221  }
222  }
223 
224  friend void swap(RotationMatrix& m1, RotationMatrix& m2)
225  {
226  m1.swap(m2);
227  }
228 
229  void resize(SizeType n)
230  {
231  size = n;
232  }
233 
234  private:
235  typedef ValueType ArrayType[4];
236 
237  SizeType size;
238  ArrayType data;
239  };
240 
241  template <typename T>
242  class ScalingMatrix : public MatrixContainer<ScalingMatrix<T> >
243  {
244 
245  typedef ScalingMatrix<T> SelfType;
246 
247  public:
248  typedef T ValueType;
249  typedef const T Reference;
250  typedef const T ConstReference;
251  typedef std::size_t SizeType;
252  typedef std::ptrdiff_t DifferenceType;
257 
258  explicit ScalingMatrix(SizeType n, const ValueType& sx = ValueType(1),
259  const ValueType& sy = ValueType(1), const ValueType& sz = ValueType(1)):
260  size(n)
261  {
262  set(sx, sy, sz);
263  }
264 
266  size(m.size)
267  {
268  std::copy(m.data, m.data + 3, data);
269  }
270 
271  void set(const ValueType& sx = ValueType(1), const ValueType& sy = ValueType(1),
272  const ValueType& sz = ValueType(1))
273  {
274  data[0] = sx;
275  data[1] = sy;
276  data[2] = sz;
277  }
278 
280  {
281  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
282 
283  if (i != j)
284  return ValueType();
285 
286  if (i < size && i < 3)
287  return data[i];
288 
289  return ValueType(1);
290  }
291 
292  bool isEmpty() const
293  {
294  return (size == 0);
295  }
296 
298  {
299  return size;
300  }
301 
303  {
304  return size;
305  }
306 
308  {
309  return std::numeric_limits<SizeType>::max();
310  }
311 
313  {
314  return std::numeric_limits<SizeType>::max();
315  }
316 
318  {
319  if (this != &m) {
320  std::copy(m.data, m.data + 3, data);
321  size = m.size;
322  }
323 
324  return *this;
325  }
326 
328  {
329  if (this != &m) {
330  std::swap_ranges(data, data + 3, m.data);
331  std::swap(size, m.size);
332  }
333  }
334 
335  friend void swap(ScalingMatrix& m1, ScalingMatrix& m2)
336  {
337  m1.swap(m2);
338  }
339 
340  void resize(SizeType n)
341  {
342  size = n;
343  }
344 
345  private:
346  typedef ValueType ArrayType[3];
347 
348  SizeType size;
349  ArrayType data;
350  };
351 
352  template <typename T>
353  class TranslationMatrix : public MatrixContainer<TranslationMatrix<T> >
354  {
355 
357 
358  public:
359  typedef T ValueType;
360  typedef const T Reference;
361  typedef const T ConstReference;
362  typedef std::size_t SizeType;
363  typedef std::ptrdiff_t DifferenceType;
368 
369  explicit TranslationMatrix(SizeType n, const ValueType& tx = ValueType(),
370  const ValueType& ty = ValueType(), const ValueType& tz = ValueType()):
371  size(n)
372  {
373  set(tx, ty, tz);
374  }
375 
377  size(m.size)
378  {
379  std::copy(m.data, m.data + 3, data);
380  }
381 
382  void set(const ValueType& tx = ValueType(), const ValueType& ty = ValueType(),
383  const ValueType& tz = ValueType())
384  {
385  data[0] = tx;
386  data[1] = ty;
387  data[2] = tz;
388  }
389 
391  {
392  CDPL_MATH_CHECK(i < getSize1() && j < getSize2(), "Index out of range", Base::IndexError);
393 
394  if (i == j)
395  return ValueType(1);
396 
397  if (j == (size - 1) && i < size && i < 3)
398  return data[i];
399 
400  return ValueType();
401  }
402 
403  bool isEmpty() const
404  {
405  return (size == 0);
406  }
407 
409  {
410  return size;
411  }
412 
414  {
415  return size;
416  }
417 
419  {
420  return std::numeric_limits<SizeType>::max();
421  }
422 
424  {
425  return std::numeric_limits<SizeType>::max();
426  }
427 
429  {
430  if (this != &m) {
431  std::copy(m.data, m.data + 3, data);
432  size = m.size;
433  }
434 
435  return *this;
436  }
437 
439  {
440  if (this != &m) {
441  std::swap_ranges(data, data + 3, m.data);
442  std::swap(size, m.size);
443  }
444  }
445 
447  {
448  m1.swap(m2);
449  }
450 
451  void resize(SizeType n)
452  {
453  size = n;
454  }
455 
456  private:
457  typedef ValueType ArrayType[3];
458 
459  SizeType size;
460  ArrayType data;
461  };
462 
467 
472 
477  } // namespace Math
478 } // namespace CDPL
479 
480 #endif // CDPL_MATH_AFFINETRANSFORM_HPP
Definition of exception classes.
Definition of various preprocessor macros for error checking.
#define CDPL_MATH_CHECK(expr, msg, e)
Definition: Check.hpp:36
Definition of basic expression types.
Thrown to indicate that an index is out of range.
Definition: Base/Exceptions.hpp:152
Definition: Expression.hpp:164
Definition: Matrix.hpp:60
Definition: Matrix.hpp:280
Definition: Expression.hpp:98
Definition: AffineTransform.hpp:57
void swap(RotationMatrix &m)
Definition: AffineTransform.hpp:216
const MatrixReference< const SelfType > ConstClosureType
Definition: AffineTransform.hpp:68
void resize(SizeType n)
Definition: AffineTransform.hpp:229
void set(const T1 &w, const T2 &ux, const T3 &uy, const T4 &uz)
Definition: AffineTransform.hpp:102
SizeType getSize1() const
Definition: AffineTransform.hpp:186
friend void swap(RotationMatrix &m1, RotationMatrix &m2)
Definition: AffineTransform.hpp:224
SizeType getMaxSize1() const
Definition: AffineTransform.hpp:196
RotationMatrix(SizeType n, const QuaternionExpression< E > &q)
Definition: AffineTransform.hpp:73
RotationMatrix & operator=(const RotationMatrix &m)
Definition: AffineTransform.hpp:206
std::size_t SizeType
Definition: AffineTransform.hpp:65
MatrixReference< SelfType > ClosureType
Definition: AffineTransform.hpp:67
bool isEmpty() const
Definition: AffineTransform.hpp:181
RotationMatrix(const RotationMatrix &m)
Definition: AffineTransform.hpp:86
const T Reference
Definition: AffineTransform.hpp:63
void set(const QuaternionExpression< E > &q)
Definition: AffineTransform.hpp:93
const T ConstReference
Definition: AffineTransform.hpp:64
RotationMatrix(SizeType n, const T1 &w, const T2 &ux, const T3 &uy, const T4 &uz)
Definition: AffineTransform.hpp:80
SizeType getMaxSize2() const
Definition: AffineTransform.hpp:201
Matrix< T, std::vector< T > > MatrixTemporaryType
Definition: AffineTransform.hpp:69
T ValueType
Definition: AffineTransform.hpp:62
Vector< T, std::vector< T > > VectorTemporaryType
Definition: AffineTransform.hpp:70
std::ptrdiff_t DifferenceType
Definition: AffineTransform.hpp:66
SizeType getSize2() const
Definition: AffineTransform.hpp:191
ConstReference operator()(SizeType i, SizeType j) const
Definition: AffineTransform.hpp:110
Definition: AffineTransform.hpp:243
void resize(SizeType n)
Definition: AffineTransform.hpp:340
ScalingMatrix(const ScalingMatrix &m)
Definition: AffineTransform.hpp:265
Matrix< T, std::vector< T > > MatrixTemporaryType
Definition: AffineTransform.hpp:255
SizeType getMaxSize2() const
Definition: AffineTransform.hpp:312
Vector< T, std::vector< T > > VectorTemporaryType
Definition: AffineTransform.hpp:256
const MatrixReference< const SelfType > ConstClosureType
Definition: AffineTransform.hpp:254
friend void swap(ScalingMatrix &m1, ScalingMatrix &m2)
Definition: AffineTransform.hpp:335
bool isEmpty() const
Definition: AffineTransform.hpp:292
std::ptrdiff_t DifferenceType
Definition: AffineTransform.hpp:252
std::size_t SizeType
Definition: AffineTransform.hpp:251
ConstReference operator()(SizeType i, SizeType j) const
Definition: AffineTransform.hpp:279
MatrixReference< SelfType > ClosureType
Definition: AffineTransform.hpp:253
SizeType getSize2() const
Definition: AffineTransform.hpp:302
T ValueType
Definition: AffineTransform.hpp:248
SizeType getSize1() const
Definition: AffineTransform.hpp:297
ScalingMatrix & operator=(const ScalingMatrix &m)
Definition: AffineTransform.hpp:317
SizeType getMaxSize1() const
Definition: AffineTransform.hpp:307
void swap(ScalingMatrix &m)
Definition: AffineTransform.hpp:327
void set(const ValueType &sx=ValueType(1), const ValueType &sy=ValueType(1), const ValueType &sz=ValueType(1))
Definition: AffineTransform.hpp:271
ScalingMatrix(SizeType n, const ValueType &sx=ValueType(1), const ValueType &sy=ValueType(1), const ValueType &sz=ValueType(1))
Definition: AffineTransform.hpp:258
const T ConstReference
Definition: AffineTransform.hpp:250
const T Reference
Definition: AffineTransform.hpp:249
Definition: AffineTransform.hpp:354
const MatrixReference< const SelfType > ConstClosureType
Definition: AffineTransform.hpp:365
friend void swap(TranslationMatrix &m1, TranslationMatrix &m2)
Definition: AffineTransform.hpp:446
std::ptrdiff_t DifferenceType
Definition: AffineTransform.hpp:363
const T Reference
Definition: AffineTransform.hpp:360
SizeType getSize1() const
Definition: AffineTransform.hpp:408
Vector< T, std::vector< T > > VectorTemporaryType
Definition: AffineTransform.hpp:367
const T ConstReference
Definition: AffineTransform.hpp:361
TranslationMatrix(const TranslationMatrix &m)
Definition: AffineTransform.hpp:376
TranslationMatrix & operator=(const TranslationMatrix &m)
Definition: AffineTransform.hpp:428
bool isEmpty() const
Definition: AffineTransform.hpp:403
std::size_t SizeType
Definition: AffineTransform.hpp:362
TranslationMatrix(SizeType n, const ValueType &tx=ValueType(), const ValueType &ty=ValueType(), const ValueType &tz=ValueType())
Definition: AffineTransform.hpp:369
void set(const ValueType &tx=ValueType(), const ValueType &ty=ValueType(), const ValueType &tz=ValueType())
Definition: AffineTransform.hpp:382
void resize(SizeType n)
Definition: AffineTransform.hpp:451
Matrix< T, std::vector< T > > MatrixTemporaryType
Definition: AffineTransform.hpp:366
T ValueType
Definition: AffineTransform.hpp:359
SizeType getMaxSize1() const
Definition: AffineTransform.hpp:418
ConstReference operator()(SizeType i, SizeType j) const
Definition: AffineTransform.hpp:390
void swap(TranslationMatrix &m)
Definition: AffineTransform.hpp:438
SizeType getSize2() const
Definition: AffineTransform.hpp:413
MatrixReference< SelfType > ClosureType
Definition: AffineTransform.hpp:364
SizeType getMaxSize2() const
Definition: AffineTransform.hpp:423
Definition: Vector.hpp:258
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:463
RotationMatrix< float > FRotationMatrix
Definition: AffineTransform.hpp:468
TranslationMatrix< long > LTranslationMatrix
Definition: AffineTransform.hpp:475
ScalingMatrix< long > LScalingMatrix
Definition: AffineTransform.hpp:465
RotationMatrix< double > DRotationMatrix
Definition: AffineTransform.hpp:469
ScalingMatrix< double > DScalingMatrix
Definition: AffineTransform.hpp:464
TranslationMatrix< double > DTranslationMatrix
Definition: AffineTransform.hpp:474
TranslationMatrix< unsigned long > ULTranslationMatrix
Definition: AffineTransform.hpp:476
TranslationMatrix< float > FTranslationMatrix
Definition: AffineTransform.hpp:473
ScalingMatrix< unsigned long > ULScalingMatrix
Definition: AffineTransform.hpp:466
RotationMatrix< unsigned long > ULRotationMatrix
Definition: AffineTransform.hpp:471
RotationMatrix< long > LRotationMatrix
Definition: AffineTransform.hpp:470
The namespace of the Chemical Data Processing Library.