40 class Matrix_3 :
public std::array<Vector_3<T>,3>
56 using typename std::array<Vector_3<T>, 3>::size_type;
57 using typename std::array<Vector_3<T>, 3>::difference_type;
58 using typename std::array<Vector_3<T>, 3>::value_type;
59 using typename std::array<Vector_3<T>, 3>::iterator;
60 using typename std::array<Vector_3<T>, 3>::const_iterator;
78 constexpr
Matrix_3(
const column_type& c1,
const column_type& c2,
const column_type& c3)
79 : std::array<Vector_3<T>,3>{{c1, c2, c3}} {}
89 : std::array<Vector_3<T>,3>{{
Vector_3<T>(T(1),T(0),T(0)),
97 static_cast<U
>((*this)(0,0)),
static_cast<U
>((*this)(0,1)),
static_cast<U
>((*this)(0,2)),
98 static_cast<U
>((*this)(1,0)),
static_cast<U
>((*this)(1,1)),
static_cast<U
>((*this)(1,2)),
99 static_cast<U
>((*this)(2,0)),
static_cast<U
>((*this)(2,1)),
static_cast<U
>((*this)(2,2)));
103 static constexpr size_type row_count() {
return 3; }
106 static constexpr size_type col_count() {
return 3; }
112 constexpr
inline T operator()(size_type row, size_type col)
const {
113 return (*
this)[col][row];
120 inline T& operator()(size_type row, size_type col) {
121 return (*
this)[col][row];
127 constexpr
const column_type& column(size_type col)
const {
136 column_type& column(size_type col) {
146 return { (*this)[0][row], (*this)[1][row], (*this)[2][row] };
150 const element_type* elements()
const {
151 return column(0).data();
155 element_type* elements() {
156 return column(0).data();
161 (*this)[0].setZero();
162 (*this)[1].setZero();
163 (*this)[2].setZero();
167 Matrix_3& operator=(
Zero) {
189 constexpr
bool operator==(
const Matrix_3& b)
const {
190 return (b[0] == (*
this)[0]) && (b[1] == (*this)[1]) && (b[2] == (*
this)[2]);
195 constexpr
bool operator!=(
const Matrix_3& b)
const {
196 return !(*
this == b);
204 inline bool equals(
const Matrix_3& m, T tolerance = T(FLOATTYPE_EPSILON))
const {
205 for(size_type i = 0; i < col_count(); i++)
206 if(!column(i).equals(m.column(i), tolerance))
return false;
213 inline bool isZero(T tolerance = T(FLOATTYPE_EPSILON))
const {
214 for(size_type i = 0; i < col_count(); i++)
215 if(!column(i).isZero(tolerance))
return false;
224 Matrix_3 inverse()
const {
225 T det = determinant();
227 return Matrix_3(((*
this)[1][1]*(*
this)[2][2] - (*
this)[1][2]*(*
this)[2][1])/det,
228 ((*
this)[2][0]*(*
this)[1][2] - (*
this)[1][0]*(*
this)[2][2])/det,
229 ((*
this)[1][0]*(*
this)[2][1] - (*
this)[1][1]*(*
this)[2][0])/det,
230 ((*
this)[2][1]*(*
this)[0][2] - (*
this)[0][1]*(*
this)[2][2])/det,
231 ((*
this)[0][0]*(*
this)[2][2] - (*
this)[2][0]*(*
this)[0][2])/det,
232 ((*
this)[0][1]*(*
this)[2][0] - (*
this)[0][0]*(*
this)[2][1])/det,
233 ((*
this)[0][1]*(*
this)[1][2] - (*
this)[1][1]*(*
this)[0][2])/det,
234 ((*
this)[0][2]*(*
this)[1][0] - (*
this)[0][0]*(*
this)[1][2])/det,
235 ((*
this)[0][0]*(*
this)[1][1] - (*
this)[1][0]*(*
this)[0][1])/det);
244 bool inverse(Matrix_3& result, T epsilon = T(FLOATTYPE_EPSILON))
const {
245 T det = determinant();
246 if(std::abs(det) <= epsilon)
return false;
247 result =
Matrix_3(((*
this)[1][1]*(*
this)[2][2] - (*
this)[1][2]*(*
this)[2][1])/det,
248 ((*
this)[2][0]*(*
this)[1][2] - (*
this)[1][0]*(*
this)[2][2])/det,
249 ((*
this)[1][0]*(*
this)[2][1] - (*
this)[1][1]*(*
this)[2][0])/det,
250 ((*
this)[2][1]*(*
this)[0][2] - (*
this)[0][1]*(*
this)[2][2])/det,
251 ((*
this)[0][0]*(*
this)[2][2] - (*
this)[2][0]*(*
this)[0][2])/det,
252 ((*
this)[0][1]*(*
this)[2][0] - (*
this)[0][0]*(*
this)[2][1])/det,
253 ((*
this)[0][1]*(*
this)[1][2] - (*
this)[1][1]*(*
this)[0][2])/det,
254 ((*
this)[0][2]*(*
this)[1][0] - (*
this)[0][0]*(*
this)[1][2])/det,
255 ((*
this)[0][0]*(*
this)[1][1] - (*
this)[1][0]*(*
this)[0][1])/det);
260 constexpr
inline T determinant()
const {
261 return(((*
this)[0][0]*(*
this)[1][1] - (*
this)[0][1]*(*
this)[1][0])*((*
this)[2][2])
262 -((*
this)[0][0]*(*
this)[1][2] - (*
this)[0][2]*(*
this)[1][0])*((*
this)[2][1])
263 +((*
this)[0][1]*(*
this)[1][2] - (*
this)[0][2]*(*
this)[1][1])*((*
this)[2][0]));
267 constexpr Matrix_3 transposed()
const {
268 return Matrix_3((*
this)[0][0], (*
this)[0][1], (*
this)[0][2],
269 (*
this)[1][0], (*
this)[1][1], (*
this)[1][2],
270 (*
this)[2][0], (*
this)[2][1], (*
this)[2][2]);
278 return (*
this)[0][index] * p[0] + (*this)[1][index] * p[1] + (*this)[2][index] * p[2];
286 return (*
this)[0][index] * v[0] + (*this)[1][index] * v[1] + (*this)[2][index] * v[2];
293 constexpr
bool isOrthogonalMatrix(T epsilon = T(FLOATTYPE_EPSILON))
const {
295 (std::abs((*
this)[0][0]*(*
this)[1][0] + (*
this)[0][1]*(*
this)[1][1] + (*
this)[0][2]*(*
this)[1][2]) <= epsilon) &&
296 (std::abs((*
this)[0][0]*(*
this)[2][0] + (*
this)[0][1]*(*
this)[2][1] + (*
this)[0][2]*(*
this)[2][2]) <= epsilon) &&
297 (std::abs((*
this)[1][0]*(*
this)[2][0] + (*
this)[1][1]*(*
this)[2][1] + (*
this)[1][2]*(*
this)[2][2]) <= epsilon) &&
298 (std::abs((*
this)[0][0]*(*
this)[0][0] + (*
this)[0][1]*(*
this)[0][1] + (*
this)[0][2]*(*
this)[0][2] - T(1)) <= epsilon) &&
299 (std::abs((*
this)[1][0]*(*
this)[1][0] + (*
this)[1][1]*(*
this)[1][1] + (*
this)[1][2]*(*
this)[1][2] - T(1)) <= epsilon) &&
300 (std::abs((*
this)[2][0]*(*
this)[2][0] + (*
this)[2][1]*(*
this)[2][1] + (*
this)[2][2]*(*
this)[2][2] - T(1)) <= epsilon);
309 constexpr
bool isRotationMatrix(T epsilon = T(FLOATTYPE_EPSILON))
const {
310 return isOrthogonalMatrix(epsilon) && (std::abs(determinant() - T(1)) <= epsilon);
324 void orthonormalize() {
327 (*this)[0].normalize();
330 T dot0 = (*this)[0].dot((*
this)[1]);
331 (*this)[1][0] -= dot0 * (*this)[0][0];
332 (*this)[1][1] -= dot0 * (*this)[0][1];
333 (*this)[1][2] -= dot0 * (*this)[0][2];
334 (*this)[1].normalize();
337 dot0 = (*this)[0].dot((*
this)[2]);
338 T dot1 = (*this)[1].dot((*
this)[2]);
339 (*this)[2][0] -= dot0*(*this)[0][0] + dot1*(*this)[1][0];
340 (*this)[2][1] -= dot0*(*this)[0][1] + dot1*(*this)[1][1];
341 (*this)[2][2] -= dot0*(*this)[0][2] + dot1*(*this)[1][2];
342 (*this)[2].normalize();
352 return { m(0,0)*v[0] + m(0,1)*v[1] + m(0,2)*v[2],
353 m(1,0)*v[0] + m(1,1)*v[1] + m(1,2)*v[2],
354 m(2,0)*v[0] + m(2,1)*v[1] + m(2,2)*v[2] };
362 return { m(0,0)*p[0] + m(0,1)*p[1] + m(0,2)*p[2],
363 m(1,0)*p[0] + m(1,1)*p[1] + m(1,2)*p[2],
364 m(2,0)*p[0] + m(2,1)*p[1] + m(2,2)*p[2] };
374 a(0,0)*b(0,0) + a(0,1)*b(1,0) + a(0,2)*b(2,0),
375 a(0,0)*b(0,1) + a(0,1)*b(1,1) + a(0,2)*b(2,1),
376 a(0,0)*b(0,2) + a(0,1)*b(1,2) + a(0,2)*b(2,2),
378 a(1,0)*b(0,0) + a(1,1)*b(1,0) + a(1,2)*b(2,0),
379 a(1,0)*b(0,1) + a(1,1)*b(1,1) + a(1,2)*b(2,1),
380 a(1,0)*b(0,2) + a(1,1)*b(1,2) + a(1,2)*b(2,2),
382 a(2,0)*b(0,0) + a(2,1)*b(1,0) + a(2,2)*b(2,0),
383 a(2,0)*b(0,1) + a(2,1)*b(1,1) + a(2,2)*b(2,1),
384 a(2,0)*b(0,2) + a(2,1)*b(1,2) + a(2,2)*b(2,2)
392 v += a(row, k) * b(k, col);
408 m(row, col) = a(row, col) - b(row, col);
423 a(0,0)*s, a(0,1)*s, a(0,2)*s,
424 a(1,0)*s, a(1,1)*s, a(1,2)*s,
425 a(2,0)*s, a(2,1)*s, a(2,2)*s
431 m(i, j) = a(i, j) * s;
448 inline std::ostream& operator<<(std::ostream &os, const Matrix_3<T>& m) {
450 os << m.row(row) << std::endl;
A point in 3d space.
Definition: Point3.h:84
A 3x3 matrix.
Definition: Matrix3.h:40
Matrix_3()
Empty default constructor that does not initialize the matrix elements (for performance reasons)...
Definition: Matrix3.h:66
constexpr Matrix_3< T > operator*(T s, const Matrix_3< T > &a)
Multiplies a matrix with a scalar value.
Definition: Matrix3.h:441
constexpr Matrix_3< T > operator*(const Matrix_3< T > &a, T s)
Multiplies a matrix with a scalar value.
Definition: Matrix3.h:419
constexpr Point_3< T > operator*(const Matrix_3< T > &m, const Point_3< T > &p)
Computes the product of a matrix and a point. This is the same as a matrix-vector product...
Definition: Matrix3.h:360
constexpr Matrix_3< T > operator*(const Matrix_3< T > &a, const Matrix_3< T > &b)
Computes the product of two matrices.
Definition: Matrix3.h:370
This file collects the definition of classes that define various simple crystal structures.
Definition: Atomicrex.h:67
Matrix_3< T > operator-(const Matrix_3< T > &a, const Matrix_3< T > &b)
Subtracts a 3x3 matrix from a 3x3 Matrix.
Definition: Matrix3.h:403
T element_type
The type of a single element of the matrix.
Definition: Matrix3.h:51
An empty type that denotes the vector (0,0,0).
Definition: Vector3.h:70
An empty type that denotes a 3x3 matrix with all elements equal to zero.
Definition: Matrix3.h:45
Vector_3< T > column_type
The type of a single column of the matrix.
Definition: Matrix3.h:54
constexpr Matrix_3(T m11, T m12, T m13, T m21, T m22, T m23, T m31, T m32, T m33)
Constructor that initializes all 9 elements of the matrix to the given values.
Definition: Matrix3.h:70
A vector with three components.
Definition: Vector3.h:65
An empty type that denotes the 3x3 identity matrix.
Definition: Matrix3.h:48
constexpr Vector_3< T > operator*(const Matrix_3< T > &m, const Vector_3< T > &v)
Computes the product of a matrix and a vector.
Definition: Matrix3.h:350