Initial commit
This commit is contained in:
110
inc/EliteMath/EMat22.h
Normal file
110
inc/EliteMath/EMat22.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*=============================================================================*/
|
||||
// Copyright 2021-2022 Elite Engine
|
||||
// Authors: Matthieu Delaere
|
||||
/*=============================================================================*/
|
||||
// EMat22.h: Row Major Matrix 2x2 struct
|
||||
// | x1 , y1 |
|
||||
// | x2 , y2 |
|
||||
// Info: Row Major Matrix for cache coherency, even though this is a small piece of data,
|
||||
// it is a good practice.
|
||||
/*=============================================================================*/
|
||||
#ifndef ELITE_MATH_MATRIX22
|
||||
#define ELITE_MATH_MATRIX22
|
||||
|
||||
namespace Elite {
|
||||
|
||||
#define IdentityMat22 Mat22();
|
||||
|
||||
//Matrix 2x2
|
||||
struct Mat22
|
||||
{
|
||||
//=== Datamembers ===
|
||||
Vector2 r[2] = { {1.f,0.f},{0.f, 1.f} };
|
||||
|
||||
//=== Constructors ===
|
||||
Mat22() {};
|
||||
Mat22(float x1, float y1, float x2, float y2)
|
||||
{ r[0] = Vector2(x1, y1); r[1] = Vector2(x2, y2); };
|
||||
Mat22(const Vector2& r1, const Vector2& r2)
|
||||
{ r[0] = r1; r[1] = r2; };
|
||||
|
||||
//=== Matrix Conversions Functions ===
|
||||
#ifdef USE_BOX2D
|
||||
//From row-major to column-major
|
||||
Mat22& operator=(const b2Mat22& m)
|
||||
{
|
||||
r[0][0] = m.ex.x; r[0][1] = m.ex.y;
|
||||
r[1][0] = m.ey.x; r[1][1] = m.ey.y;
|
||||
return *this;
|
||||
}
|
||||
operator b2Mat22() const
|
||||
{
|
||||
return b2Mat22(r[0][0], r[1][0], r[0][1], r[1][1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
//=== Arithmetic Operators ===
|
||||
inline auto operator+(const Mat22& m) const
|
||||
{ return Mat22(r[0] + m.r[0], r[1] + m.r[1]); }
|
||||
inline auto operator-(const Mat22& m) const
|
||||
{ return Mat22(r[0] - m.r[0], r[1] - m.r[1]); }
|
||||
inline auto operator*(float scale) const
|
||||
{ return Mat22(r[0] * scale, r[1] * scale); }
|
||||
inline auto operator*(const Mat22& m) const
|
||||
{
|
||||
//The rows of the first matrix are multiplied by the columns of the second one
|
||||
Mat22 res = {};
|
||||
for(auto row = 0; row < 2; ++row)
|
||||
{
|
||||
for(auto col = 0; col < 2; ++col)
|
||||
{
|
||||
res.r[row][col] = r[row][0] * m.r[0][col] +
|
||||
r[row][1] * m.r[1][col];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
inline auto operator*(const Vector2& v) const
|
||||
{
|
||||
//Same principle as mat22 * mat22, but with a "column" Vector2...
|
||||
return Vector2(
|
||||
r[0][0] * v.x + r[0][1] * v.y,
|
||||
r[1][0] * v.x + r[1][1] * v.y);
|
||||
}
|
||||
|
||||
//=== Compound Assignment Operators ===
|
||||
inline auto& operator+=(const Mat22& m)
|
||||
{ r[0] += m.r[0]; r[1] += m.r[1]; return *this; }
|
||||
inline auto& operator-=(const Mat22& m)
|
||||
{ r[0] -= m.r[0]; r[1] -= m.r[1]; return *this; }
|
||||
inline auto& operator*=(float scale)
|
||||
{ r[0] *= scale; r[1] *= scale; return *this; }
|
||||
inline auto& operator*=(const Mat22& m)
|
||||
{ auto result = *this * m; return *this = result; }
|
||||
|
||||
//=== Internal Vector Functions ===
|
||||
void SetIdentity()
|
||||
{ r[0] = Vector2( 1.f, 0.f); r[1] = Vector2(0.f, 1.f); }
|
||||
auto Determinant() const //Formula: x1*y2 - y1*x2
|
||||
{ return r[0][0] * r[1][1] - r[0][1] * r[1][0]; }
|
||||
auto Inverse() const
|
||||
{
|
||||
auto det = Determinant();
|
||||
if (AreEqual(det, 0.f)) //We cannot get inverse because determinant is zero, return identity matrix instead
|
||||
return IdentityMat22;
|
||||
|
||||
det = 1.f / det;
|
||||
auto m00 = det * r[1][1], m01 = det * (-r[0][1]);
|
||||
auto m10 = det * (-r[1][0]), m11 = det * r[0][0];
|
||||
return Mat22(m00, m01, m10, m11);
|
||||
}
|
||||
};
|
||||
|
||||
//=== Global Matrix Functions ===
|
||||
inline auto GetDeterminant(const Mat22& m)
|
||||
{ return m.Determinant(); }
|
||||
|
||||
inline auto GetInverse(const Mat22& m)
|
||||
{ return m.Inverse(); }
|
||||
}
|
||||
#endif
|
||||
21
inc/EliteMath/EMath.h
Normal file
21
inc/EliteMath/EMath.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*=============================================================================*/
|
||||
// Copyright 2021-2022 Elite Engine
|
||||
// Authors: Matthieu Delaere
|
||||
/*=============================================================================*/
|
||||
// EMath.h: General Math header that includes all math types and utilities
|
||||
/*=============================================================================*/
|
||||
#ifndef ELITE_MATH
|
||||
#define ELITE_MATH
|
||||
|
||||
/* --- STANDARD --- */
|
||||
#include <math.h>
|
||||
/* --- UTILITIES --- */
|
||||
#include "EMathUtilities.h"
|
||||
/* --- TYPES --- */
|
||||
#include "EVector2.h"
|
||||
#include "EVector3.h"
|
||||
#include "EMat22.h"
|
||||
#include "FMatrix.h"
|
||||
|
||||
/* --- TYPE DEFINES --- */
|
||||
#endif
|
||||
133
inc/EliteMath/EMathUtilities.h
Normal file
133
inc/EliteMath/EMathUtilities.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*=============================================================================*/
|
||||
// Copyright 2021-2022 Elite Engine
|
||||
// Authors: Matthieu Delaere, Thomas Goussaert
|
||||
/*=============================================================================*/
|
||||
// EMathUtilities.h: Utility class containing a bunch of commonely used functionality (not custom-type specific)
|
||||
/*=============================================================================*/
|
||||
#ifndef ELITE_MATH_UTILITIES
|
||||
#define ELITE_MATH_UTILITIES
|
||||
//Standard C++ includes
|
||||
#include <cstdlib>
|
||||
#include <cfloat>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Elite {
|
||||
/* --- CONSTANTS --- */
|
||||
#define E_PI 3.14159265358979323846
|
||||
#define E_PI_2 1.57079632679489661923
|
||||
#define E_PI_4 0.785398163397448309616
|
||||
|
||||
/* --- FUNCTIONS --- */
|
||||
/*! Comparing two values (preferably float or doubles) and see if they are equal. You can change the precision (by default: epsilon)*/
|
||||
template<typename T, typename = std::enable_if<std::is_pod<T>::value>>
|
||||
constexpr bool AreEqual(T a, T b, float precision = FLT_EPSILON)
|
||||
{
|
||||
if (abs(a - b) > precision)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
/*! An accurate inverse square root*/
|
||||
inline float InvSqrt(float f) //sqrtf not defined as constexpr
|
||||
{
|
||||
return 1.0f / sqrtf(f);
|
||||
}
|
||||
/*! An fast inverse square root, not fully accurate. Implementation based on Quake III Arena*/
|
||||
/*! Reference: https://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/ */
|
||||
inline float InvSqrtFst(float f)
|
||||
{
|
||||
const float xHalf = 0.5f * f;
|
||||
int i = *reinterpret_cast<int*>(&f);
|
||||
i = 0x5f3759df - (i >> 1);
|
||||
f = *reinterpret_cast<float*>(&i);
|
||||
f = f*(1.5f - xHalf*f*f);
|
||||
return f;
|
||||
}
|
||||
/*! Function to square a number */
|
||||
template<typename T, typename = std::enable_if<std::is_pod<T>::value>>
|
||||
constexpr auto Square(T v)
|
||||
{
|
||||
return v*v;
|
||||
}
|
||||
/*! Function to convert degrees to radians */
|
||||
constexpr float ToRadians(const float angle)
|
||||
{
|
||||
return angle * (static_cast<float>(E_PI) / 180.f);
|
||||
}
|
||||
/*! Function to convert radians to degrees */
|
||||
constexpr float ToDegrees(const float angle)
|
||||
{
|
||||
return angle * (180.f / static_cast<float>(E_PI));
|
||||
}
|
||||
/*! Clamped angle between -pi, pi (in radians) */
|
||||
inline float ClampedAngle(const float radians)
|
||||
{
|
||||
float a = fmodf(radians + b2_pi, 2 * b2_pi);
|
||||
a = a >= 0 ? (a - b2_pi) : (a + b2_pi);
|
||||
return a;
|
||||
}
|
||||
/*! Template function to clamp between a minimum and a maximum value -> in STD since c++17 */
|
||||
template<typename T>
|
||||
constexpr T Clamp(const T a, T min, T max)
|
||||
{
|
||||
if (a < min)
|
||||
return min;
|
||||
|
||||
if (a > max)
|
||||
return max;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
/*! Template function to clamp between a minimum and a maximum value*/
|
||||
template<typename T>
|
||||
constexpr T ClampRef(T& a, T min, T max)
|
||||
{
|
||||
if (a < min)
|
||||
a = min;
|
||||
|
||||
if (a > max)
|
||||
a = max;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
/*! Random Integer */
|
||||
inline int randomInt(int max = 1)
|
||||
{ return rand() % max; }
|
||||
|
||||
/*! Random Float */
|
||||
inline float randomFloat(float max = 1.f)
|
||||
{ return max * (float(rand()) / RAND_MAX); }
|
||||
|
||||
/*! Random Float */
|
||||
inline float randomFloat(float min, float max)
|
||||
{
|
||||
auto range = max - min;
|
||||
return (range * (float(rand()) / RAND_MAX)) + min;
|
||||
}
|
||||
|
||||
/*! Random Binomial Float */
|
||||
inline float randomBinomial(float max = 1.f)
|
||||
{ return randomFloat(max) - randomFloat(max); }
|
||||
|
||||
/*! Linear Interpolation */
|
||||
/*inline float Lerp(float v0, float v1, float t)
|
||||
{ return (1 - t) * v0 + t * v1; }*/
|
||||
template<typename T>
|
||||
inline T Lerp(T v0, T v1, float t)
|
||||
{ return (1 - t) * v0 + t * v1; }
|
||||
|
||||
/*! Smooth Step */
|
||||
inline float smoothStep(float edge0, float edge1, float x)
|
||||
{
|
||||
// Scale, bias and saturate x to 0..1 range
|
||||
x = Clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
|
||||
// Evaluate polynomial
|
||||
return x * x * (3 - 2 * x);
|
||||
}
|
||||
|
||||
/*! Sign Function*/
|
||||
template <typename T> int sign(T val)
|
||||
{ return (T(0) < val) - (val < T(0)); }
|
||||
}
|
||||
#endif
|
||||
158
inc/EliteMath/EMatrix2x3.cpp
Normal file
158
inc/EliteMath/EMatrix2x3.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
#include "stdafx.h"
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "EMatrix2x3.h"
|
||||
|
||||
|
||||
Matrix2x3::Matrix2x3(Elite::Vector2 dirX, Elite::Vector2 dirY, Elite::Vector2 orig)
|
||||
: dirX{ dirX }, dirY{ dirY }, orig{ orig }
|
||||
{}
|
||||
|
||||
Matrix2x3::Matrix2x3(float e1X, float e1Y, float e2X, float e2Y, float oX, float oY)
|
||||
: Matrix2x3{ Elite::Vector2{e1X, e1Y}, Elite::Vector2{e2X, e2Y}, Elite::Vector2{oX, oY} }
|
||||
{}
|
||||
|
||||
Elite::Vector2 Matrix2x3::Transform(const Elite::Vector2& vector) const
|
||||
{
|
||||
return Elite::Vector2{ vector.x * dirX + vector.y * dirY } + orig;
|
||||
}
|
||||
|
||||
float Matrix2x3::Determinant() const
|
||||
{
|
||||
return dirX.x * dirY.y - dirX.y * dirY.x;
|
||||
}
|
||||
|
||||
Matrix2x3 Matrix2x3::Inverse() const
|
||||
{
|
||||
//Calculate Determinant
|
||||
float det = Determinant();
|
||||
|
||||
//1)calculate matrix of minors
|
||||
//2)Use the alternating law of signs to produce the matrix of cofactors
|
||||
//3)Transpose
|
||||
//4)the inverse matrix is 1/Determinant * the resulting matrix
|
||||
return Matrix2x3{
|
||||
Elite::Vector2(+dirY.y, -dirX.y) / det,
|
||||
Elite::Vector2(-dirY.x, +dirX.x) / det,
|
||||
Elite::Vector2(dirY.x * orig.y - dirY.y * orig.x, -(dirX.x * orig.y - dirX.y * orig.x)) / det
|
||||
};
|
||||
}
|
||||
|
||||
bool Matrix2x3::Equals(const Matrix2x3& other, float epsilon ) const
|
||||
{
|
||||
return (dirX == other.dirX) &&
|
||||
(dirY == other.dirY) &&
|
||||
(orig == other.orig);
|
||||
}
|
||||
|
||||
std::string Matrix2x3::ToString() const
|
||||
{
|
||||
return std::string( "Matrix2x3( x( ") +
|
||||
std::to_string(dirX.x) + ", " + std::to_string( dirX.y )
|
||||
+ " ), y( " + std::to_string( dirY.x ) + ", " + std::to_string( dirY.y )
|
||||
+ " ), orig( " + std::to_string( orig.x ) + ", " + std::to_string( orig.y ) + " ) )";
|
||||
}
|
||||
|
||||
void Matrix2x3::SetAsIdentity()
|
||||
{
|
||||
dirX = Elite::Vector2{1, 0};
|
||||
dirY = Elite::Vector2{0, 1};
|
||||
orig = Elite::Vector2{0, 0};
|
||||
}
|
||||
|
||||
void Matrix2x3::SetAsRotate(float degrees)
|
||||
{
|
||||
float radians = degrees * 3.1415926535f / 180;
|
||||
dirX = Elite::Vector2{ cos( radians ), sin( radians ) };
|
||||
dirY = Elite::Vector2{ -sin( radians ), cos( radians ) };
|
||||
orig = Elite::Vector2{ 0, 0 };
|
||||
}
|
||||
void Matrix2x3::SetAsTranslate(float tx, float ty)
|
||||
{
|
||||
dirX = Elite::Vector2{ 1, 0 };
|
||||
dirY = Elite::Vector2{ 0, 1 };
|
||||
orig = Elite::Vector2{ tx, ty };
|
||||
}
|
||||
|
||||
void Matrix2x3::SetAsTranslate(Elite::Vector2 pt)
|
||||
{
|
||||
dirX = Elite::Vector2{ 1, 0 };
|
||||
dirY = Elite::Vector2{ 0, 1 };
|
||||
orig = Elite::Vector2{ pt.x, pt.y };
|
||||
}
|
||||
|
||||
void Matrix2x3::SetAsScale(float scaleX, float scaleY)
|
||||
{
|
||||
dirX = Elite::Vector2{ scaleX, 0 };
|
||||
dirY = Elite::Vector2{ 0, scaleY };
|
||||
orig = Elite::Vector2{ 0, 0 };
|
||||
}
|
||||
|
||||
void Matrix2x3::SetAsScale(float scale)
|
||||
{
|
||||
SetAsScale(scale, scale);
|
||||
}
|
||||
|
||||
Matrix2x3 Matrix2x3::CreateRotationMatrix(float degrees)
|
||||
{
|
||||
float radians = degrees * 3.1415926535f / 180;
|
||||
return Matrix2x3( Elite::Vector2{ cos( radians ), sin( radians ) }, Elite::Vector2{ -sin(radians), cos( radians ) }, Elite::Vector2{} );
|
||||
}
|
||||
|
||||
Matrix2x3 Matrix2x3::CreateIdentityMatrix()
|
||||
{
|
||||
return Matrix2x3( Elite::Vector2{ 1, 0 }, Elite::Vector2{ 0, 1 }, Elite::Vector2{} );
|
||||
}
|
||||
|
||||
Matrix2x3 Matrix2x3::CreateScalingMatrix(float scale)
|
||||
{
|
||||
return CreateScalingMatrix(scale, scale);
|
||||
}
|
||||
|
||||
Matrix2x3 Matrix2x3::CreateScalingMatrix(Elite::Vector2 scaleVector)
|
||||
{
|
||||
return CreateScalingMatrix(scaleVector.x, scaleVector.y);
|
||||
}
|
||||
|
||||
Matrix2x3 Matrix2x3::CreateScalingMatrix(float scaleX, float scaleY)
|
||||
{
|
||||
return Matrix2x3( Elite::Vector2{ scaleX, 0 }, Elite::Vector2{ 0, scaleY }, Elite::Vector2{} );
|
||||
}
|
||||
|
||||
Matrix2x3 Matrix2x3::CreateTranslationMatrix(Elite::Vector2 origin)
|
||||
{
|
||||
return Matrix2x3( Elite::Vector2{ 1, 0 }, Elite::Vector2{ 0, 1 }, origin );
|
||||
}
|
||||
|
||||
Matrix2x3 Matrix2x3::CreateTranslationMatrix(float tx, float ty)
|
||||
{
|
||||
return CreateTranslationMatrix( Elite::Vector2{ tx, ty } );
|
||||
}
|
||||
|
||||
// Operator overloading functionality
|
||||
bool operator==(const Matrix2x3& lhs, const Matrix2x3& rhs)
|
||||
{
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
|
||||
bool operator!=(const Matrix2x3& lhs, const Matrix2x3& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
Matrix2x3 operator*(const Matrix2x3& lhs, const Matrix2x3& rhs)
|
||||
{
|
||||
return Matrix2x3{
|
||||
Elite::Vector2{ rhs.dirX.x * lhs.dirX.x + rhs.dirX.y * lhs.dirY.x, rhs.dirX.x * lhs.dirX.y + rhs.dirX.y * lhs.dirY.y },
|
||||
Elite::Vector2{ rhs.dirY.x * lhs.dirX.x + rhs.dirY.y * lhs.dirY.x, rhs.dirY.x * lhs.dirX.y + rhs.dirY.y * lhs.dirY.y },
|
||||
Elite::Vector2{ rhs.orig.x * lhs.dirX.x + rhs.orig.y * lhs.dirY.x + lhs.orig.x, rhs.orig.x * lhs.dirX.y + rhs.orig.y * lhs.dirY.y + lhs.orig.y }
|
||||
};
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Matrix2x3& matrix )
|
||||
{
|
||||
os << matrix.ToString( );
|
||||
return os;
|
||||
}
|
||||
|
||||
93
inc/EliteMath/EMatrix2x3.h
Normal file
93
inc/EliteMath/EMatrix2x3.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
|
||||
struct Matrix2x3
|
||||
{
|
||||
// -------------------------
|
||||
// Constructors
|
||||
// -------------------------
|
||||
// Default constructor results in a unity matrix
|
||||
explicit Matrix2x3( Elite::Vector2 dirX = Elite::Vector2{ 1, 0 }, Elite::Vector2 dirY = Elite::Vector2{ 0, 1 }, Elite::Vector2 origTrans = Elite::Vector2{ 0, 0 } );
|
||||
// Constructor, using floats, all required
|
||||
explicit Matrix2x3( float e1X, float e1Y, float e2X, float e2Y, float oX, float oY );
|
||||
|
||||
// -------------------------
|
||||
// General Methods
|
||||
// -------------------------
|
||||
// Elite::Vector2 vTransformed = mat.Transform(v);
|
||||
Elite::Vector2 Transform( const Elite::Vector2& v ) const;
|
||||
|
||||
// Calculate the determinant
|
||||
float Determinant( ) const;
|
||||
|
||||
// Calculate the inverse matrix
|
||||
Matrix2x3 Inverse( ) const;
|
||||
|
||||
// Are two matrices equal within a threshold?
|
||||
// mat1.Equals(mat2)
|
||||
bool Equals( const Matrix2x3& other, float epsilon = 0.001f ) const;
|
||||
|
||||
// Creates a string containing a text representation of the values of the matrix
|
||||
std::string ToString( ) const;
|
||||
|
||||
// Converts this matrix into a Identity matrix
|
||||
void SetAsIdentity( );
|
||||
// Converts this matrix into a Rotate matrix
|
||||
void SetAsRotate( float degrees );
|
||||
// Converts this matrix into a Translation matrix
|
||||
void SetAsTranslate( float tx, float ty );
|
||||
// Converts this matrix into a Translation matrix
|
||||
void SetAsTranslate( Elite::Vector2 pt );
|
||||
// Converts this matrix into a Scale matrix
|
||||
void SetAsScale( float sx, float sy );
|
||||
// Converts this matrix into a Scale matrix
|
||||
void SetAsScale( float s );
|
||||
|
||||
// -------------------------------------------
|
||||
// Static Matrix2x3 object creation methods
|
||||
// -------------------------------------------
|
||||
// Instantiate a rotation matrix:
|
||||
// Matrix matRot = Matrix::Rotation(45.0f);
|
||||
static Matrix2x3 CreateRotationMatrix( float degrees );
|
||||
// Instantiate an identity matrix:
|
||||
// Matrix2x3 matId = Matrix2x3::Identity();
|
||||
static Matrix2x3 CreateIdentityMatrix( );
|
||||
// Instantiate a scale matrix:
|
||||
// Matrix matScale = Matrix::Scaling(2.0f);
|
||||
static Matrix2x3 CreateScalingMatrix( float scale );
|
||||
// Instantiate a scale matrix:
|
||||
// Matrix matScale = Matrix::Scaling(2.0f,-3.0f);
|
||||
static Matrix2x3 CreateScalingMatrix( float scaleX, float scaleY );
|
||||
// Instantiate a scale matrix:
|
||||
// Matrix matScale = Matrix::Scaling( Elite::Vector2(2.0f,-3.0f) );
|
||||
static Matrix2x3 CreateScalingMatrix( Elite::Vector2 scaleVector );
|
||||
// Instantiate a translation matrix:
|
||||
// Matrix matTrans = Matrix::Translation( Elite::Vector2(2.0f,3.0f) );
|
||||
static Matrix2x3 CreateTranslationMatrix( Elite::Vector2 origin );
|
||||
// Instantiate a translation matrix:
|
||||
// Matrix matTrans = Matrix::Translation(2.0f, 3.0f);
|
||||
static Matrix2x3 CreateTranslationMatrix( float tx, float ty );
|
||||
|
||||
// -------------------------
|
||||
// Datamembers
|
||||
// -------------------------
|
||||
Elite::Vector2 dirX; // The first matrix vector (the "x-axis"), 1st column
|
||||
Elite::Vector2 dirY; // The second matrix vector (the "y-axis"), second column
|
||||
Elite::Vector2 orig; // The origin of the coordinate matrix (the "translation"), third column
|
||||
};
|
||||
|
||||
// -------------------------
|
||||
// Operators
|
||||
// -------------------------
|
||||
// Are two matrices exactly equal?
|
||||
// mat1 == mat2
|
||||
bool operator==( const Matrix2x3& lhs, const Matrix2x3& rhs );
|
||||
// Are two matrices exactly unequal?
|
||||
// mat1 != mat2
|
||||
bool operator!=( const Matrix2x3& lhs, const Matrix2x3& rhs );
|
||||
// Multiply matrices
|
||||
// Matrix2x3 matProduct {mat1 * mat2};
|
||||
Matrix2x3 operator*( const Matrix2x3& lhs, const Matrix2x3& rhs );
|
||||
// Send matrix to output stream
|
||||
// std::cout << mat;
|
||||
std::ostream& operator<<( std::ostream& os, const Matrix2x3& matrix );
|
||||
237
inc/EliteMath/EVector2.h
Normal file
237
inc/EliteMath/EVector2.h
Normal file
@@ -0,0 +1,237 @@
|
||||
/*=============================================================================*/
|
||||
// Copyright 2021-2022 Elite Engine
|
||||
// Authors: Matthieu Delaere
|
||||
/*=============================================================================*/
|
||||
// EVector2.h: Vector2D struct
|
||||
/*=============================================================================*/
|
||||
#ifndef ELITE_MATH_VECTOR2
|
||||
#define ELITE_MATH_VECTOR2
|
||||
namespace Elite
|
||||
{
|
||||
#define ZeroVector2 Vector2()
|
||||
#define UnitVector2 Vector2(1.f,1.f)
|
||||
|
||||
//Vector 2D
|
||||
struct Vector2
|
||||
{
|
||||
//=== Datamembers ===
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
|
||||
//=== Constructors ===
|
||||
Vector2() = default;
|
||||
Vector2(float _x, float _y) :x(_x), y(_y) {};
|
||||
|
||||
//=== Vector Conversions Functions ===
|
||||
#ifdef USE_BOX2D
|
||||
explicit Vector2(const b2Vec2& v) : x(v.x), y(v.y) {};
|
||||
Vector2& operator=(const b2Vec2& v) { x = v.x; y = v.y; return *this; }
|
||||
operator b2Vec2() const
|
||||
{return {x, y};};
|
||||
#endif
|
||||
|
||||
//=== Arithmetic Operators ===
|
||||
inline auto operator-(const Vector2& v) const
|
||||
{ return Vector2(x - v.x, y - v.y); }
|
||||
inline auto operator-() const
|
||||
{ return Vector2(-x, -y); }
|
||||
inline auto operator*(float scale) const
|
||||
{ return Vector2(x * scale, y * scale); }
|
||||
inline auto operator/(float scale) const
|
||||
{
|
||||
const auto revScale = 1.0f / scale;
|
||||
return Vector2(x * revScale, y * revScale);
|
||||
}
|
||||
|
||||
//=== Compound Assignment Operators === //auto& for type deduction
|
||||
inline auto& operator+=(const Vector2& v)
|
||||
{ x += v.x; y += v.y; return *this; }
|
||||
inline auto& operator-=(const Vector2& v)
|
||||
{ x -= v.x; y -= v.y; return *this; }
|
||||
inline auto& operator*=(float scale)
|
||||
{ x *= scale; y *= scale; return *this; }
|
||||
inline auto& operator/=(float scale)
|
||||
{
|
||||
const auto revScale = 1.0f / scale;
|
||||
x *= revScale; y *= revScale; return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=== Relational Operators ===
|
||||
inline auto operator==(const Vector2& v) const /*Check if both components are equal*/
|
||||
{ return AreEqual(x, v.x) && AreEqual(y, v.y); }
|
||||
inline auto operator!=(const Vector2& v) const /*Check if one or both components are NOT equal*/
|
||||
{ return !(*this == v); }
|
||||
|
||||
//=== Member Access Operators ===
|
||||
inline float operator[](unsigned int i) const
|
||||
{
|
||||
return ((i == 0) ? x : y);
|
||||
//if (i >= 0 && i < 2)
|
||||
// return ((i == 0) ? x : y);
|
||||
//throw; /*TODO : specify error thrown;*/
|
||||
}
|
||||
inline float& operator[](unsigned int i)
|
||||
{
|
||||
return ((i == 0) ? x : y);
|
||||
//if (i >= 0 && i < 2)
|
||||
// return ((i == 0) ? x : y);
|
||||
//throw; /*TODO : specify error thrown;*/
|
||||
}
|
||||
|
||||
//=== Internal Vector Functions ===
|
||||
inline auto Dot(const Vector2& v) const
|
||||
{ return x * v.x + y * v.y; }
|
||||
|
||||
inline auto Cross(const Vector2& v) const
|
||||
{ return x * v.y - y * v.x; }
|
||||
|
||||
inline auto GetAbs() const
|
||||
{ return Vector2(abs(x), abs(y)); }
|
||||
|
||||
inline auto MagnitudeSquared() const
|
||||
{ return x*x + y*y; }
|
||||
|
||||
inline auto Magnitude() const
|
||||
{ return sqrtf(MagnitudeSquared()); }
|
||||
|
||||
inline float Normalize()
|
||||
{
|
||||
auto m = Magnitude();
|
||||
if (AreEqual(m, 0.f))
|
||||
{
|
||||
*this = ZeroVector2;
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
auto invM = 1.f / m;
|
||||
x *= invM;
|
||||
y *= invM;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
inline Vector2 GetNormalized() const /*! Returns a normalized copy of this vector. This vector does not change.*/
|
||||
{
|
||||
auto v = Vector2(*this);
|
||||
v.Normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
inline auto DistanceSquared(const Vector2& v) const
|
||||
{ return Square(v.x - x) + Square(v.y - y); }
|
||||
|
||||
inline auto Distance(const Vector2& v) const
|
||||
{ return sqrtf(DistanceSquared(v)); }
|
||||
|
||||
inline auto Clamp(float max)
|
||||
{
|
||||
auto scale = max / Magnitude();
|
||||
scale = scale < 1.f ? scale : 1.f;
|
||||
return *this * scale;
|
||||
}
|
||||
};
|
||||
|
||||
//=== Global Vector Operators ===
|
||||
#pragma region GlobalVectorOperators
|
||||
inline auto operator+(const Vector2& v, const Vector2& v2)
|
||||
{ return Vector2(v.x + v2.x, v.y + v2.y); }
|
||||
|
||||
inline auto operator* (float s, const Vector2& v)
|
||||
{ return Vector2(s * v.x, s * v.y); }
|
||||
|
||||
inline auto operator*(const Vector2& a, const Vector2& b)
|
||||
{ return Vector2(a.x*b.x, a.y*b.y); }
|
||||
|
||||
inline auto operator/ (float s, const Vector2& v)
|
||||
{
|
||||
const auto revScale = 1.0f / s;
|
||||
return Vector2(revScale * v.x, revScale * v.y);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Vector2& rhs)
|
||||
{
|
||||
os << "(" << rhs.x << ", " << rhs.y << " )";
|
||||
return os;
|
||||
}
|
||||
#pragma endregion //GlobalVectorOperators
|
||||
|
||||
//=== Global Vector Functions ===
|
||||
#pragma region GlobalVectorFunctions
|
||||
inline auto Dot(const Vector2& v1, const Vector2& v2)
|
||||
{ return v1.Dot(v2); }
|
||||
|
||||
inline auto Cross(const Vector2& v1, const Vector2& v2)
|
||||
{ return v1.Cross(v2); }
|
||||
|
||||
inline auto GetAbs(const Vector2& v)
|
||||
{ return v.GetAbs(); }
|
||||
|
||||
inline void Abs(Vector2& v) /*! Make absolute Vector2 of this Vector2 */
|
||||
{ v = v.GetAbs(); }
|
||||
|
||||
inline void Normalize(Vector2& v)
|
||||
{ v.Normalize(); }
|
||||
|
||||
inline auto GetNormalized(const Vector2& v)
|
||||
{ return v.GetNormalized(); }
|
||||
|
||||
inline auto DistanceSquared(const Vector2& v1, const Vector2& v2)
|
||||
{ return v1.DistanceSquared(v2); }
|
||||
|
||||
inline auto Distance(const Vector2& v1, const Vector2& v2)
|
||||
{ return v1.Distance(v2); }
|
||||
|
||||
inline auto Clamp(const Vector2& v, float max)
|
||||
{
|
||||
auto scale = max / v.Magnitude();
|
||||
scale = scale < 1.f ? scale : 1.f;
|
||||
return v * scale;
|
||||
}
|
||||
#pragma endregion //GlobalVectorFunctions
|
||||
|
||||
#pragma region ExtraFunctions
|
||||
/*! Random Vector2 */
|
||||
inline Vector2 randomVector2(float max = 1.f)
|
||||
{
|
||||
return{ randomBinomial(max),randomBinomial(max) };
|
||||
}
|
||||
inline Vector2 randomVector2(float min, float max)
|
||||
{
|
||||
return{ randomFloat(min, max),randomFloat(min, max) };
|
||||
}
|
||||
|
||||
/* Get orientation from an a velocity vector
|
||||
-- [Deprecated] -- Use VectorToAngle instead*/
|
||||
[[deprecated("Use VectorToOrientation instead")]]
|
||||
inline float GetOrientationFromVelocity(const Elite::Vector2& velocity)
|
||||
{
|
||||
if (velocity.Magnitude() == 0)
|
||||
return 0.f;
|
||||
|
||||
return atan2f(velocity.x, -velocity.y);
|
||||
}
|
||||
|
||||
/* Creates a normalized vector from an angle in radians. */
|
||||
inline Vector2 OrientationToVector(float orientation)
|
||||
{
|
||||
return Vector2(cos(orientation), sin(orientation));
|
||||
}
|
||||
|
||||
/*Calculates the orientation angle from a vector*/
|
||||
inline float VectorToOrientation(const Vector2& vector)
|
||||
{
|
||||
return atan2f(vector.y, vector.x);
|
||||
}
|
||||
|
||||
/*! Get Angle Between 2 vectors*/
|
||||
inline float AngleBetween(const Elite::Vector2& v1, const Elite::Vector2& v2) {
|
||||
float x = v1.Dot(v2);
|
||||
float y = v1.Cross(v2);
|
||||
return atan2(y, x);
|
||||
}
|
||||
|
||||
#pragma endregion //ExtraFunctions
|
||||
}
|
||||
#endif
|
||||
170
inc/EliteMath/EVector3.h
Normal file
170
inc/EliteMath/EVector3.h
Normal file
@@ -0,0 +1,170 @@
|
||||
/*=============================================================================*/
|
||||
// Copyright 2021-2022 Elite Engine
|
||||
// Authors: Matthieu Delaere
|
||||
/*=============================================================================*/
|
||||
// EVector2.h: Vector3D struct
|
||||
/*=============================================================================*/
|
||||
#ifndef ELITE_MATH_VECTOR3
|
||||
#define ELITE_MATH_VECTOR3
|
||||
namespace Elite {
|
||||
|
||||
#define ZeroVector3 Vector3()
|
||||
#define UnitVector3 Vector3(1.f,1.f,1.f)
|
||||
|
||||
//Vector 3D
|
||||
struct Vector3
|
||||
{
|
||||
//=== Datamembers ===
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
|
||||
//=== Constructors ===
|
||||
Vector3(){};
|
||||
Vector3(float _x, float _y, float _z):x(_x), y(_y), z(_z) {};
|
||||
explicit Vector3(const Vector2 v, float _z = 0.f):x(v.x), y(v.y), z(_z) {};
|
||||
//Vector3(const Vector3& other); //Copy Constructor
|
||||
//Vector3& operator=(const Vector3& other); //Copy Assignment Operator
|
||||
|
||||
//=== Vector Conversions Functions ===
|
||||
#ifdef USE_BOX2D
|
||||
explicit Vector3(const b2Vec3& v) : x(v.x), y(v.y), z(v.z) {};
|
||||
Vector3& operator=(const b2Vec3& v) { x = v.x; y = v.y; z = v.z; return *this; }
|
||||
explicit operator b2Vec3() const
|
||||
{ return b2Vec3(x, y, z); };
|
||||
#endif
|
||||
|
||||
//=== Arithmetic Operators ===
|
||||
inline auto operator+(const Vector3& v) const
|
||||
{ return Vector3(x + v.x, y + v.y, z + v.z); }
|
||||
inline auto operator-(const Vector3& v) const
|
||||
{ return Vector3(x - v.x, y - v.y, z - v.z); }
|
||||
inline auto operator*(float scale) const
|
||||
{ return Vector3(x * scale, y * scale, z * scale); }
|
||||
inline auto operator/(float scale) const
|
||||
{
|
||||
const auto revScale = 1.0f / scale;
|
||||
return Vector3(x * revScale, y * revScale, z * revScale);
|
||||
}
|
||||
|
||||
//=== Compound Assignment Operators === //auto& for type deduction
|
||||
inline auto& operator+=(const Vector3& v)
|
||||
{ x += v.x; y += v.y; z += v.z; return *this; }
|
||||
inline auto& operator-=(const Vector3& v)
|
||||
{ x -= v.x; y -= v.y; z -= v.z; return *this; }
|
||||
inline auto& operator*=(float scale)
|
||||
{ x *= scale; y *= scale; z *= scale; return *this; }
|
||||
inline auto& operator/=(float scale)
|
||||
{
|
||||
const auto revScale = 1.0f / scale;
|
||||
x *= revScale; y *= revScale; z *= revScale; return *this;
|
||||
}
|
||||
|
||||
//=== Relational Operators ===
|
||||
inline auto operator==(const Vector3& v) const /*Check if both components are equal*/
|
||||
{ return AreEqual(x, v.x) && AreEqual(y, v.y) && AreEqual(z, v.z); }
|
||||
inline auto operator!=(const Vector3& v) const /*Check if one or both components are NOT equal*/
|
||||
{ return !(*this == v); }
|
||||
|
||||
//=== Member Access Operators ===
|
||||
inline float operator[](unsigned int i) const
|
||||
{ return ((i == 0) ? x : y); }
|
||||
inline float& operator[](unsigned int i)
|
||||
{ return ((i == 0) ? x : y); }
|
||||
|
||||
//=== Internal Vector Functions ===
|
||||
inline auto Dot(const Vector3& v) const
|
||||
{ return x * v.x + y * v.y + z * v.z; }
|
||||
|
||||
inline auto Cross(const Vector3& v) const
|
||||
{
|
||||
return Vector3(
|
||||
y * v.z - z * v.y,
|
||||
z * v.x - x * v.z,
|
||||
x * v.y - y * v.x);
|
||||
}
|
||||
|
||||
inline auto GetAbs() const
|
||||
{ return Vector3(abs(x), abs(y), abs(z)); }
|
||||
|
||||
inline auto SqrtMagnitude() const
|
||||
{ return x*x + y*y + z*z; }
|
||||
|
||||
inline auto Magnitude() const
|
||||
{ return sqrtf(SqrtMagnitude()); }
|
||||
|
||||
inline void Normalize()
|
||||
{
|
||||
auto m = Magnitude();
|
||||
if (AreEqual(m, 0.f))
|
||||
{
|
||||
*this = ZeroVector3;
|
||||
return;
|
||||
}
|
||||
|
||||
auto invM = 1.f / m;
|
||||
x *= invM;
|
||||
y *= invM;
|
||||
z *= invM;
|
||||
}
|
||||
|
||||
inline Vector3 GetNormalized() const /*! Returns a normalized copy of this vector. This vector does not change.*/
|
||||
{
|
||||
auto v = Vector3(*this);
|
||||
v.Normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
inline auto DistanceSquared(const Vector3& v) const
|
||||
{ return Square(v.x - x) + Square(v.y - y) + Square(v.z - z); }
|
||||
|
||||
inline auto Distance(const Vector3& v) const
|
||||
{ return sqrtf(DistanceSquared(v)); }
|
||||
|
||||
inline auto Project(const Vector3& v) const
|
||||
{ return v * ((*this).Dot(v) / v.Dot(v)); }
|
||||
|
||||
inline auto Reject(const Vector3& v) const
|
||||
{ return *this - (*this).Project(v);}
|
||||
};
|
||||
|
||||
//=== Global Vector Operators ===
|
||||
#pragma region GlobalVectorOperators
|
||||
inline auto operator * (float s, const Vector3& v)
|
||||
{ return Vector3(s * v.x, s * v.y, s * v.z); }
|
||||
#pragma endregion //GlobalVectorOperators
|
||||
|
||||
//=== Global Vector Functions ===
|
||||
#pragma region GlobalVectorFunctions
|
||||
inline auto Dot(const Vector3& v1, const Vector3& v2)
|
||||
{ return v1.Dot(v2); }
|
||||
|
||||
inline auto Cross(const Vector3& v1, const Vector3& v2)
|
||||
{ return v1.Cross(v2); }
|
||||
|
||||
inline auto GetAbs(const Vector3& v)
|
||||
{ return v.GetAbs(); }
|
||||
|
||||
inline void Abs(Vector3& v) /*! Make absolute Vector3 of this Vector3 */
|
||||
{ v = v.GetAbs(); }
|
||||
|
||||
inline void Normalize(Vector3& v)
|
||||
{ v.Normalize(); }
|
||||
|
||||
inline auto GetNormalized(Vector3& v)
|
||||
{ return v.GetNormalized(); }
|
||||
|
||||
inline auto DistanceSquared(const Vector3& v1, const Vector3& v2)
|
||||
{ return v1.DistanceSquared(v2); }
|
||||
|
||||
inline auto Distance(const Vector3& v1, const Vector3& v2)
|
||||
{ return v1.Distance(v2); }
|
||||
|
||||
inline auto Project(const Vector3& v1, const Vector3& v2)
|
||||
{ return v1.Project(v2); }
|
||||
|
||||
inline auto Reject(const Vector3& v1, const Vector3& v2)
|
||||
{ return v1.Reject(v2); }
|
||||
#pragma endregion //GlobalVectorFunctions
|
||||
}
|
||||
#endif
|
||||
267
inc/EliteMath/FMatrix.h
Normal file
267
inc/EliteMath/FMatrix.h
Normal file
@@ -0,0 +1,267 @@
|
||||
/*=============================================================================*/
|
||||
// Copyright 2021-2022 Elite Engine
|
||||
// Authors: Koen Samyn
|
||||
/*=============================================================================*/
|
||||
// FMatrix.cpp: FMatrix class
|
||||
/*=============================================================================*/
|
||||
#ifndef ELITE_MATH_FMATRIX
|
||||
#define ELITE_MATH_FMATRIX
|
||||
|
||||
#include <random>
|
||||
namespace Elite
|
||||
{
|
||||
class FMatrix
|
||||
{
|
||||
public:
|
||||
FMatrix(): m_Data(nullptr), m_Rows(0), m_Columns(0), m_Size(0) {}
|
||||
FMatrix(int rows, int columns):
|
||||
m_Rows(rows),
|
||||
m_Columns(columns),
|
||||
m_Data(new float[rows * columns]),
|
||||
m_Size(rows * columns)
|
||||
{}
|
||||
|
||||
virtual ~FMatrix()
|
||||
{
|
||||
delete[] m_Data;
|
||||
m_Data = nullptr;
|
||||
}
|
||||
|
||||
void Resize(int nrOfRows, int nrOfColumns)
|
||||
{
|
||||
m_Rows = nrOfRows;
|
||||
m_Columns = nrOfColumns;
|
||||
m_Size = m_Rows * m_Columns;
|
||||
delete[] m_Data; //ATTENTION: DELETES OLD DATA IN MATRIX
|
||||
m_Data = new float[m_Size];
|
||||
}
|
||||
|
||||
void Set(int row, int column, float value)
|
||||
{
|
||||
int index = RcToIndex(row, column);
|
||||
if (index > -1 && index < m_Size)
|
||||
{
|
||||
m_Data[index] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Wrong index! [%d, %d]\n", row, column);
|
||||
}
|
||||
}
|
||||
void SetAll(float value)
|
||||
{
|
||||
for (int i = 0; i < m_Size; ++i)
|
||||
{
|
||||
m_Data[i] = value;
|
||||
}
|
||||
}
|
||||
void SetRowAll(int row, float value)
|
||||
{
|
||||
for (int c = 0; c < m_Columns; ++c)
|
||||
{
|
||||
Set(row, c, value);
|
||||
}
|
||||
}
|
||||
void Randomize(float min, float max)
|
||||
{
|
||||
for (int i = 0; i < m_Size; ++i)
|
||||
{
|
||||
float r = min + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (max - min)));
|
||||
m_Data[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
void Add(int row, int column, float toAdd)
|
||||
{
|
||||
int index = RcToIndex(row, column);
|
||||
if (index > -1 && index < m_Size) {
|
||||
m_Data[index] += toAdd;
|
||||
}
|
||||
else {
|
||||
printf("Wrong index! [%d, %d]\n", row, column);
|
||||
}
|
||||
}
|
||||
void Add(const FMatrix& other)
|
||||
{
|
||||
int maxRows = min(GetNrOfRows(), other.GetNrOfRows());
|
||||
int maxColumns = min(GetNrOfColumns(), other.GetNrOfColumns());
|
||||
|
||||
for (int c_row = 0; c_row < maxRows; ++c_row) {
|
||||
for (int c_column = 0; c_column < maxColumns; ++c_column) {
|
||||
float oVal = other.Get(c_row, c_column);
|
||||
float thisVal = Get(c_row, c_column);
|
||||
Set(c_row, c_column, thisVal + oVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float Get(int row, int column) const
|
||||
{
|
||||
int index = RcToIndex(row, column);
|
||||
if (index > -1 && index < m_Size) {
|
||||
return m_Data[index];
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
int GetNrOfRows() const
|
||||
{
|
||||
return m_Rows;
|
||||
}
|
||||
int GetNrOfColumns() const
|
||||
{
|
||||
return m_Columns;
|
||||
}
|
||||
void MatrixMultiply(const FMatrix& op2, FMatrix& result)
|
||||
{
|
||||
int maxRows = min(GetNrOfRows(), result.GetNrOfRows());
|
||||
int maxColumns = min(op2.GetNrOfColumns(), result.GetNrOfColumns());
|
||||
|
||||
for (int c_row = 0; c_row < maxRows; ++c_row)
|
||||
{
|
||||
for (int c_column = 0; c_column < maxColumns; ++c_column)
|
||||
{
|
||||
float sum = 0;
|
||||
for (int index = 0; index < GetNrOfColumns(); ++index)
|
||||
{
|
||||
sum += Get(c_row, index) * op2.Get(index, c_column);
|
||||
}
|
||||
result.Set(c_row, c_column, sum);
|
||||
}
|
||||
}
|
||||
}
|
||||
void ScalarMultiply(float scalar)
|
||||
{
|
||||
for (int i = 0; i < m_Size; ++i)
|
||||
{
|
||||
m_Data[i] *= scalar;
|
||||
}
|
||||
}
|
||||
|
||||
void Copy(const FMatrix& other)
|
||||
{
|
||||
int maxRows = min(GetNrOfRows(), other.GetNrOfRows());
|
||||
int maxColumns = min(GetNrOfColumns(), other.GetNrOfColumns());
|
||||
|
||||
for (int c_row = 0; c_row < maxRows; ++c_row) {
|
||||
for (int c_column = 0; c_column < maxColumns; ++c_column) {
|
||||
float oVal = other.Get(c_row, c_column);
|
||||
Set(c_row, c_column, oVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Subtract(const FMatrix& other)
|
||||
{
|
||||
int maxRows = min(GetNrOfRows(), other.GetNrOfRows());
|
||||
int maxColumns = min(GetNrOfColumns(), other.GetNrOfColumns());
|
||||
|
||||
for (int c_row = 0; c_row < maxRows; ++c_row)
|
||||
{
|
||||
for (int c_column = 0; c_column < maxColumns; ++c_column)
|
||||
{
|
||||
float oVal = other.Get(c_row, c_column);
|
||||
float thisVal = Get(c_row, c_column);
|
||||
Set(c_row, c_column, thisVal - oVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
void Sigmoid()
|
||||
{
|
||||
for (int i = 0; i < m_Size; ++i)
|
||||
{
|
||||
float val = m_Data[i];
|
||||
m_Data[i] = 1 / (1 + exp(-val));
|
||||
}
|
||||
}
|
||||
|
||||
float Sum() const
|
||||
{
|
||||
float sum = 0;
|
||||
for (int i = 0; i < m_Size; ++i)
|
||||
{
|
||||
sum += m_Data[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
float Dot(const FMatrix& op2) const
|
||||
{
|
||||
int mR = min(GetNrOfRows(), op2.GetNrOfRows());
|
||||
int mC = min(GetNrOfColumns(), op2.GetNrOfColumns());
|
||||
|
||||
float dot = 0;
|
||||
for (int c_row = 0; c_row < mR; ++c_row) {
|
||||
for (int c_column = 0; c_column < mC; ++c_column) {
|
||||
float v1 = Get(c_row, c_column);
|
||||
float v2 = Get(c_row, c_column);
|
||||
dot += v1 * v2;
|
||||
}
|
||||
}
|
||||
return dot;
|
||||
}
|
||||
float Max() const
|
||||
{
|
||||
float max = -FLT_MAX;
|
||||
for (int c_row = 0; c_row < m_Rows; ++c_row) {
|
||||
for (int c_column = 0; c_column < m_Columns; ++c_column) {
|
||||
float value = Get(c_row, c_column);
|
||||
if (value > max) {
|
||||
max = value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
float Max(int r, int c) const
|
||||
{
|
||||
float max = -FLT_MAX;
|
||||
for (int c_row = 0; c_row < m_Rows; ++c_row) {
|
||||
for (int c_column = 0; c_column < m_Columns; ++c_column) {
|
||||
float value = Get(c_row, c_column);
|
||||
if (value > max) {
|
||||
max = value;
|
||||
r = c_row;
|
||||
c = c_column;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
float MaxOfRow(int r) const
|
||||
{
|
||||
float max = -FLT_MAX;
|
||||
for (int c_column = 0; c_column < m_Columns; ++c_column) {
|
||||
float value = Get(r, c_column);
|
||||
if (value > max) {
|
||||
max = value;
|
||||
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
void Print() const
|
||||
{
|
||||
for (int c_row = 0; c_row < m_Rows; ++c_row) {
|
||||
for (int c_column = 0; c_column < m_Columns; ++c_column) {
|
||||
float value = Get(c_row, c_column);
|
||||
printf("%.3f\t", value);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
private:
|
||||
float* m_Data;
|
||||
int m_Rows, m_Columns;
|
||||
int m_Size;
|
||||
int RcToIndex(int r, int c) const
|
||||
{
|
||||
return c * m_Rows + r;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user