MeshLib C++ Docs
Loading...
Searching...
No Matches
MRMatrix2.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRVector2.h"
4#include "MRConstants.h"
5
6namespace MR
7{
8
9#ifdef _MSC_VER
10#pragma warning(push)
11#pragma warning(disable: 4804) // unsafe use of type 'bool' in operation
12#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
13#endif
14
17template <typename T>
18struct Matrix2
19{
20 using ValueType = T;
22
24 Vector2<T> x{ 1, 0 };
25 Vector2<T> y{ 0, 1 };
26
27 constexpr Matrix2() noexcept
28 {
29 static_assert( sizeof( Matrix2<ValueType> ) == 2 * sizeof( VectorType ), "Struct size invalid" );
30 }
32 constexpr Matrix2( const Vector2<T> & x, const Vector2<T> & y ) : x( x ), y( y ) { }
33 template <typename U>
34 constexpr explicit Matrix2( const Matrix2<U> & m ) : x( m.x ), y( m.y ) { }
35 static constexpr Matrix2 zero() noexcept { return Matrix2( Vector2<T>(), Vector2<T>() ); }
36 static constexpr Matrix2 identity() noexcept { return Matrix2(); }
38 static constexpr Matrix2 scale( T s ) noexcept { return Matrix2( { s, T(0) }, { T(0), s } ); }
40 static constexpr Matrix2 scale( T sx, T sy ) noexcept { return Matrix2( { sx, T(0) }, { T(0), sy } ); }
41 static constexpr Matrix2 scale( const Vector2<T> & s ) noexcept { return Matrix2( { s.x, T(0) }, { T(0), s.y } ); }
43 static constexpr Matrix2 rotation( T angle ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> );
45 static constexpr Matrix2 rotation( const Vector2<T> & from, const Vector2<T> & to ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> );
47 static constexpr Matrix2 fromRows( const Vector2<T> & x, const Vector2<T> & y ) noexcept { return Matrix2( x, y ); }
50 static constexpr Matrix2 fromColumns( const Vector2<T> & x, const Vector2<T> & y ) noexcept { return Matrix2( x, y ).transposed(); }
51
53 constexpr const Vector2<T> & operator []( int row ) const noexcept { return *( ( VectorType* )this + row ); }
54 constexpr Vector2<T> & operator []( int row ) noexcept { return *( ( VectorType* )this + row ); }
55
57 constexpr Vector2<T> col( int i ) const noexcept { return { x[i], y[i] }; }
58
60 constexpr T trace() const noexcept { return x.x + y.y; }
62 constexpr T normSq() const noexcept { return x.lengthSq() + y.lengthSq(); }
63 constexpr auto norm() const noexcept
64 {
65 // Calling `sqrt` this way to hopefully support boost.multiprecision numbers.
66 // Returning `auto` to not break on integral types.
67 using std::sqrt;
68 return sqrt( normSq() );
69 }
71 constexpr T det() const noexcept;
73 constexpr Matrix2<T> inverse() const noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> );
75 constexpr Matrix2<T> transposed() const noexcept;
76
77 [[nodiscard]] friend constexpr bool operator ==( const Matrix2<T> & a, const Matrix2<T> & b ) { return a.x == b.x && a.y == b.y; }
78 [[nodiscard]] friend constexpr bool operator !=( const Matrix2<T> & a, const Matrix2<T> & b ) { return !( a == b ); }
79
80 // NOTE: We use `std::declval()` in the operators below because libclang 18 in our binding generator is bugged and chokes on decltyping `a.x` and such. TODO fix this when we update libclang.
81
82 [[nodiscard]] friend constexpr auto operator +( const Matrix2<T> & a, const Matrix2<T> & b ) -> Matrix2<decltype( std::declval<T>() + std::declval<T>() )> { return { a.x + b.x, a.y + b.y }; }
83 [[nodiscard]] friend constexpr auto operator -( const Matrix2<T> & a, const Matrix2<T> & b ) -> Matrix2<decltype( std::declval<T>() - std::declval<T>() )> { return { a.x - b.x, a.y - b.y }; }
84 [[nodiscard]] friend constexpr auto operator *( T a, const Matrix2<T> & b ) -> Matrix2<decltype( std::declval<T>() * std::declval<T>() )> { return { a * b.x, a * b.y }; }
85 [[nodiscard]] friend constexpr auto operator *( const Matrix2<T> & b, T a ) -> Matrix2<decltype( std::declval<T>() * std::declval<T>() )> { return { a * b.x, a * b.y }; }
86 [[nodiscard]] friend constexpr auto operator /( Matrix2<T> b, T a ) -> Matrix2<decltype( std::declval<T>() / std::declval<T>() )>
87 {
88 if constexpr ( std::is_integral_v<T> )
89 return { b.x / a, b.y / a };
90 else
91 return b * ( 1 / a );
92 }
93
94 friend constexpr Matrix2<T> & operator +=( Matrix2<T> & a, const Matrix2<T> & b ) { a.x += b.x; a.y += b.y; return a; }
95 friend constexpr Matrix2<T> & operator -=( Matrix2<T> & a, const Matrix2<T> & b ) { a.x -= b.x; a.y -= b.y; return a; }
96 friend constexpr Matrix2<T> & operator *=( Matrix2<T> & a, T b ) { a.x *= b; a.y *= b; return a; }
97 friend constexpr Matrix2<T> & operator /=( Matrix2<T> & a, T b )
98 {
99 if constexpr ( std::is_integral_v<T> )
100 { a.x /= b; a.y /= b; return a; }
101 else
102 return a *= ( 1 / b );
103 }
104
106 [[nodiscard]] friend constexpr auto operator *( const Matrix2<T> & a, const Vector2<T> & b ) -> Vector2<decltype( dot( std::declval<Vector2<T>>(), std::declval<Vector2<T>>() ) )>
107 {
108 return { dot( a.x, b ), dot( a.y, b ) };
109 }
110
112 [[nodiscard]] friend constexpr auto operator *( const Matrix2<T> & a, const Matrix2<T> & b ) -> Matrix2<decltype( dot( std::declval<Vector2<T>>(), std::declval<Vector2<T>>() ) )>
113 {
114 Matrix2<decltype( dot( std::declval<Vector2<T>>(), std::declval<Vector2<T>>() ) )> res;
115 for ( int i = 0; i < 2; ++i )
116 for ( int j = 0; j < 2; ++j )
117 res[i][j] = dot( a[i], b.col(j) );
118 return res;
119 }
120};
121
124
126template <typename T>
127inline auto dot( const Matrix2<T> & a, const Matrix2<T> & b ) -> decltype( dot( a.x, b.x ) )
128{
129 return dot( a.x, b.x ) + dot( a.y, b.y );
130}
131
133template <typename T>
134inline Matrix2<T> outer( const Vector2<T> & a, const Vector2<T> & b )
135{
136 return { a.x * b, a.y * b };
137}
138
139template <typename T>
140constexpr Matrix2<T> Matrix2<T>::rotation( T angle ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> )
141{
142 T c = cos( angle );
143 T s = sin( angle );
144 return {
145 { c, -s },
146 { s, c }
147 };
148}
149
150template <typename T>
151constexpr Matrix2<T> Matrix2<T>::rotation( const Vector2<T> & from, const Vector2<T> & to ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> )
152{
153 const auto x = cross( from, to );
154 if ( x > 0 )
155 return rotation( angle( from, to ) );
156 if ( x < 0 )
157 return rotation( -angle( from, to ) );
158 if ( dot( from, to ) >= 0 )
159 return {}; // identity matrix
160 return rotation( T( PI ) );
161}
162
163template <typename T>
164constexpr T Matrix2<T>::det() const noexcept
165{
166 return x.x * y.y - x.y * y.x;
167}
168
169template <typename T>
170constexpr Matrix2<T> Matrix2<T>::inverse() const noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> )
171{
172 auto det = this->det();
173 if ( det == 0 )
174 return {};
175 return Matrix2<T>
176 {
177 { y.y, - x.y },
178 { - y.x, x.x }
179 } / det;
180}
181
182template <typename T>
183constexpr Matrix2<T> Matrix2<T>::transposed() const noexcept
184{
185 return Matrix2<T>
186 {
187 { x.x, y.x },
188 { x.y, y.y }
189 };
190}
191
193
194#ifdef _MSC_VER
195#pragma warning(pop)
196#endif
197
198} // namespace MR
#define MR_REQUIRES_IF_SUPPORTED(...)
Definition MRMacros.h:34
Definition MRCameraOrientationPlugin.h:8
Vector3f cross(Vector3f a, Vector3f b)
int dot(Vector4b a, Vector4b b)
Definition MRMatrix2.h:19
constexpr Matrix2(const Matrix2< U > &m)
Definition MRMatrix2.h:34
Vector2< T > x
rows, identity matrix by default
Definition MRMatrix2.h:24
constexpr Matrix2() noexcept
Definition MRMatrix2.h:27
static constexpr Matrix2 scale(T s) noexcept
returns a matrix that scales uniformly
Definition MRMatrix2.h:38
constexpr T normSq() const noexcept
compute sum of squared matrix elements
Definition MRMatrix2.h:62
Matrix2< T > outer(const Vector2< T > &a, const Vector2< T > &b)
x = a * b^T
Definition MRMatrix2.h:134
auto dot(const Matrix2< T > &a, const Matrix2< T > &b) -> decltype(dot(a.x, b.x))
double-dot product: x = a : b
Definition MRMatrix2.h:127
static constexpr Matrix2 static rotation(T angle) noexcept MR_REQUIRES_IF_SUPPORTED(std constexpr Matrix2 static rotation(const Vector2< T > &from, const Vector2< T > &to) noexcept MR_REQUIRES_IF_SUPPORTED(std constexpr Matrix fromRows)(const Vector2< T > &x, const Vector2< T > &y) noexcept
creates matrix representing rotation around origin on given angle
Definition MRMatrix2.h:47
friend constexpr auto operator/(Matrix2< T > b, T a) -> Matrix2< decltype(std::declval< T >()/std::declval< T >())>
Definition MRMatrix2.h:86
friend constexpr auto operator-(const Matrix2< T > &a, const Matrix2< T > &b) -> Matrix2< decltype(std::declval< T >() - std::declval< T >())>
Definition MRMatrix2.h:83
constexpr Matrix2(const Vector2< T > &x, const Vector2< T > &y)
initializes matrix from its 2 rows
Definition MRMatrix2.h:32
friend constexpr Matrix2< T > & operator-=(Matrix2< T > &a, const Matrix2< T > &b)
Definition MRMatrix2.h:95
friend constexpr Matrix2< T > & operator*=(Matrix2< T > &a, T b)
Definition MRMatrix2.h:96
constexpr Vector2< T > col(int i) const noexcept
column access
Definition MRMatrix2.h:57
static constexpr Matrix2 identity() noexcept
Definition MRMatrix2.h:36
Vector2< T > y
Definition MRMatrix2.h:25
T ValueType
Definition MRMatrix2.h:20
constexpr T det() const noexcept
computes determinant of the matrix
friend constexpr auto operator*(T a, const Matrix2< T > &b) -> Matrix2< decltype(std::declval< T >() *std::declval< T >())>
Definition MRMatrix2.h:84
static constexpr Matrix2 scale(const Vector2< T > &s) noexcept
Definition MRMatrix2.h:41
friend constexpr Matrix2< T > & operator+=(Matrix2< T > &a, const Matrix2< T > &b)
Definition MRMatrix2.h:94
static constexpr Matrix2 scale(T sx, T sy) noexcept
returns a matrix that has its own scale along each axis
Definition MRMatrix2.h:40
constexpr T trace() const noexcept
computes trace of the matrix
Definition MRMatrix2.h:60
constexpr const Vector2< T > & operator[](int row) const noexcept
row access
Definition MRMatrix2.h:53
friend constexpr bool operator!=(const Matrix2< T > &a, const Matrix2< T > &b)
Definition MRMatrix2.h:78
constexpr Matrix2< T > inverse() const noexcept MR_REQUIRES_IF_SUPPORTED(std constexpr Matrix2< T > transposed() const noexcept
computes inverse matrix
friend constexpr Matrix2< T > & operator/=(Matrix2< T > &a, T b)
Definition MRMatrix2.h:97
constexpr auto norm() const noexcept
Definition MRMatrix2.h:63
static constexpr Matrix2 zero() noexcept
Definition MRMatrix2.h:35
friend constexpr auto operator+(const Matrix2< T > &a, const Matrix2< T > &b) -> Matrix2< decltype(std::declval< T >()+std::declval< T >())>
Definition MRMatrix2.h:82
static constexpr Matrix2 fromColumns(const Vector2< T > &x, const Vector2< T > &y) noexcept
Definition MRMatrix2.h:50
Definition MRVector2.h:28
T x
Definition MRVector2.h:34
T y
Definition MRVector2.h:34