JPL Spatial
Sound spatialization and propagation library
Loading...
Searching...
No Matches
MinimalMat.h
Go to the documentation of this file.
1//
2// ██╗██████╗ ██╗ ██╗██████╗ ███████╗
3// ██║██╔══██╗ ██║ ██║██╔══██╗██╔════╝ ** JPLSpatial **
4// ██║██████╔╝ ██║ ██║██████╔╝███████╗
5// ██ ██║██╔═══╝ ██║ ██║██╔══██╗╚════██║ https://github.com/Jaytheway/JPLSpatial
6// ╚█████╔╝██║ ███████╗██║██████╔╝███████║
7// ╚════╝ ╚═╝ ╚══════╝╚═╝╚═════╝ ╚══════╝
8//
9// Copyright 2024 Jaroslav Pevno, JPLSpatial is offered under the terms of the ISC license:
10//
11// Permission to use, copy, modify, and/or distribute this software for any purpose with or
12// without fee is hereby granted, provided that the above copyright notice and this permission
13// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
14// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
16// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
17// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20#pragma once
21
22#include "JPLSpatial/Core.h"
27
28#include <cmath>
29
30namespace JPL::Math
31{
33 template<class Vec2>
34 struct Mat2
35 {
36 using Float = std::remove_cvref_t<decltype(std::declval<Vec2>().X)>;
37
38 // Columns: [ l1 | l2 ]
40
41 [[nodiscard]] static JPL_INLINE constexpr Mat2 Identity() noexcept { return { Vec2{ 1, 0 }, Vec2{ 0, 1 } }; }
42 [[nodiscard]] static JPL_INLINE constexpr Mat2 FromColumns(const Vec2& l1, const Vec2& l2) noexcept { return { l1, l2 }; }
43
44 // p' = M * p (column-major)
45 [[nodiscard]] JPL_INLINE constexpr Vec2 Transform(const Vec2& p) const noexcept { return C0 * p.X + C1 * p.Y; }
46
47 [[nodiscard]] JPL_INLINE constexpr Float Det() const noexcept{ return CrossProduct(C0, C1); }
48 [[nodiscard]] JPL_INLINE constexpr bool IsInvertible(Float eps = Float(1e-6)) const noexcept{ return Math::Abs(Det()) >= eps; }
49
50 // Build inverse into 'out', returns success
51 [[nodiscard]] inline constexpr bool TryInverse(Mat2& out, Float eps = Float(1e-6)) const
52 {
53 const Float det = Det();
54 if (!JPL_ENSURE(Math::Abs(det) >= eps))
55 {
56 out = Identity();
57 return false;
58 }
59 const Float inv = Float(1.0) / det;
60
61 // Rows of L^{-1}
62 const Vec2 r0{ C1.Y, -C1.X }; // PerpCW(C1)
63 const Vec2 r1{ -C0.Y, C0.X }; // PerpCCW(C0)
64 const Vec2 R0 = r0 * inv, R1 = r1 * inv;
65
66 // Convert rows -> columns for column-major storage
67 out.C0 = Vec2{ R0.X, R1.X };
68 out.C1 = Vec2{ R0.Y, R1.Y };
69 return true;
70 }
71
72 [[nodiscard]] JPL_INLINE constexpr Mat2 Inversed(Float eps = Float(1e-6)) const
73 {
74 Mat2 m;
76 return m;
77 }
78 };
79
81 template<CVec3 Vec3>
82 struct Mat3
83 {
85
86 // Columns: [ l1 | l2 | l3 ]
87 Vec3 C0, C1, C2;
88
89 [[nodiscard]] static JPL_INLINE constexpr Mat3 Identity() noexcept { return { Vec3{1, 0, 0}, Vec3{0, 1, 0}, Vec3{0, 0, 1} }; }
90 [[nodiscard]] static JPL_INLINE constexpr Mat3 FromColumns(const Vec3& l1, const Vec3& l2, const Vec3& l3) noexcept { return { l1, l2, l3 }; }
91
92 [[nodiscard]] JPL_INLINE constexpr Vec3 Transform(const Vec3& v) const noexcept { return C0 * GetX(v) + C1 * GetY(v) + C2 * GetZ(v); }
93
94 [[nodiscard]] JPL_INLINE constexpr Float Det() const { return DotProduct(C0, CrossProduct(C1, C2)); }
95 [[nodiscard]] JPL_INLINE constexpr bool IsInvertible(Float eps = Float(1e-6)) const noexcept { return Math::Abs(Det()) >= eps; }
96
97 [[nodiscard]] inline constexpr bool TryInverse(Mat3& out, Float eps = Float(1e-6)) const
98 {
99 const Vec3 v1 = CrossProduct(C1, C2); // cofactor row 0^T
100 const Vec3 v2 = CrossProduct(C2, C0); // cofactor row 1^T
101 const Vec3 v3 = CrossProduct(C0, C1); // cofactor row 2^T
102 const Float det = DotProduct(C0, v1);
103 if (!JPL_ENSURE(Math::Abs(det) >= eps))
104 {
105 out = Identity();
106 return false;
107 }
108 const Float inv = 1.0f / det;
109
110 const Vec3 R0 = v1 * inv; // row 0 of L^{-1}
111 const Vec3 R1 = v2 * inv; // row 1 of L^{-1}
112 const Vec3 R2 = v3 * inv; // row 2 of L^{-1}
113
114 // rows -> columns (column-major)
115 out.C0 = Vec3{ GetX(R0), GetX(R1), GetX(R2) };
116 out.C1 = Vec3{ GetY(R0), GetY(R1), GetY(R2) };
117 out.C2 = Vec3{ GetZ(R0), GetZ(R1), GetZ(R2) };
118 return true;
119 }
120
121 [[nodiscard]] JPL_INLINE constexpr Mat3 Inversed(Float eps = Float(1e-6)) const
122 {
123 Mat3 m;
124 TryInverse(m, eps);
125 return m;
126 }
127 };
128} // namespace JPL
#define JPL_ENSURE(inExpression,...)
Define ENSURE.
Definition ErrorReporting.h:90
std::remove_cvref_t< decltype(GetX(std::declval< Vec3 >()))> FloatOf
Definition Vec3Math.h:36
Definition Math.h:61
JPL_INLINE constexpr auto Abs(const T &value) noexcept
Standard abs is not constexpr in C++20.
Definition Math.h:87
JPL_INLINE auto GetX(const Vec3Type &v) noexcept
Definition Vec3Traits.h:35
JPL_INLINE auto GetZ(const Vec3Type &v) noexcept
Definition Vec3Traits.h:37
JPL_INLINE auto GetY(const Vec3Type &v) noexcept
Definition Vec3Traits.h:36
JPL_INLINE simd min(const simd &a, const simd &b) noexcept
Element-wise min.
Definition SIMD.h:1813
Minimal 2x2 matrix interface.
Definition MinimalMat.h:35
constexpr bool TryInverse(Mat2 &out, Float eps=Float(1e-6)) const
Definition MinimalMat.h:51
static JPL_INLINE constexpr Mat2 FromColumns(const Vec2 &l1, const Vec2 &l2) noexcept
Definition MinimalMat.h:42
JPL_INLINE constexpr bool IsInvertible(Float eps=Float(1e-6)) const noexcept
Definition MinimalMat.h:48
std::remove_cvref_t< decltype(std::declval< Vec2 >().X)> Float
Definition MinimalMat.h:36
static JPL_INLINE constexpr Mat2 Identity() noexcept
Definition MinimalMat.h:41
Vec2 C1
Definition MinimalMat.h:39
Vec2 C0
Definition MinimalMat.h:39
JPL_INLINE constexpr Vec2 Transform(const Vec2 &p) const noexcept
Definition MinimalMat.h:45
JPL_INLINE constexpr Mat2 Inversed(Float eps=Float(1e-6)) const
Definition MinimalMat.h:72
JPL_INLINE constexpr Float Det() const noexcept
Definition MinimalMat.h:47
Minimal 3x3 matrix interface.
Definition MinimalMat.h:83
Internal::FloatOf< Vec3 > Float
Definition MinimalMat.h:84
Vec3 C0
Definition MinimalMat.h:87
JPL_INLINE constexpr Float Det() const
Definition MinimalMat.h:94
JPL_INLINE constexpr Vec3 Transform(const Vec3 &v) const noexcept
Definition MinimalMat.h:92
static JPL_INLINE constexpr Mat3 FromColumns(const Vec3 &l1, const Vec3 &l2, const Vec3 &l3) noexcept
Definition MinimalMat.h:90
JPL_INLINE constexpr Mat3 Inversed(Float eps=Float(1e-6)) const
Definition MinimalMat.h:121
JPL_INLINE constexpr bool IsInvertible(Float eps=Float(1e-6)) const noexcept
Definition MinimalMat.h:95
Vec3 C2
Definition MinimalMat.h:87
constexpr bool TryInverse(Mat3 &out, Float eps=Float(1e-6)) const
Definition MinimalMat.h:97
Vec3 C1
Definition MinimalMat.h:87
static JPL_INLINE constexpr Mat3 Identity() noexcept
Definition MinimalMat.h:89
Definition MinimalVec2.h:29
float X
Definition MinimalVec2.h:30
float Y
Definition MinimalVec2.h:31