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 = default;
29 constexpr Matrix2( const Vector2<T> & x, const Vector2<T> & y ) : x( x ), y( y ) { }
30 template <typename U>
31 constexpr explicit Matrix2( const Matrix2<U> & m ) : x( m.x ), y( m.y ) { }
32 static constexpr Matrix2 zero() noexcept { return Matrix2( Vector2<T>(), Vector2<T>() ); }
33 static constexpr Matrix2 identity() noexcept { return Matrix2(); }
35 static constexpr Matrix2 scale( T s ) noexcept { return Matrix2( { s, T(0) }, { T(0), s } ); }
37 static constexpr Matrix2 scale( T sx, T sy ) noexcept { return Matrix2( { sx, T(0) }, { T(0), sy } ); }
38 static constexpr Matrix2 scale( const Vector2<T> & s ) noexcept { return Matrix2( { s.x, T(0) }, { T(0), s.y } ); }
40 static constexpr Matrix2 rotation( T angle ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> );
42 static constexpr Matrix2 rotation( const Vector2<T> & from, const Vector2<T> & to ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> );
44 static constexpr Matrix2 fromRows( const Vector2<T> & x, const Vector2<T> & y ) noexcept { return Matrix2( x, y ); }
47 static constexpr Matrix2 fromColumns( const Vector2<T> & x, const Vector2<T> & y ) noexcept { return Matrix2( x, y ).transposed(); }
48
50 constexpr const Vector2<T> & operator []( int row ) const noexcept { return *( &x + row ); }
51 constexpr Vector2<T> & operator []( int row ) noexcept { return *( &x + row ); }
52
54 constexpr Vector2<T> col( int i ) const noexcept { return { x[i], y[i] }; }
55
57 constexpr T trace() const noexcept { return x.x + y.y; }
59 constexpr T normSq() const noexcept { return x.lengthSq() + y.lengthSq(); }
60 constexpr auto norm() const noexcept
61 {
62 // Calling `sqrt` this way to hopefully support boost.multiprecision numbers.
63 // Returning `auto` to not break on integral types.
64 using std::sqrt;
65 return sqrt( normSq() );
66 }
68 constexpr T det() const noexcept;
70 constexpr Matrix2<T> inverse() const noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> );
72 constexpr Matrix2<T> transposed() const noexcept;
73
74 [[nodiscard]] friend constexpr bool operator ==( const Matrix2<T> & a, const Matrix2<T> & b ) { return a.x == b.x && a.y == b.y; }
75 [[nodiscard]] friend constexpr bool operator !=( const Matrix2<T> & a, const Matrix2<T> & b ) { return !( a == b ); }
76
77 // 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.
78
79 [[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 }; }
80 [[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 }; }
81 [[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 }; }
82 [[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 }; }
83 [[nodiscard]] friend constexpr auto operator /( Matrix2<T> b, T a ) -> Matrix2<decltype( std::declval<T>() / std::declval<T>() )>
84 {
85 if constexpr ( std::is_integral_v<T> )
86 return { b.x / a, b.y / a };
87 else
88 return b * ( 1 / a );
89 }
90
91 friend constexpr Matrix2<T> & operator +=( Matrix2<T> & a, const Matrix2<T> & b ) MR_REQUIRES_IF_SUPPORTED( requires{ a + b; } ) { a.x += b.x; a.y += b.y; return a; }
92 friend constexpr Matrix2<T> & operator -=( Matrix2<T> & a, const Matrix2<T> & b ) MR_REQUIRES_IF_SUPPORTED( requires{ a - b; } ) { a.x -= b.x; a.y -= b.y; return a; }
93 friend constexpr Matrix2<T> & operator *=( Matrix2<T> & a, T b ) MR_REQUIRES_IF_SUPPORTED( requires{ a * b; } ) { a.x *= b; a.y *= b; return a; }
94 friend constexpr Matrix2<T> & operator /=( Matrix2<T> & a, T b ) MR_REQUIRES_IF_SUPPORTED( requires{ a / b; } )
95 {
96 if constexpr ( std::is_integral_v<T> )
97 { a.x /= b; a.y /= b; return a; }
98 else
99 return a *= ( 1 / b );
100 }
101
103 [[nodiscard]] friend constexpr auto operator *( const Matrix2<T> & a, const Vector2<T> & b ) -> Vector2<decltype( dot( std::declval<Vector2<T>>(), std::declval<Vector2<T>>() ) )>
104 {
105 return { dot( a.x, b ), dot( a.y, b ) };
106 }
107
109 [[nodiscard]] friend constexpr auto operator *( const Matrix2<T> & a, const Matrix2<T> & b ) -> Matrix2<decltype( dot( std::declval<Vector2<T>>(), std::declval<Vector2<T>>() ) )>
110 {
111 Matrix2<decltype( dot( std::declval<Vector2<T>>(), std::declval<Vector2<T>>() ) )> res;
112 for ( int i = 0; i < 2; ++i )
113 for ( int j = 0; j < 2; ++j )
114 res[i][j] = dot( a[i], b.col(j) );
115 return res;
116 }
117};
118
121
123template <typename T>
124inline auto dot( const Matrix2<T> & a, const Matrix2<T> & b ) -> decltype( dot( a.x, b.x ) )
125{
126 return dot( a.x, b.x ) + dot( a.y, b.y );
127}
128
130template <typename T>
131inline Matrix2<T> outer( const Vector2<T> & a, const Vector2<T> & b )
132{
133 return { a.x * b, a.y * b };
134}
135
136template <typename T>
137constexpr Matrix2<T> Matrix2<T>::rotation( T angle ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> )
138{
139 T c = cos( angle );
140 T s = sin( angle );
141 return {
142 { c, -s },
143 { s, c }
144 };
145}
146
147template <typename T>
148constexpr Matrix2<T> Matrix2<T>::rotation( const Vector2<T> & from, const Vector2<T> & to ) noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> )
149{
150 const auto x = cross( from, to );
151 if ( x > 0 )
152 return rotation( angle( from, to ) );
153 if ( x < 0 )
154 return rotation( -angle( from, to ) );
155 if ( dot( from, to ) >= 0 )
156 return {}; // identity matrix
157 return rotation( T( PI ) );
158}
159
160template <typename T>
161constexpr T Matrix2<T>::det() const noexcept
162{
163 return x.x * y.y - x.y * y.x;
164}
165
166template <typename T>
167constexpr Matrix2<T> Matrix2<T>::inverse() const noexcept MR_REQUIRES_IF_SUPPORTED( std::is_floating_point_v<T> )
168{
169 auto det = this->det();
170 if ( det == 0 )
171 return {};
172 return Matrix2<T>
173 {
174 { y.y, - x.y },
175 { - y.x, x.x }
176 } / det;
177}
178
179template <typename T>
180constexpr Matrix2<T> Matrix2<T>::transposed() const noexcept
181{
182 return Matrix2<T>
183 {
184 { x.x, y.x },
185 { x.y, y.y }
186 };
187}
188
190
191#ifdef _MSC_VER
192#pragma warning(pop)
193#endif
194
195} // namespace MR
#define MR_REQUIRES_IF_SUPPORTED(...)
Definition MRMacros.h:31
MRMESH_CLASS Vector3< double > Matrix2
Definition MRMesh/MRMeshFwd.h:186
int dot(Vector2i a, Vector2i b)
Vector3f cross(Vector3f a, Vector3f b)
Definition MRMatrix2.h:19
constexpr Matrix2(const Matrix2< U > &m)
Definition MRMatrix2.h:31
Vector2< T > x
rows, identity matrix by default
Definition MRMatrix2.h:24
static constexpr Matrix2 rotation(const Vector2< T > &from, const Vector2< T > &to) noexcept
creates matrix representing rotation that after application to (from) makes (to) vector
static constexpr Matrix2 scale(T s) noexcept
returns a matrix that scales uniformly
Definition MRMatrix2.h:35
constexpr T normSq() const noexcept
compute sum of squared matrix elements
Definition MRMatrix2.h:59
Matrix2< T > outer(const Vector2< T > &a, const Vector2< T > &b)
x = a * b^T
Definition MRMatrix2.h:131
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:124
friend constexpr auto operator/(Matrix2< T > b, T a) -> Matrix2< decltype(std::declval< T >()/std::declval< T >())>
Definition MRMatrix2.h:83
friend constexpr auto operator-(const Matrix2< T > &a, const Matrix2< T > &b) -> Matrix2< decltype(std::declval< T >() - std::declval< T >())>
Definition MRMatrix2.h:80
friend constexpr Matrix2< T > & operator-=(Matrix2< T > &a, const Matrix2< T > &b)
Definition MRMatrix2.h:92
friend constexpr Matrix2< T > & operator*=(Matrix2< T > &a, T b)
Definition MRMatrix2.h:93
static constexpr Matrix2 rotation(T angle) noexcept
creates matrix representing rotation around origin on given angle
constexpr Vector2< T > col(int i) const noexcept
column access
Definition MRMatrix2.h:54
static constexpr Matrix2 identity() noexcept
Definition MRMatrix2.h:33
Vector2< T > y
Definition MRMatrix2.h:25
constexpr Matrix2< T > transposed() const noexcept
computes transposed matrix
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:81
static constexpr Matrix2 scale(const Vector2< T > &s) noexcept
Definition MRMatrix2.h:38
friend constexpr Matrix2< T > & operator+=(Matrix2< T > &a, const Matrix2< T > &b)
Definition MRMatrix2.h:91
static constexpr Matrix2 scale(T sx, T sy) noexcept
returns a matrix that has its own scale along each axis
Definition MRMatrix2.h:37
constexpr T trace() const noexcept
computes trace of the matrix
Definition MRMatrix2.h:57
constexpr const Vector2< T > & operator[](int row) const noexcept
row access
Definition MRMatrix2.h:50
constexpr Matrix2() noexcept=default
friend constexpr bool operator!=(const Matrix2< T > &a, const Matrix2< T > &b)
Definition MRMatrix2.h:75
constexpr Matrix2< T > inverse() const noexcept
computes inverse matrix
friend constexpr Matrix2< T > & operator/=(Matrix2< T > &a, T b)
Definition MRMatrix2.h:94
constexpr auto norm() const noexcept
Definition MRMatrix2.h:60
static constexpr Matrix2 zero() noexcept
Definition MRMatrix2.h:32
friend constexpr auto operator+(const Matrix2< T > &a, const Matrix2< T > &b) -> Matrix2< decltype(std::declval< T >()+std::declval< T >())>
Definition MRMatrix2.h:79
static constexpr Matrix2 fromRows(const Vector2< T > &x, const Vector2< T > &y) noexcept
constructs a matrix from its 2 rows
Definition MRMatrix2.h:44
static constexpr Matrix2 fromColumns(const Vector2< T > &x, const Vector2< T > &y) noexcept
Definition MRMatrix2.h:47
Definition MRVector2.h:25
T x
Definition MRVector2.h:31
T y
Definition MRVector2.h:31