Templates -- Meow  1.1.4
A C++ template which is unable and also not allowed to compile to obj-file first.
LinearTransformations.h
Go to the documentation of this file.
1 #ifndef math_LinearTransformations_H__
2 #define math_LinearTransformations_H__
3 
4 #include "LinearTransformation.h"
5 #include "Matrix.h"
6 #include "utility.h"
7 #include "../Self.h"
8 #include "../geo/Vectors.h"
9 
10 #include <cstdlib>
11 
12 namespace meow {
13 
19 template<class Scalar>
20 class Rotation3D: public LinearTransformation<Scalar> {
21 private:
22  struct Myself {
23  Vector3D<Scalar> theta_;
24  bool need_;
25 
26  Myself(): theta_(0, 0, 0), need_(true) {
27  }
28 
29  Myself(Myself const& b): theta_(b.theta_), need_(b.need_) {
30  }
31 
32  ~Myself() {
33  }
34  };
35 
36  Self<Myself> const self;
37 
38  void calcMatrix() const {
39  if (self->need_) {
40  Matrix<Scalar> tmp(3, 3, 0.0);
41  if (noEPS(self->theta_.length2()) == 0) {
42  tmp.identitied();
43  }
44  else {
45  Vector3D<double> axis (self->theta_.normalize());
46  double angle(self->theta_.length());
47  double cs(cos(angle / 2.0));
48  double sn(sin(angle / 2.0));
49 
50  tmp.entry(0, 0, 2*(squ(axis.x())-1.0)*squ(sn) + 1);
51  tmp.entry(1, 1, 2*(squ(axis.y())-1.0)*squ(sn) + 1);
52  tmp.entry(2, 2, 2*(squ(axis.z())-1.0)*squ(sn) + 1);
53  tmp.entry(0, 1, 2*axis.x()*axis.y()*squ(sn) - 2*axis.z()*cs*sn);
54  tmp.entry(1, 0, 2*axis.y()*axis.x()*squ(sn) + 2*axis.z()*cs*sn);
55  tmp.entry(0, 2, 2*axis.x()*axis.z()*squ(sn) + 2*axis.y()*cs*sn);
56  tmp.entry(2, 0, 2*axis.z()*axis.x()*squ(sn) - 2*axis.y()*cs*sn);
57  tmp.entry(1, 2, 2*axis.y()*axis.z()*squ(sn) - 2*axis.x()*cs*sn);
58  tmp.entry(2, 1, 2*axis.z()*axis.y()*squ(sn) + 2*axis.x()*cs*sn);
59  }
60  ((Rotation3D*)this)->LinearTransformation<Scalar>::matrix(tmp);
61  self()->need_ = false;
62  }
63  }
64 
65 public:
69  Rotation3D(): LinearTransformation<Scalar>(3u, 3u, 3u), self() {
70  }
71 
76  self(b.self, Self<Myself>::COPY_FROM) {
77  }
78 
83  }
84 
93  self().copyFrom(b.self);
94  return *this;
95  }
96 
105  self().referenceFrom(b.self);
106  return *this;
107  }
108 
112  Scalar parameter(size_t i) const {
113  return theta(i);
114  }
115 
119  Scalar parameter(size_t i, Scalar const& s) {
120  return theta(i, s);
121  }
122 
131  Scalar const& theta(size_t i) const {
132  return self->theta_(i);
133  }
134 
144  Scalar const& theta(size_t i, Scalar const& s) {
145  if (theta(i) != s) {
146  if (i == 0) self()->theta_.x(s);
147  else if (i == 1) self()->theta_.y(s);
148  else if (i == 2) self()->theta_.z(s);
149  self()->need_ = true;
150  }
151  return theta(i);
152  }
153 
160  void axisAngle(Vector<Scalar> const& axis, Scalar const& angle) {
161  Vector<Scalar> n(axis.normalize());
162  for (size_t i = 0; i < 3; i++) {
163  theta(i, n(i) * angle);
164  }
165  }
166 
171  Rotation3D& add(Rotation3D const& r) {
172  for (size_t i = 0; i < 3; i++) {
173  theta(i, r.theta(i));
174  }
175  return *this;
176  }
177 
214  calcMatrix();
216  }
217 
244  calcMatrix();
246  }
247 
320  Matrix<Scalar> jacobian(Matrix<Scalar> const& x, size_t i) const {
321  calcMatrix();
322  Matrix<Scalar> mid(3u, 3u, Scalar(0.0));
323  if (i == 0) {
324  mid.entry(1, 2, Scalar(-1.0));
325  mid.entry(2, 1, Scalar( 1.0));
326  }
327  else if(i == 1) {
328  mid.entry(0, 2, Scalar( 1.0));
329  mid.entry(2, 0, Scalar(-1.0));
330  }
331  else {
332  mid.entry(0, 1, Scalar(-1.0));
333  mid.entry(1, 0, Scalar( 1.0));
334  }
335  return mid * LinearTransformation<Scalar>::matrix() * x;
336  }
337 
345  return matrixInv() * x;
346  }
347 
355  return matrixInv();
356  }
357 
365  Matrix<Scalar> jacobianInv(Matrix<Scalar> const& x, size_t i) const {
366  calcMatrix();
367  Matrix<Scalar> mid(3u, 3u, Scalar(0.0));
368  if (i == 0) {
369  mid.entry(1, 2, Scalar(-1.0));
370  mid.entry(2, 1, Scalar( 1.0));
371  }
372  else if(i == 1) {
373  mid.entry(0, 2, Scalar( 1.0));
374  mid.entry(2, 0, Scalar(-1.0));
375  }
376  else {
377  mid.entry(0, 1, Scalar(-1.0));
378  mid.entry(1, 0, Scalar( 1.0));
379  }
380  return matrixInv() * mid.transpose() * x;
381  return (-mid) * matrixInv() * x;
382  }
383 
392  calcMatrix();
394  }
395 
398  return copyFrom(b);
399  }
400 };
401 
402 }
403 
404 #endif // math_LinearTransformations_H__
Rotation3D & operator=(Rotation3D const &b)
same as copyFrom(b)
Scalar parameter(size_t i, Scalar const &s)
same as theta(i, s)
Matrix< Scalar > jacobian(Matrix< Scalar > const &x, size_t i) const
Return the jacobian matrix of this transformate.
Rotation3D & copyFrom(Rotation3D const &b)
Copy data.
Scalar const & theta(size_t i) const
Get the i -th theta.
Rotation3D & referenceFrom(Rotation3D const &b)
Reference data.
Matrix< Scalar > transformate(Matrix< Scalar > const &x) const
Do the transformate.
Matrix< Scalar > jacobian(Matrix< Scalar > const &x) const
Return the jacobian matrix (derivate by the input vector) of this transformate.
Matrix< Scalar > matrixInv() const
Return the inverse matrix.
A base class for implementing kinds of linear transformations.
Scalar parameter(size_t i) const
same as theta(i)
T noEPS(T value, T eps=1e-9)
如果abs(輸入的數值) < eps, 則回傳0, 否則回傳輸入的數值
Definition: utility.h:18
LinearTransformation & copyFrom(LinearTransformation const &b)
Copy settings, matrix from another LinearTransformation.
vector
Definition: Vector.h:19
Matrix< Scalar > jacobianInv(Matrix< Scalar > const &x) const
Return the jacobian matrix of the inverse form of this transformate.
3D's vector
Definition: Vectors.h:255
Matrix transpose() const
return itself's transpose matrix
Definition: Matrix.h:416
Rotation a point/vector alone an axis with given angle in 3D world.
Rotation3D(Rotation3D const &b)
virtual Matrix< Scalar > const & matrix() const
Return the matrix form of this transformation.
Matrix & identitied()
Let itself be an identity matrix.
Definition: Matrix.h:348
Entry entry(size_t r, size_t c) const
Access the entry at r x c.
Definition: Matrix.h:193
void axisAngle(Vector< Scalar > const &axis, Scalar const &angle)
Setting.
Matrix< Scalar > transformateInv(Matrix< Scalar > const &x) const
Do the inverse transformate.
Rotation3D & add(Rotation3D const &r)
Concat another rotation transformation.
Matrix< Scalar > jacobianInv(Matrix< Scalar > const &x, size_t i) const
Return the jacobian matrix of the inverse form of this transformate.
LinearTransformation & referenceFrom(LinearTransformation const &b)
Reference settings, matrix from another LinearTransformation.
Scalar const & theta(size_t i, Scalar const &s)
Set the i -th theta.
T squ(T const &x)
x*x
Definition: utility.h:67
Vector normalize() const
return a normalize form of itself
Definition: Vector.h:209