Update Matrix2.

This commit is contained in:
scorpioblood 2024-06-12 22:01:40 +02:00
parent 69be245e29
commit d99a318e53
3 changed files with 283 additions and 278 deletions

View File

@ -9,4 +9,6 @@
#include "Core/public/Math/IntVector2.hpp" #include "Core/public/Math/IntVector2.hpp"
#include "Core/public/Math/IntVector3.hpp" #include "Core/public/Math/IntVector3.hpp"
#include "Core/public/Math/IntVector4.hpp" #include "Core/public/Math/IntVector4.hpp"
#include "Core/public/Math/Matrix2.hpp"

View File

@ -29,7 +29,6 @@ namespace Phanes::Core::Math {
template<RealType T> struct TRay; template<RealType T> struct TRay;
template<RealType T> struct TLine; template<RealType T> struct TLine;
template<RealType T> struct TPlane; template<RealType T> struct TPlane;
template<RealType T> struct TMatrix2;
template<RealType T> struct TMatrix3; template<RealType T> struct TMatrix3;
template<RealType T> struct TMatrix4; template<RealType T> struct TMatrix4;
template<RealType T> struct TQuaternion; template<RealType T> struct TQuaternion;
@ -40,38 +39,17 @@ namespace Phanes::Core::Math {
template<IntType T> struct TIntPoint2; template<IntType T> struct TIntPoint2;
template<IntType T> struct TIntPoint3; template<IntType T> struct TIntPoint3;
template<IntType T> struct TIntPoint4; template<IntType T> struct TIntPoint4;
template<RealType T, bool A> struct TVector2; template<RealType T> struct TMatrix2;
template<RealType T, bool A> struct TVector3; template<RealType T, bool S> struct TVector2;
template<RealType T, bool A> struct TVector4; template<RealType T, bool S> struct TVector3;
template<IntType T, bool A> struct TIntVector2; template<RealType T, bool S> struct TVector4;
template<IntType T, bool A> struct TIntVector3; template<IntType T, bool S> struct TIntVector2;
template<IntType T, bool A> struct TIntVector4; template<IntType T, bool S> struct TIntVector3;
template<IntType T, bool S> struct TIntVector4;
/** /**
* Specific instantiation of forward declarations. * Specific instantiation of forward declarations.
*/ */
// TMatrix2
typedef TMatrix2<float> Matrix2;
typedef TMatrix2<double> Matrix2d;
typedef std::vector<Matrix2> Matrix2List;
typedef std::vector<Matrix2d> Matrix2Listd;
// TMatrix3
typedef TMatrix3<float> Matrix3;
typedef TMatrix3<double> Matrix3d;
typedef std::vector<Matrix3> Matrix3List;
typedef std::vector<Matrix3d> Matrix3Listd;
// TPlane
typedef TPlane<float> Plane;
typedef TPlane<double> Planed;
typedef std::vector<Plane> PlaneList;
typedef std::vector<Planed> PlaneListd;
} // Phanes::Core::Math::coretypes } // Phanes::Core::Math::coretypes

View File

@ -2,295 +2,320 @@
#include "Core/public/Math/Boilerplate.h" #include "Core/public/Math/Boilerplate.h"
#include "Core/public/Math/MathFwd.h"
#include "Core/public/Math/Vector2.hpp" #include "Core/public/Math/Vector2.hpp"
#ifndef MATRIX2_H #ifndef MATRIX2_H
#define MATRIX2_H #define MATRIX2_H
namespace Phanes::Core::Math { namespace Phanes::Core::Math {
// 2x2 Matrix defined in column-major order.
// Accessed by M[Row][Col].
template<RealType T>
struct TMatrix2
{
public:
union
{
struct
{
/// <summary>
/// Column one.
/// </summary>
TVector2<T, false> c0;
/// <summary>
/// Column two
/// </summary>
TVector2<T, false> c1;
};
T data[2][2];
};
public:
TMatrix2() = default;
/**
* Copy constructor.
*/
TMatrix2(const TMatrix2<T>& m1)
{
this->c0 = m1.c0;
this->c1 = m1.c1;
}
/**
* Construct Matrix from 2d array.
*
* @param(fields) 2D Array with column major order.
*/
TMatrix2(T fields[2][2])
{
this->data[0][0] = fields[0][0]; this->data[1][0] = fields[1][0];
this->data[0][1] = fields[0][1]; this->data[1][1] = fields[1][1];
}
/**
* Construct Matrix from parameters.
*
* @param(n00) M[0][0]
* @param(n10) M[1][0]
* @param(n01) M[0][1]
* @param(n11) M[1][1]
*
* @note nXY = n[Row][Col]
*/
TMatrix2(T n00, T n01, T n10, T n11)
{
this->data[0][0] = n00; this->data[1][0] = n01;
this->data[0][1] = n10; this->data[1][1] = n11;
}
/**
* Construct Matrix from two 2d vector columns.
*
* @param(v1) Column zero
* @param(v2) Column one
*/
TMatrix2(const TVector2<T, false>& v1, const TVector2<T, false>& v2)
{
this->c0 = v1;
this->c1 = v2;
}
public:
// 2x2 Matrix defined in column-major order. constexpr GetCol(int n)
// Accessed by M[Row][Col]. {
switch (n)
{
case 0:
return this->c0;
case 1:
return this->c1;
default:
break;
}
}
template<RealType T> FORCEINLINE T operator() (int n, int m) const
struct TMatrix2 {
{ this->data[m][n];
public: }
T m[2][2]; FORCEINLINE TVector2<T, false>& operator[] (int m) const
{
static_assert(m > -1 && m < 2, "(PHANES_CORE::MATH [Matrix2.hpp]): m must be between 0 or 1.");
public: return GetCol(m);
}
TMatrix2() = default; };
/** // ====================== //
* Copy constructor. // TMatrix2 operator //
*/ // ====================== //
TMatrix2(const TMatrix2<T>& m1) template<RealType T>
TMatrix2<T> operator+= (TMatrix2<T>& m1, T s)
{ {
memcpy(this->m, m1.m, sizeof(T) * 4); m1->m(0, 0) += s;
m1->m(0, 1) += s;
m1->m(1, 0) += s;
m1->m(1, 1) += s;
return m1;
} }
/** template<RealType T>
* Move constructor. TMatrix2<T> operator+= (TMatrix2<T>& m1, const TMatrix2<T>& m2)
*/
TMatrix2(TMatrix2<T>&& m)
{ {
this->m = m.m; m1->m(0, 0) += m2.m(0, 0);
m.m = nullptr; m1->m(0, 1) += m2.m(0, 1);
m1->m(1, 0) += m2.m(1, 0);
m1->m(1, 1) += m2.m(1, 1);
return m1;
} }
/** template<RealType T>
* Construct Matrix from 2d array. TMatrix2<T> operator-= (TMatrix2<T>& m1, T s)
*
* @param(fields) 2D Array with column major order.
*/
TMatrix2(T fields[2][2])
{ {
this->m[0][0] = fields[0][0]; this->m[1][0] = fields[1][0]; m1->m(0, 0) -= s;
this->m[0][1] = fields[0][1]; this->m[1][1] = fields[1][1]; m1->m(0, 1) -= s;
m1->m(1, 0) -= s;
m1->m(1, 1) -= s;
return m1;
} }
/**
* Construct Matrix from parameters.
*
* @param(n00) M[0][0]
* @param(n10) M[1][0]
* @param(n01) M[0][1]
* @param(n11) M[1][1]
*
* @note nXY = n[Row][Col]
*/
TMatrix2(T n00, T n01, T n10, T n11)
{
this->m[0][0] = n00; this->m[1][0] = n01;
this->m[0][1] = n10; this->m[1][1] = n11;
}
/**
* Construct Matrix from two 2d vector columns.
*
* @param(v1) Column zero
* @param(v2) Column one
*/
TMatrix2(const TVector2<T>& v1, const TVector2<T>& v2)
{
this->m[0][0] = v1.x; this->m[1][0] = v2.x;
this->m[0][1] = v1.y; this->m[1][1] = v2.y;
}
public:
FORCEINLINE T& operator() (int n, int m) const template<RealType T>
TMatrix2<T> operator-= (TMatrix2<T>& m1, const TMatrix2<T>& m2)
{ {
return this->m[m][n]; m1->m(0, 0) -= m2.m(0, 0);
m1->m(0, 1) -= m2.m(0, 1);
m1->m(1, 0) -= m2.m(1, 0);
m1->m(1, 1) -= m2.m(1, 1);
return m1;
} }
FORCEINLINE TVector2<T>& operator[] (int m) const
template<RealType T>
TMatrix2<T> operator*= (TMatrix2<T>& m1, T s)
{ {
return reinterpret_cast<TVector2*>(this->m[m]); m1->m[0][0] *= s;
m1->m[0][1] *= s;
m1->m[1][0] *= s;
m1->m[1][1] *= s;
return m1;
}
template<RealType T>
TMatrix2<T> operator*= (TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
TMatrix2<T> c = m1;
m1(0, 0) = c(0, 0) * m2(0, 0) + c(0, 1) * m2(1, 0);
m1(0, 1) = c(0, 0) * m2(0, 1) + c(0, 1) * m2(1, 1);
m1(1, 0) = c(1, 0) * m2(0, 0) + c(1, 1) * m2(1, 0);
m1(1, 1) = c(1, 0) * m2(0, 1) + c(1, 1) * m2(1, 1);
return m1;
} }
}; template<RealType T>
TMatrix2<T> operator+ (const TMatrix2<T>& m1, T s)
{
return TMatrix2<T>(m1(0, 0) + s, m1(0, 1) + s,
m1(1, 0) + s, m1(1, 1) + s);
}
template<RealType T>
TMatrix2<T> operator+ (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return TMatrix2<T>(m1(0, 0) + m2(0, 0), m1(0, 1) + m2(0, 1),
m1(1, 0) + m2(1, 0), m1(1, 1) + m2(1, 1));
}
// ===================== // template<RealType T>
// TMatrix2 operator // TMatrix2<T> operator- (const TMatrix2<T>& m1, T s)
// ===================== // {
return TMatrix2<T>(m1(0, 0) - s, m1(0, 1) - s,
template<RealType T> m1(1, 0) - s, m1(1, 1) - s);
TMatrix2<T> operator+= (TMatrix2<T>& m1, T s) }
{
m1->m(0, 0) += s; template<RealType T>
m1->m(0, 1) += s; TMatrix2<T> operator- (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
m1->m(1, 0) += s; {
m1->m(1, 1) += s; return TMatrix2<T>(m1(0, 0) - m2(0, 0), m1(0, 1) - m2(0, 1),
m1(1, 0) - m2(1, 0), m1(1, 1) - m2(1, 1));
}
return m1; template<RealType T>
} TMatrix2<T> operator* (const TMatrix2<T>& m1, T s)
{
return TMatrix2<T>(m1(0, 0) * s, m1(0, 1) * s,
m1(1, 0) * s, m1(1, 1) * s);
}
template<RealType T>
TMatrix2<T> operator* (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return TMatrix2<T>(m1(0, 0) * m2(0, 0) + m1(0, 1) * m2(1, 0), m1(0, 0) * m2(0, 1) + m1(0, 1) * m2(1, 1),
m1(1, 0) * m2(0, 0) + m1(1, 1) * m2(1, 0), m1(1, 0) * m2(0, 1) + m1(1, 1) * m2(1, 1));
}
template<RealType T>
TVector2<T, false> operator* (const TMatrix2<T>& m1, const TVector2<T, false>& v)
{
return TVector2<T, false>>(m1(0, 0) * v.x + m1(0, 1) * v.y,
m1(1, 0) * v.x + m1(1, 1) * v.y);
}
template<RealType T> template<RealType T>
TMatrix2<T> operator+= (TMatrix2<T>& m1, const TMatrix2<T>& m2) bool operator== (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{ {
m1->m(0, 0) += m2.m(0, 0); return (abs(m1(0, 0) - m2(0, 0)) < P_FLT_INAC && abs(m1(0, 1) - m2(0, 1)) < P_FLT_INAC &&
m1->m(0, 1) += m2.m(0, 1); abs(m1(1, 0) - m2(1, 0)) < P_FLT_INAC && abs(m1(1, 1) - m2(1, 1)) < P_FLT_INAC);
m1->m(1, 0) += m2.m(1, 0); }
m1->m(1, 1) += m2.m(1, 1);
return m1; template<RealType T>
} bool operator!= (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
template<RealType T> return (abs(m1(0, 0) - m2(0, 0)) > P_FLT_INAC || abs(m1(0, 1) - m2(0, 1)) > P_FLT_INAC ||
TMatrix2<T> operator-= (TMatrix2<T>& m1, T s) abs(m1(1, 0) - m2(1, 0)) > P_FLT_INAC || abs(m1(1, 1) - m2(1, 1)) > P_FLT_INAC);
{ }
m1->m(0, 0) -= s;
m1->m(0, 1) -= s;
m1->m(1, 0) -= s;
m1->m(1, 1) -= s;
return m1;
}
template<RealType T>
TMatrix2<T> operator-= (TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
m1->m(0, 0) -= m2.m(0, 0);
m1->m(0, 1) -= m2.m(0, 1);
m1->m(1, 0) -= m2.m(1, 0);
m1->m(1, 1) -= m2.m(1, 1);
return m1;
}
template<RealType T>
TMatrix2<T> operator*= (TMatrix2<T>& m1, T s)
{
m1->m[0][0] *= s;
m1->m[0][1] *= s;
m1->m[1][0] *= s;
m1->m[1][1] *= s;
return m1;
}
template<RealType T>
TMatrix2<T> operator*= (TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
Matrix2 c = m1;
m1(0, 0) = c(0, 0) * m2(0, 0) + c(0, 1) * m2(1, 0);
m1(0, 1) = c(0, 0) * m2(0, 1) + c(0, 1) * m2(1, 1);
m1(1, 0) = c(1, 0) * m2(0, 0) + c(1, 1) * m2(1, 0);
m1(1, 1) = c(1, 0) * m2(0, 1) + c(1, 1) * m2(1, 1);
return m1;
}
template<RealType T>
TMatrix2<T> operator+ (const TMatrix2<T>& m1, T s)
{
return TMatrix2<T>(m1(0, 0) + s, m1(0, 1) + s,
m1(1, 0) + s, m1(1, 1) + s);
}
template<RealType T>
TMatrix2<T> operator+ (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return TMatrix2<T>(m1(0, 0) + m2(0, 0), m1(0, 1) + m2(0, 1),
m1(1, 0) + m2(1, 0), m1(1, 1) + m2(1, 1));
}
template<RealType T>
TMatrix2<T> operator- (const TMatrix2<T>& m1, T s)
{
return TMatrix2<T>(m1(0, 0) - s, m1(0, 1) - s,
m1(1, 0) - s, m1(1, 1) - s);
}
template<RealType T>
TMatrix2<T> operator- (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return TMatrix2<T>(m1(0, 0) - m2(0, 0), m1(0, 1) - m2(0, 1),
m1(1, 0) - m2(1, 0), m1(1, 1) - m2(1, 1));
}
template<RealType T>
TMatrix2<T> operator* (const TMatrix2<T>& m1, T s)
{
return TMatrix2<T>(m1(0, 0) * s, m1(0, 1) * s,
m1(1, 0) * s, m1(1, 1) * s);
}
template<RealType T>
TMatrix2<T> operator* (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return TMatrix2<T>(m1(0, 0) * m2(0, 0) + m1(0, 1) * m2(1, 0), m1(0, 0) * m2(0, 1) + m1(0, 1) * m2(1, 1),
m1(1, 0) * m2(0, 0) + m1(1, 1) * m2(1, 0), m1(1, 0) * m2(0, 1) + m1(1, 1) * m2(1, 1));
}
template<RealType T>
TVector2<T> operator* (const TMatrix2<T>& m1, const TVector2<T>& v)
{
return TVector2<T>(m1(0, 0) * v.x + m1(0, 1) * v.y,
m1(1, 0) * v.x + m1(1, 1) * v.y);
}
template<RealType T>
bool operator== (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return (abs(m1(0, 0) - m2(0, 0)) < P_FLT_INAC && abs(m1(0, 1) - m2(0, 1)) < P_FLT_INAC &&
abs(m1(1, 0) - m2(1, 0)) < P_FLT_INAC && abs(m1(1, 1) - m2(1, 1)) < P_FLT_INAC);
}
template<RealType T>
bool operator!= (const TMatrix2<T>& m1, const TMatrix2<T>& m2)
{
return (abs(m1(0, 0) - m2(0, 0)) > P_FLT_INAC || abs(m1(0, 1) - m2(0, 1)) > P_FLT_INAC ||
abs(m1(1, 0) - m2(1, 0)) > P_FLT_INAC || abs(m1(1, 1) - m2(1, 1)) > P_FLT_INAC);
}
// =============================== // // ============================== //
// Matrix function definition // // Matrix function definition //
// =============================== // // ============================== //
template<RealType T> template<RealType T>
T Determinant(const Matrix2& m1) T Determinant(const TMatrix2<T>& m1)
{ {
return m1(0, 0) * m1(1, 1) - m1(0, 1) * m1(0, 1); return m1(0, 0) * m1(1, 1) - m1(0, 1) * m1(0, 1);
} }
template<RealType T> template<RealType T>
TMatrix2<T> InverseV(TMatrix2<T>& m1) TMatrix2<T> InverseV(TMatrix2<T>& m1)
{ {
float _1_det = 1.0f / Determinant(m1); float _1_det = 1.0f / Determinant(m1);
float m00 = m1(0, 0); float m00 = m1(0, 0);
m1(0, 0) = m1(1, 1); m1(0, 0) = m1(1, 1);
m1(0, 1) = -m1(0, 1); m1(0, 1) = -m1(0, 1);
m1(1, 0) = -m1(1, 0); m1(1, 0) = -m1(1, 0);
m1(1, 1) = m00; m1(1, 1) = m00;
m1 *= _1_det; m1 *= _1_det;
return m1; return m1;
} }
template<RealType T> template<RealType T>
TMatrix2<T> TransposeV(TMatrix2<T>& m1) TMatrix2<T> TransposeV(TMatrix2<T>& m1)
{ {
Swap(m1(0, 1), m1(1, 0)); Swap(m1(0, 1), m1(1, 0));
} }
// =============== // // =============== //
// WITH RETURN // // WITH RETURN //
// =============== // // =============== //
template<RealType T> template<RealType T>
TMatrix2<T> Inverse(TMatrix2<T>& m1) TMatrix2<T> Inverse(TMatrix2<T>& m1)
{ {
float _1_det = 1.0f / Determinant(m1); float _1_det = 1.0f / Determinant(m1);
return TMatrix2<T>(m1(1, 1) * _1_det, m1(1, 0) * _1_det, return TMatrix2<T>(m1(1, 1) * _1_det, m1(1, 0) * _1_det,
m1(0, 1) * _1_det, m1(0, 0) * _1_det); m1(0, 1) * _1_det, m1(0, 0) * _1_det);
} }
template<RealType T> template<RealType T>
TMatrix2<T> Transpose(const TMatrix2<T>& m1) TMatrix2<T> Transpose(const TMatrix2<T>& m1)
{ {
return TMatrix2<T>(m1(0, 0), m1(1, 0), return TMatrix2<T>(m1(0, 0), m1(1, 0),
m1(0, 1), m1(1, 1)); m1(0, 1), m1(1, 1));
} }
template<RealType T> template<RealType T>
bool IsIndentityMatrix(const TMatrix2<T>& m1, T threshold = P_FLT_INAC) bool IsIndentityMatrix(const TMatrix2<T>& m1, T threshold = P_FLT_INAC)
{ {
return (abs(m1(0, 0) - (T)1.0) < P_FLT_INAC && abs(m1(0, 1) - (T)1.0) < P_FLT_INAC && return (abs(m1(0, 0) - (T)1.0) < P_FLT_INAC && abs(m1(0, 1) - (T)1.0) < P_FLT_INAC &&
abs(m1(1, 0) - (T)1.0) < P_FLT_INAC && abs(m1(1, 1) - (T)1.0) < P_FLT_INAC); abs(m1(1, 0) - (T)1.0) < P_FLT_INAC && abs(m1(1, 1) - (T)1.0) < P_FLT_INAC);
} }
} // Phanes::Core::Math } // Phanes::Core::Math