wfmath 1.0.3
A math library for the Worldforge system.
rotmatrix.h
1// rotmatrix.h (RotMatrix<> class definition)
2//
3// The WorldForge Project
4// Copyright (C) 2001 The WorldForge Project
5//
6// This program is free software; you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 2 of the License, or
9// (at your option) any later version.
10//
11// This program 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
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19//
20// For information about WorldForge and its authors, please contact
21// the Worldforge Web Site at http://www.worldforge.org.
22
23// Author: Ron Steinke
24// Created: 2001-12-7
25
26#ifndef WFMATH_ROTMATRIX_H
27#define WFMATH_ROTMATRIX_H
28
29#include <wfmath/const.h>
30
31#include <iosfwd>
32
33namespace WFMath {
34
36template<int dim> // m1 * m2
37RotMatrix<dim> Prod(const RotMatrix<dim>& m1, const RotMatrix<dim>& m2);
39template<int dim> // m1 * m2^-1
40RotMatrix<dim> ProdInv(const RotMatrix<dim>& m1, const RotMatrix<dim>& m2);
42template<int dim> // m1^-1 * m2
43RotMatrix<dim> InvProd(const RotMatrix<dim>& m1, const RotMatrix<dim>& m2);
45template<int dim> // m1^-1 * m2^-1
46RotMatrix<dim> InvProdInv(const RotMatrix<dim>& m1, const RotMatrix<dim>& m2);
47
48template<int dim> // m * v
49Vector<dim> Prod(const RotMatrix<dim>& m, const Vector<dim>& v);
50template<int dim> // m^-1 * v
51Vector<dim> InvProd(const RotMatrix<dim>& m, const Vector<dim>& v);
52template<int dim> // v * m
53Vector<dim> Prod(const Vector<dim>& v, const RotMatrix<dim>& m);
54template<int dim> // v * m^-1
55Vector<dim> ProdInv(const Vector<dim>& v, const RotMatrix<dim>& m);
56
58template<int dim>
59RotMatrix<dim> operator*(const RotMatrix<dim>& m1, const RotMatrix<dim>& m2);
60template<int dim>
61Vector<dim> operator*(const RotMatrix<dim>& m, const Vector<dim>& v);
62template<int dim>
63Vector<dim> operator*(const Vector<dim>& v, const RotMatrix<dim>& m);
64
65template<int dim>
66std::ostream& operator<<(std::ostream& os, const RotMatrix<dim>& m);
67template<int dim>
68std::istream& operator>>(std::istream& is, RotMatrix<dim>& m);
69
71
86template<int dim = 3>
87class RotMatrix {
88 public:
90 RotMatrix() : m_elem{}, m_flip(false), m_valid(false), m_age(0) {}
92 RotMatrix(const RotMatrix& m) = default;
93
94 friend std::ostream& operator<< <dim>(std::ostream& os, const RotMatrix& m);
95 friend std::istream& operator>> <dim>(std::istream& is, RotMatrix& m);
96
97 RotMatrix& operator=(const RotMatrix& m) = default;
98 // No operator=(CoordType d[dim][dim]), since it can fail.
99 // Use setVals() instead.
100
101 bool isEqualTo(const RotMatrix& m, CoordType epsilon = numeric_constants<CoordType>::epsilon()) const;
102
103 bool operator==(const RotMatrix& m) const {return isEqualTo(m);}
104 bool operator!=(const RotMatrix& m) const {return !isEqualTo(m);}
105
106 bool isValid() const {return m_valid;}
107
110
112 CoordType elem(const int i, const int j) const {return m_elem[i][j];}
113
115
122 bool setVals(const CoordType vals[dim][dim], CoordType precision = numeric_constants<CoordType>::epsilon());
124
131 bool setVals(const CoordType vals[dim*dim], CoordType precision = numeric_constants<CoordType>::epsilon());
132
134 Vector<dim> row(int i) const;
136 Vector<dim> column(int i) const;
137
139 CoordType trace() const;
141
144 CoordType determinant() const {return (m_flip ? -1.f : 1.f);}
146
149 RotMatrix inverse() const;
151
154 bool parity() const {return m_flip;}
155
156 // documented outside the class
157
158 friend RotMatrix Prod<dim> (const RotMatrix& m1, const RotMatrix& m2);
159 friend RotMatrix ProdInv<dim> (const RotMatrix& m1, const RotMatrix& m2);
160 friend RotMatrix InvProd<dim> (const RotMatrix& m1, const RotMatrix& m2);
161 friend RotMatrix InvProdInv<dim> (const RotMatrix& m1, const RotMatrix& m2);
162 friend Vector<dim> Prod<dim> (const RotMatrix& m, const Vector<dim>& v);
163 friend Vector<dim> InvProd<dim> (const RotMatrix& m, const Vector<dim>& v);
164
165 // Set the value to a given rotation
166
168 RotMatrix& rotation (int i, int j, CoordType theta);
170
173 RotMatrix& rotation (const Vector<dim>& v1, const Vector<dim>& v2,
174 CoordType theta);
176
181 RotMatrix& rotation (const Vector<dim>& from, const Vector<dim>& to);
182
183 // Set the value to mirror image about a certain axis
184
188 RotMatrix& mirror(const Vector<dim>& v);
190
193 RotMatrix& mirror();
194
196 RotMatrix& rotate(const RotMatrix& m) {return *this = Prod(*this, m);}
197
199 void normalize();
201 unsigned age() const {return m_age;}
202
203 // 2D/3D stuff
204
206
212 RotMatrix(const Quaternion& q, bool not_flip = true);
213
216 {return rotation(0, 1, theta);}
217
219 RotMatrix& rotationX(CoordType theta) {return rotation(1, 2, theta);}
221 RotMatrix& rotationY(CoordType theta) {return rotation(2, 0, theta);}
223 RotMatrix& rotationZ(CoordType theta) {return rotation(0, 1, theta);}
227
230 RotMatrix& rotation(const Vector<dim>& axis); // angle taken from magnitude of axis
231
233
239 RotMatrix& fromQuaternion(const Quaternion& q, bool not_flip = true);
240
243
245 RotMatrix& mirrorX() {return mirror(0);}
247 RotMatrix& mirrorY() {return mirror(1);}
250
251 private:
252 CoordType m_elem[dim][dim];
253 bool m_flip; // True if the matrix is parity odd
254 bool m_valid;
255 unsigned m_age;
256
257 // Backend to setVals() above, also used in fromStream()
258 bool _setVals(CoordType *vals, CoordType precision = numeric_constants<CoordType>::epsilon());
259 void checkNormalization() {if(m_age >= WFMATH_MAX_NORM_AGE && m_valid) normalize();}
260};
261
262template<>
263inline RotMatrix<3>& RotMatrix<3>::mirrorZ()
264{
265 return mirror(2);
266}
267
268template<int dim>
270{
271 identity();
272 m_elem[i][i] = -1;
273 m_flip = true;
274 // m_valid and m_age already set correctly
275
276 return *this;
277}
278
279} // namespace WFMath
280
281#endif // WFMATH_ROTMATRIX_H
A normalized quaternion.
Definition: quaternion.h:36
A dim dimensional rotation matrix. Technically, a member of the group O(dim).
Definition: rotmatrix.h:87
RotMatrix & rotation(int i, int j, CoordType theta)
set the matrix to a rotation by the angle theta in the (i, j) plane
RotMatrix & mirrorZ()
set a RotMatrix to a mirror perpendicular to the z axis
friend RotMatrix Prod(const RotMatrix &m1, const RotMatrix &m2)
returns m1 * m2
Vector< dim > row(int i) const
Get a copy of the i'th row as a Vector.
RotMatrix & rotationY(CoordType theta)
3D only: set a RotMatrix to a rotation about the y axis by angle theta
Definition: rotmatrix.h:221
Vector< dim > column(int i) const
Get a copy of the i'th column as a Vector.
RotMatrix & rotate(const RotMatrix &m)
rotate the matrix using another matrix
Definition: rotmatrix.h:196
RotMatrix & mirrorX()
set a RotMatrix to a mirror perpendicular to the x axis
Definition: rotmatrix.h:245
RotMatrix & rotation(const Vector< dim > &axis, CoordType theta)
3D only: set a RotMatrix to a rotation about the axis given by the Vector
RotMatrix & identity()
set the matrix to the identity matrix
bool parity() const
Get the parity of the matrix.
Definition: rotmatrix.h:154
CoordType trace() const
Get the trace of the matrix.
CoordType elem(const int i, const int j) const
get the (i, j) element of the matrix
Definition: rotmatrix.h:112
RotMatrix & rotationZ(CoordType theta)
3D only: set a RotMatrix to a rotation about the z axis by angle theta
Definition: rotmatrix.h:223
RotMatrix & mirrorY()
set a RotMatrix to a mirror perpendicular to the y axis
Definition: rotmatrix.h:247
RotMatrix & rotationX(CoordType theta)
3D only: set a RotMatrix to a rotation about the x axis by angle theta
Definition: rotmatrix.h:219
void normalize()
normalize to remove accumulated round-off error
RotMatrix & mirror()
set the matrix to mirror all axes
RotMatrix & rotation(CoordType theta)
2D only: Construct a RotMatrix from an angle theta
Definition: rotmatrix.h:215
RotMatrix(const Quaternion &q, bool not_flip=true)
3D only: Construct a RotMatrix from a Quaternion
RotMatrix & mirror(int i)
set the matrix to a mirror perpendicular to the i'th axis
Definition: rotmatrix.h:269
RotMatrix & fromQuaternion(const Quaternion &q, bool not_flip=true)
3D only: set a RotMatrix from a Quaternion
RotMatrix inverse() const
Get the inverse of the matrix.
unsigned age() const
current round-off age
Definition: rotmatrix.h:201
RotMatrix & rotate(const Quaternion &)
rotate the matrix using the quaternion
RotMatrix & rotation(const Vector< dim > &axis)
3D only: set a RotMatrix to a rotation about the axis given by the Vector
bool setVals(const CoordType vals[dim][dim], CoordType precision=numeric_constants< CoordType >::epsilon())
Set the values of the elements of the matrix.
CoordType determinant() const
Get the determinant of the matrix.
Definition: rotmatrix.h:144
Generic library namespace.
Definition: shape.h:41
double CoordType
Basic floating point type.
Definition: const.h:140
RotMatrix< dim > InvProd(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1^-1 * m2
RotMatrix< dim > Prod(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2
RotMatrix< dim > InvProdInv(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1^-1 * m2^-1
RotMatrix< dim > ProdInv(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2^-1
RotMatrix< dim > operator*(const RotMatrix< dim > &m1, const RotMatrix< dim > &m2)
returns m1 * m2