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
6#include <iosfwd>
7
8namespace MR
9{
10
11#ifdef _MSC_VER
12#pragma warning(push)
13#pragma warning(disable: 4804) // unsafe use of type 'bool' in operation
14#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
15#endif
16
19template <typename T>
20struct Matrix2
21{
22 using ValueType = T;
24
26 Vector2<T> x{ 1, 0 };
27 Vector2<T> y{ 0, 1 };
28
29 constexpr Matrix2() noexcept
30 {
31 static_assert( sizeof( Matrix2<ValueType> ) == 2 * sizeof( VectorType ), "Struct size invalid" );
32 }
34 constexpr Matrix2( const Vector2<T> & x, const Vector2<T> & y ) : x( x ), y( y ) { }
35 template <typename U>
36 constexpr explicit Matrix2( const Matrix2<U> & m ) : x( m.x ), y( m.y ) { }
37 static constexpr Matrix2 zero() noexcept { return Matrix2( Vector2<T>(), Vector2<T>() ); }
38 static constexpr Matrix2 identity() noexcept { return Matrix2(); }
40 static constexpr Matrix2 scale( T s ) noexcept { return Matrix2( { s, T(0) }, { T(0), s } ); }
42 static constexpr Matrix2 scale( T sx, T sy ) noexcept { return Matrix2( { sx, T(0) }, { T(0), sy } ); }
43 static constexpr Matrix2 scale( const Vector2<T> & s ) noexcept { return Matrix2( { s.x, T(0) }, { T(0), s.y } ); }
45 static constexpr Matrix2 rotation( T angle ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> );
47 static constexpr Matrix2 rotation( const Vector2<T> & from, const Vector2<T> & to ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> );
49 static constexpr Matrix2 fromRows( const Vector2<T> & x, const Vector2<T> & y ) noexcept { return Matrix2( x, y ); }
52 static constexpr Matrix2 fromColumns( const Vector2<T> & x, const Vector2<T> & y ) noexcept { return Matrix2( x, y ).transposed(); }
53
55 constexpr const Vector2<T> & operator []( int row ) const noexcept { return *( ( VectorType* )this + row ); }
56 constexpr Vector2<T> & operator []( int row ) noexcept { return *( ( VectorType* )this + row ); }
57
59 constexpr Vector2<T> col( int i ) const noexcept { return { x[i], y[i] }; }
60
62 constexpr T trace() const noexcept { return x.x + y.y; }
64 constexpr T normSq() const noexcept { return x.lengthSq() + y.lengthSq(); }
65 constexpr auto norm() const noexcept
66 {
67 // Calling `sqrt` this way to hopefully support boost.multiprecision numbers.
68 // Returning `auto` to not break on integral types.
69 using std::sqrt;
70 return sqrt( normSq() );
71 }
73 constexpr T det() const noexcept;
75 constexpr Matrix2<T> inverse() const noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> );
77 constexpr Matrix2<T> transposed() const noexcept;
78
79 [[nodiscard]] friend constexpr bool operator ==( const Matrix2<T> & a, const Matrix2<T> & b ) { return a.x == b.x && a.y == b.y; }
80 [[nodiscard]] friend constexpr bool operator !=( const Matrix2<T> & a, const Matrix2<T> & b ) { return !( a == b ); }
81
82 // 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.
83
84 [[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 }; }
85 [[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 }; }
86 [[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 }; }
87 [[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 }; }
88 [[nodiscard]] friend constexpr auto operator /( Matrix2<T> b, T a ) -> Matrix2<decltype( std::declval<T>() / std::declval<T>() )>
89 {
90 if constexpr ( std::is_integral_v<T> )
91 return { b.x / a, b.y / a };
92 else
93 return b * ( 1 / a );
94 }
95
96 friend constexpr Matrix2<T> & operator +=( Matrix2<T> & a, const Matrix2<T> & b ) { a.x += b.x; a.y += b.y; return a; }
97 friend constexpr Matrix2<T> & operator -=( Matrix2<T> & a, const Matrix2<T> & b ) { a.x -= b.x; a.y -= b.y; return a; }
98 friend constexpr Matrix2<T> & operator *=( Matrix2<T> & a, T b ) { a.x *= b; a.y *= b; return a; }
99 friend constexpr Matrix2<T> & operator /=( Matrix2<T> & a, T b )
100 {
101 if constexpr ( std::is_integral_v<T> )
102 { a.x /= b; a.y /= b; return a; }
103 else
104 return a *= ( 1 / b );
105 }
106
108 [[nodiscard]] friend constexpr auto operator *( const Matrix2<T> & a, const Vector2<T> & b ) -> Vector2<decltype( dot( std::declval<Vector2<T>>(), std::declval<Vector2<T>>() ) )>
109 {
110 return { dot( a.x, b ), dot( a.y, b ) };
111 }
112
114 [[nodiscard]] friend constexpr auto operator *( const Matrix2<T> & a, const Matrix2<T> & b ) -> Matrix2<decltype( dot( std::declval<Vector2<T>>(), std::declval<Vector2<T>>() ) )>
115 {
116 Matrix2<decltype( dot( std::declval<Vector2<T>>(), std::declval<Vector2<T>>() ) )> res;
117 for ( int i = 0; i < 2; ++i )
118 for ( int j = 0; j < 2; ++j )
119 res[i][j] = dot( a[i], b.col(j) );
120 return res;
121 }
122
123 friend std::ostream& operator<<( std::ostream& s, const Matrix2& mat )
124 {
125 return s << mat.x << '\n' << mat.y << '\n';
126 }
127
128 friend std::istream& operator>>( std::istream& s, Matrix2& mat )
129 {
130 return s >> mat.x >> mat.y;
131 }
132};
133
136
138template <typename T>
139inline auto dot( const Matrix2<T> & a, const Matrix2<T> & b ) -> decltype( dot( a.x, b.x ) )
140{
141 return dot( a.x, b.x ) + dot( a.y, b.y );
142}
143
145template <typename T>
146inline Matrix2<T> outer( const Vector2<T> & a, const Vector2<T> & b )
147{
148 return { a.x * b, a.y * b };
149}
150
151template <typename T>
152constexpr Matrix2<T> Matrix2<T>::rotation( T angle ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> )
153{
154 T c = cos( angle );
155 T s = sin( angle );
156 return {
157 { c, -s },
158 { s, c }
159 };
160}
161
162template <typename T>
163constexpr Matrix2<T> Matrix2<T>::rotation( const Vector2<T> & from, const Vector2<T> & to ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> )
164{
165 const auto x = cross( from, to );
166 if ( x > 0 )
167 return rotation( angle( from, to ) );
168 if ( x < 0 )
169 return rotation( -angle( from, to ) );
170 if ( dot( from, to ) >= 0 )
171 return {}; // identity matrix
172 return rotation( T( PI ) );
173}
174
175template <typename T>
176constexpr T Matrix2<T>::det() const noexcept
177{
178 return x.x * y.y - x.y * y.x;
179}
180
181template <typename T>
182constexpr Matrix2<T> Matrix2<T>::inverse() const noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> )
183{
184 auto det = this->det();
185 if ( det == 0 )
186 return {};
187 return Matrix2<T>
188 {
189 { y.y, - x.y },
190 { - y.x, x.x }
191 } / det;
192}
193
194template <typename T>
195constexpr Matrix2<T> Matrix2<T>::transposed() const noexcept
196{
197 return Matrix2<T>
198 {
199 { x.x, y.x },
200 { x.y, y.y }
201 };
202}
203
205
206#ifdef _MSC_VER
207#pragma warning(pop)
208#endif
209
210} // namespace MR
#define MR_REQUIRES_IF_SUPPORTED(...)
Definition MRMacros.h:34
Definition MRCameraOrientationPlugin.h:8
float dot(Vector2f a, Vector2f b)
float cross(Vector2f a, Vector2f b)
Definition MRMatrix2.h:21
constexpr Matrix2(const Matrix2< U > &m)
Definition MRMatrix2.h:36
Vector2< T > x
rows, identity matrix by default
Definition MRMatrix2.h:26
constexpr Matrix2() noexcept
Definition MRMatrix2.h:29
static constexpr Matrix2 scale(T s) noexcept
returns a matrix that scales uniformly
Definition MRMatrix2.h:40
constexpr T normSq() const noexcept
compute sum of squared matrix elements
Definition MRMatrix2.h:64
Matrix2< T > outer(const Vector2< T > &a, const Vector2< T > &b)
x = a * b^T
Definition MRMatrix2.h:146
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:139
friend std::ostream & operator<<(std::ostream &s, const Matrix2 &mat)
Definition MRMatrix2.h:123
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:49
friend constexpr auto operator/(Matrix2< T > b, T a) -> Matrix2< decltype(std::declval< T >()/std::declval< T >())>
Definition MRMatrix2.h:88
friend constexpr auto operator-(const Matrix2< T > &a, const Matrix2< T > &b) -> Matrix2< decltype(std::declval< T >() - std::declval< T >())>
Definition MRMatrix2.h:85
constexpr Matrix2(const Vector2< T > &x, const Vector2< T > &y)
initializes matrix from its 2 rows
Definition MRMatrix2.h:34
friend constexpr Matrix2< T > & operator-=(Matrix2< T > &a, const Matrix2< T > &b)
Definition MRMatrix2.h:97
friend constexpr Matrix2< T > & operator*=(Matrix2< T > &a, T b)
Definition MRMatrix2.h:98
constexpr Vector2< T > col(int i) const noexcept
column access
Definition MRMatrix2.h:59
static constexpr Matrix2 identity() noexcept
Definition MRMatrix2.h:38
Vector2< T > y
Definition MRMatrix2.h:27
T ValueType
Definition MRMatrix2.h:22
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:86
static constexpr Matrix2 scale(const Vector2< T > &s) noexcept
Definition MRMatrix2.h:43
friend constexpr Matrix2< T > & operator+=(Matrix2< T > &a, const Matrix2< T > &b)
Definition MRMatrix2.h:96
static constexpr Matrix2 scale(T sx, T sy) noexcept
returns a matrix that has its own scale along each axis
Definition MRMatrix2.h:42
friend std::istream & operator>>(std::istream &s, Matrix2 &mat)
Definition MRMatrix2.h:128
constexpr T trace() const noexcept
computes trace of the matrix
Definition MRMatrix2.h:62
constexpr const Vector2< T > & operator[](int row) const noexcept
row access
Definition MRMatrix2.h:55
friend constexpr bool operator!=(const Matrix2< T > &a, const Matrix2< T > &b)
Definition MRMatrix2.h:80
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:99
constexpr auto norm() const noexcept
Definition MRMatrix2.h:65
static constexpr Matrix2 zero() noexcept
Definition MRMatrix2.h:37
friend constexpr auto operator+(const Matrix2< T > &a, const Matrix2< T > &b) -> Matrix2< decltype(std::declval< T >()+std::declval< T >())>
Definition MRMatrix2.h:84
static constexpr Matrix2 fromColumns(const Vector2< T > &x, const Vector2< T > &y) noexcept
Definition MRMatrix2.h:52
Definition MRVector2.h:29
T x
Definition MRVector2.h:35
T y
Definition MRVector2.h:35