More stuff

This commit is contained in:
Balhau 2023-06-23 00:43:34 +01:00
parent 3f79338304
commit ba009f8edd
6 changed files with 175 additions and 32 deletions

View file

@ -1,4 +1,5 @@
#include "../src/engine/math/matrix3d.hpp"
#include "../src/engine/math/point3d.hpp"
#include "../src/engine/math/vector3d.hpp"
#include <iostream>
@ -40,7 +41,7 @@ int main() {
cout << (id * 3.0f) * v1 << endl;
cout << v1 * (id * 3.0f) << endl;
matrix3d m3(1, 2, 3, 4, 5, 6, 7, 8, 9);
matrix3d m3(1, 2, 3, 4, 5, 5, 7, 8, 9);
cout << endl << m3 << endl;
cout << endl << matrix3d::trans(m3) << endl;
@ -138,4 +139,36 @@ int main() {
cout << "Reject [1,1,0] over [1,0,0]: "
<< vector3d::reject(vector3d(1, 1, 0), vector3d(1, 0, 0)) << endl;
// Checking determinant properties
cout << "Det of identity matrix should be 1: "
<< is_true(matrix3d::det(id) == 1) << endl;
cout << "Det(m^T) should be the same as Det(m): "
<< is_true(matrix3d::det(m3) == matrix3d::det(matrix3d::trans(m3)))
<< endl;
matrix3d m4 = matrix3d(4, -1, 1, 4, 5, 3, -2, 0, 0);
matrix3d m4_inv = matrix3d::inv(m4);
float32 dm4 = matrix3d::det(m4);
float32 dm4_inv = matrix3d::det(m4_inv);
float inv_dm4 = 1.0f / dm4;
float32 pdet = dm4 * dm4_inv;
cout << "Determinant of inverse should be the inverse of the determinant: "
<< is_true(dm4_inv == inv_dm4) << endl;
cout << "Determinant of product should be the product of determinants: "
<< is_true(matrix3d::det(m4 * m4_inv) ==
matrix3d::det(m4) * matrix3d::det(m4_inv))
<< endl;
cout << id.to_string() << endl;
point3d p1 = point3d(0, 1, 0);
point3d p2 = point3d(1, 0, 0);
point3d p3 = point3d(0, 0, 1);
point3d p4 = p1 + v1;
cout << v1 << endl;
cout << point3d() - p4 << endl;
}

View file

@ -13,11 +13,11 @@ files {
buildoptions { "-fpermissive" }
filter "configurations:Debug"
defines { "DEBUG" }
symbols "On"
defines { "DEBUG" }
symbols "On"
filter "configurations:Release"
defines { "NDEBUG" }
optimize "On"
defines { "NDEBUG" }
optimize "On"
filter { "system:linux" }

View file

@ -1,4 +1,5 @@
#include "matrix3d.hpp"
#include <cmath>
namespace engine::math {
@ -10,7 +11,6 @@ void matrix3d::setFloatArray(const float32 m[3][3]) {
this->_m[1][0] = m[1][0];
this->_m[1][1] = m[1][1];
this->_m[1][2] = m[1][2];
this->_m[2][0] = m[2][0];
this->_m[2][1] = m[2][1];
this->_m[2][2] = m[2][2];
@ -90,14 +90,24 @@ matrix3d::matrix3d(const vector3d r1, const vector3d r2, const vector3d r3) {
this->_m[2][2] = r3[2];
};
std::string matrix3d::to_string() const {
std::string str = "\n";
str += "[" + std::to_string(this->_m[0][0]) + ", " +
std::to_string(this->_m[0][1]) + ", " +
std::to_string(this->_m[0][2]) + "]\n";
str += "[" + std::to_string(this->_m[1][0]) + ", " +
std::to_string(this->_m[1][1]) + ", " +
std::to_string(this->_m[1][2]) + "]\n";
str += "[" + std::to_string(this->_m[2][0]) + ", " +
std::to_string(this->_m[2][1]) + ", " +
std::to_string(this->_m[2][2]) + "]\n";
return str;
}
// Overload of << operator. Usefull to combine this with ostream stream
std::ostream &operator<<(std::ostream &stream, matrix3d const &m) {
stream << "[" << m._m[0][0] << "," << m._m[0][1] << "," << m._m[0][2] << "]"
<< std::endl;
stream << "[" << m._m[1][0] << "," << m._m[1][1] << "," << m._m[1][2] << "]"
<< std::endl;
stream << "[" << m._m[2][0] << "," << m._m[2][1] << "," << m._m[2][2] << "]"
<< std::endl;
std::string m_str = m.to_string();
stream << m.to_string();
return stream;
};
@ -123,9 +133,94 @@ bool matrix3d::equals(const matrix3d &first, const matrix3d &second) {
first(2, 2) == second(2, 2);
}
float32 matrix3d::det(const matrix3d &m) {
return m(0, 0) * Det(m(1, 1), m(1, 2), m(2, 1), m(2, 2)) -
m(0, 1) * Det(m(1, 0), m(1, 2), m(2, 0), m(2, 2)) +
m(0, 2) * Det(m(1, 0), m(1, 1), m(2, 0), m(2, 1));
};
matrix3d matrix3d::inv(const matrix3d &m) {
// Rows as vectors
const vector3d &a = m[0];
const vector3d &b = m[1];
const vector3d &c = m[2];
// Cross product of rows
vector3d r0 = vector3d::cross(b, c);
vector3d r1 = vector3d::cross(c, a);
vector3d r2 = vector3d::cross(a, b);
// determinant inverse
float32 idet = 1.0f / vector3d::dot(r2, c);
return matrix3d(Idet(r0, idet), Idet(r1, idet), Idet(r2, idet));
};
matrix3d matrix3d::rotX(float32 angle) {
float32 _cos = cos(angle);
float32 _sin = sin(angle);
return matrix3d(1, 0, 0, 0, _cos, -_sin, 0, _sin, _cos);
};
matrix3d matrix3d::rotY(float32 angle) {
float32 _cos = cos(angle);
float32 _sin = sin(angle);
return matrix3d(_cos, 0, _sin, 0, 1, 0, -_sin, 0, _cos);
};
matrix3d matrix3d::rotZ(float32 angle) {
float32 _cos = cos(angle);
float32 _sin = sin(angle);
return matrix3d(_cos, -_sin, 0, _sin, _cos, 0, 0, 0, 1);
};
matrix3d matrix3d::rot(float32 angle, const vector3d &axis) {
float32 _cos = cos(angle);
float32 _sin = sin(angle);
float32 d = 1 - _cos;
float32 x = axis[0] * d;
float32 y = axis[1] * d;
float32 z = axis[2] * d;
float32 ax_y = x * axis[1];
float32 ax_z = x * axis[2];
float32 ay_z = y * axis[2];
return matrix3d(
_cos + x * axis[0], ax_y - _sin * axis[2], ax_z + _sin * axis[1],
ax_y + _sin * axis[2], _cos + y * axis[1], ay_z - _sin * axis[0],
ax_z - _sin * axis[1], ay_z + _sin * axis[0], _cos + z * axis[2]);
};
matrix3d matrix3d::scale(float32 scalex, float32 scaley, float32 scalez) {
return matrix3d(scalex, 0, 0, 0, scaley, 0, 0, 0, scalez);
};
matrix3d matrix3d::scale(float32 scale, const vector3d &vector) {
scale -= 1;
float32 x = vector[0] * scale;
float32 y = vector[1] * scale;
float32 z = vector[2] * scale;
float vx_vy = x * vector[1];
float vx_vz = x * vector[1];
float vy_vz = y * vector[2];
return matrix3d(x * vector[0] + 1, vx_vy, vx_vz, vx_vy, y * vector[1] + 1,
vx_vz, vx_vz, vy_vz, z * vector[2] + 1);
};
matrix3d matrix3d::skew(float32 angle, const vector3d v1, const vector3d &v2) {
float32 t = tan(angle);
float32 x = v1[0];
float32 y = v1[1];
float32 z = v1[2];
return matrix3d();
};
// Overload of + operator. This will add 2 matrix3d instances
matrix3d operator+(const matrix3d &left, const matrix3d &right) {
MATRIX(add);
Matrix(add);
add[0][0] = left[0][0] + right[0][0];
add[0][1] = left[0][1] + right[0][1];
add[0][2] = left[0][2] + right[0][2];
@ -142,7 +237,7 @@ matrix3d operator+(const matrix3d &left, const matrix3d &right) {
};
matrix3d operator-(const matrix3d &left, const matrix3d &right) {
MATRIX(m_temp);
Matrix(m_temp);
m_temp[0][0] = left[0][0] - right[0][0];
m_temp[0][1] = left[0][1] - right[0][1];
m_temp[0][2] = left[0][2] - right[0][2];

View file

@ -1,18 +1,20 @@
#pragma once
#include "../../platform/base.hpp"
#include "math.h"
#include "vector3d.hpp"
#define MATRIX(n) float32 n[3][3]
// Defines a matrix in termos of float32
#define Matrix(n) float32 n[3][3]
// Computes determinant sub block
#define Det(a, b, c, d) (a * d - b * c)
#define Idet(row, idet) row[0] * idet, row[1] * idet, row[2] * idet
namespace engine::math {
class matrix3d {
private:
MATRIX(_m);
struct matrix3d {
Matrix(_m);
void setFloatArray(const float32[3][3]);
void setAll(float32 v);
public:
// Default empty constructor
matrix3d();
~matrix3d();
@ -27,6 +29,7 @@ public:
const vector3d operator[](int i) const;
float32 operator()(int r, int c);
float32 operator()(int r, int c) const;
std::string to_string() const;
friend std::ostream &operator<<(std::ostream &stream,
engine::math::matrix3d const &m);
@ -36,8 +39,22 @@ public:
static matrix3d trans(const matrix3d &matrix);
// Compute the matrix determinant value
static float32 det(const matrix3d &matrix);
// Compute matrix inverse
static matrix3d inv(const matrix3d &m);
// Check if two matrices are equal, by checking each entry equality
static bool equals(const matrix3d &first, const matrix3d &second);
// Rotation matrices
static matrix3d rotX(float32 angle);
static matrix3d rotY(float32 angle);
static matrix3d rotZ(float32 angle);
static matrix3d rot(float32 angle, const vector3d &axis);
// Scaling matrix
static matrix3d scale(float32 scale_x, float32 scale_y, float32 scale_z);
// Scaling matrix in relation to a given vector
static matrix3d scale(float32 scale, const vector3d &vector);
// Skew matrix based on an angle and two vector3d
static matrix3d skew(float32 angle, const vector3d v1, const vector3d &v2);
};
// Non instance operator overloading

View file

@ -21,27 +21,27 @@ vector3d &vector3d::operator-=(const vector3d &other) {
};
vector3d operator+(const vector3d &left, const vector3d &right) {
return vector3d(left[0] + right[0], left[1] + right[1], left[2] + right[2]);
return vector3d(left.x + right.x, left.y + right.y, left.z + right.z);
}
vector3d operator-(const vector3d &left, const vector3d &right) {
return vector3d(left[0] - right[0], left[1] - right[1], left[2] - right[2]);
return vector3d(left.x - right.x, left.y - right.y, left.z - right.z);
}
vector3d operator-(const vector3d &vector, float32 scalar) {
return vector3d(vector[0] - scalar, vector[1] - scalar, vector[2] - scalar);
return vector3d(vector.x - scalar, vector.y - scalar, vector.z - scalar);
}
vector3d operator*(float32 scalar, const vector3d &vector) {
return vector3d(vector[0] * scalar, vector[1] * scalar, vector[2] * scalar);
return vector3d(vector.x * scalar, vector.y * scalar, vector.z * scalar);
};
vector3d operator*(const vector3d &vector, float32 scalar) {
return vector3d(vector[0] * scalar, vector[1] * scalar, vector[2] * scalar);
return vector3d(vector.x * scalar, vector.y * scalar, vector.z * scalar);
}
vector3d operator*(const vector3d &v1, const vector3d &v2) {
return vector3d(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]);
return vector3d(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
}
vector3d vector3d::operator-() {
@ -70,9 +70,6 @@ float32 vector3d::dot(const vector3d &one, const vector3d &other) {
};
// Cross product of two vectors given by
// v1_y*v2_z-v1_z*v2y,
// v1_z*v2_x-v1_x*v2_z
// v1_x*v2_y-v1_y*v2_x
vector3d vector3d::cross(const vector3d &v1, const vector3d &v2) {
return vector3d(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z,
v1.x * v2.y - v1.y * v2.x);

View file

@ -2,6 +2,7 @@
#include "../../platform/base.hpp"
#include <cmath>
#include <iostream>
using namespace std;
@ -9,11 +10,9 @@ namespace engine::math {
/**
* Class that abstracts away a vector in 3 dimensions
*/
class vector3d {
private:
struct vector3d {
float32 x, y, z;
public:
// Default constructor;
vector3d();
/***
@ -40,6 +39,8 @@ public:
vector3d operator/(const float32 scalar);
vector3d operator-();
void dummy();
// Compute the magnitude of the vector
static float32 norm(const vector3d &v);
// Compute the normalized vector