Messing with matrices.
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 5m32s
Build Docs With Doxygen / Explore-Gitea-Actions (push) Successful in 30s

This commit is contained in:
2025-06-11 08:12:31 -05:00
parent 2886bbb397
commit 9ecb64a2fe
7 changed files with 104 additions and 7 deletions

View File

@@ -15,6 +15,9 @@
#include <cstddef>
#include <cstdlib>
#include <algorithm>
#include <ranges>
#include <initializer_list>
#include "Vector.hpp"
namespace J3ML::LinearAlgebra
@@ -22,8 +25,8 @@ namespace J3ML::LinearAlgebra
template <uint ROWS, uint COLS, typename T>
class Matrix
{
class Matrix {
public:
static constexpr uint Diag = std::min(ROWS, COLS);
using RowVector = Vector<ROWS, T>;
@@ -33,6 +36,22 @@ namespace J3ML::LinearAlgebra
enum { Rows = ROWS };
enum { Cols = COLS };
Matrix(std::initializer_list<T> arg) {
int iterator = 0;
for (T entry : arg) {
int x = iterator % ROWS;
int y = iterator / ROWS;
elems[x][y] = entry;
iterator++;
}
}
Matrix(const std::vector<T>& entries);
Matrix(const std::vector<RowVector>& rows);
void AssertRowSize(uint rows)
{
assert(rows < Rows && "");

View File

@@ -5,6 +5,8 @@
#include <J3ML/Algorithm/RNG.hpp>
#include <algorithm>
#include <iostream>
#include <bits/ostream.tcc>
using namespace J3ML::Algorithm;
@@ -569,10 +571,15 @@ namespace J3ML::LinearAlgebra {
/// Returns true if this Matrix4x4 is equal to the given Matrix4x4, up to given per-element epsilon.
bool Equals(const Matrix4x4& other, float epsilon = 1e-3f) const;
[[nodiscard]] std::string ToString() const;
protected:
float elems[4][4];
Vector3 TransformDir(float tx, float ty, float tz) const;
};
}
std::ostream& operator << (std::ostream& out, const Matrix4x4& rhs);
}

View File

@@ -1,11 +1,12 @@
#pragma once
#include <cstddef>
#include <cstdlib>
namespace J3ML::LinearAlgebra
{
template <uint DIMS, typename T>
template <size_t DIMS, typename T>
class Vector {
public:
enum { Dimensions = DIMS};

View File

@@ -384,6 +384,7 @@ namespace J3ML::LinearAlgebra {
static Vector2 RandomBox(Algorithm::RNG& rng, float minElem, float maxElem);
[[nodiscard]] std::string ToString() const;
};
Vector2 operator*(float lhs, const Vector2 &rhs);

View File

@@ -30,6 +30,9 @@ namespace J3ML::LinearAlgebra {
because there is a considerable SIMD performance benefit in the first form.
@see x, y, z, w. */
Vector4(float X, float Y, float Z, float W);
Vector4(float XYZW) : x(XYZW), y(0), z(0), w(0) {}
Vector4(float X, float Y) : x(X), y(Y), z(0), w(0) {}
Vector4(float X, float Y, float Z) : x(X), y(Y), z(Z), w(0) {}
/// The Vector4 copy constructor.
Vector4(const Vector4& copy) { Set(copy); }
Vector4(Vector4&& move) = default;

View File

@@ -15,6 +15,7 @@
#include <J3ML/Geometry.hpp>
#include <J3ML/J3ML.hpp>
#include <jlog/Logger.hpp>
#include <J3ML/LinearAlgebra/Matrix.hpp>
int main(int argc, char** argv)
@@ -50,9 +51,28 @@ int main(int argc, char** argv)
}
Ray a({420, 0, 0}, {1, 0, 0});
std::cout << a << std::endl;
Matrix4x4 A {
1, 2, 0, 1,
3, 1, 2, 0,
0, 4, 1, 2,
2, 0, 3, 1
};
Matrix4x4 B {
0, 1, 2, 3,
1, 0, 1, 0,
2, 3, 0, 1,
1, 2, 1, 0
};
auto C = A*B;
std::cout << C << std::endl;
std::cout << "j3ml demo coming soon" << std::endl;
return 0;
}

View File

@@ -1,9 +1,10 @@
#include <iomanip>
#include <J3ML/LinearAlgebra/Matrix4x4.hpp>
#include <J3ML/LinearAlgebra/Vector4.hpp>
#include <J3ML/LinearAlgebra/Matrix3x3.hpp>
#include <J3ML/LinearAlgebra/Quaternion.hpp>
#include <J3ML/LinearAlgebra/Matrices.inl>
#include <iostream>
namespace J3ML::LinearAlgebra {
@@ -679,6 +680,11 @@ namespace J3ML::LinearAlgebra {
}
std::ostream & operator<<(std::ostream &out, const Matrix4x4 &rhs) {
out << rhs.ToString();
return out;
}
void Matrix4x4::InverseOrthonormal()
{
//assert(!ContainsProjection());
@@ -1014,6 +1020,46 @@ namespace J3ML::LinearAlgebra {
return true;
}
std::string trim_trailing_zeros(const std::string &value) {
std::string str = value;
// Ensure that there is a decimal point somewhere (there should be)
if(str.find('.') != std::string::npos)
{
// Remove trailing zeroes
str = str.substr(0, str.find_last_not_of('0')+1);
// If the decimal point is now the last character, remove that as well
if(str.find('.') == str.size()-1)
{
str = str.substr(0, str.size()-1);
}
}
return str;
}
std::string Matrix4x4::ToString() const {
// Determine the maximum width for any element in the matrix.
size_t max_width = 0;
for (size_t row = 0; row < 4; ++row) {
for (size_t col = 0; col < 4; ++col) {
std::string s = std::to_string(At(row, col));
s = trim_trailing_zeros(s);
max_width = std::max(max_width, s.length());
}
}
for (size_t row = 0; row < 4; ++row) {
for (size_t col = 0; col < 4; ++col) {
auto val = this->At(row, col);
std::cout << std::right << std::setw(static_cast<int>(max_width)) << val << " ";
}
std::cout << std::endl;
}
}
void
Matrix4x4::Set(float _00, float _01, float _02, float _03, float _10, float _11, float _12, float _13, float _20,
float _21, float _22, float _23, float _30, float _31, float _32, float _33) {