Implement Matrix3x3::Equals() RandomRotation() RandomGeneral() Unary + Operator

This commit is contained in:
2024-05-31 15:17:49 -04:00
parent f82aeb1168
commit a4f10b0b7e

View File

@@ -5,6 +5,9 @@
#include <J3ML/LinearAlgebra/Vector2.h>
#include <J3ML/LinearAlgebra/Vector3.h>
#include <J3ML/LinearAlgebra/Quaternion.h>
#include <J3ML/Algorithm/RNG.h>
using namespace J3ML::Algorithm;
#include <cstring>
@@ -126,6 +129,19 @@ namespace J3ML::LinearAlgebra {
view->world. In GLM, the LookAt function is tied to cameras only, and it returns the inverse mapping world->view.
*/
static Matrix3x3 LookAt(const Vector3& forward, const Vector3& target, const Vector3& localUp, const Vector3& worldUp);
// Returns a uniformly random 3x3 matrix that performs only rotation.
/** This matrix produces a random orthonormal bassi for an orientation of an object. There is no mirroring
or scaling present in the generated matrix. Also, naturally since Matrix3x3 cannot represent translation or projection,
these properties are not present either. */
static Matrix3x3 RandomRotation(RNG& rng);
/// Returns a random 3x3 matrix with each entry randomized between the range [minElem, maxElem]
/** Warning: The matrices returned by this function do not represent well-formed 3D transformations.
This function is mostly used for testing and debugging purposes only. */
static Matrix3x3 RandomGeneral(RNG& rng, float minElem, float maxElem);
/// Creates a new Matrix3x3 that performs the rotation expressed by the given quaternion.
static Matrix3x3 FromQuat(const Quaternion& orientation);
/// Creates a new Matrix3x3 as a combination of rotation and scale.
@@ -306,7 +322,7 @@ namespace J3ML::LinearAlgebra {
/** If a matrix is of form M=R*S, where
R is a rotation matrix and S is a diagonal matrix with non-zero but potentially non-uniform scaling
factors (possibly mirroring), then the matrix M is column-orthogonal and this function can be used to compute the inverse.
Calling this function is faster than calling the generic matrix Inverse() function.\
Calling this function is faster than calling the generic matrix Inverted() function.\
Returns true on success. On failure, the matrix is not modified. This function fails if any of the
elements of this vector are not finite, or if the matrix contains a zero scaling factor on X, Y, or Z.
@note The returned matrix will be row-orthogonal, but not column-orthogonal in general.
@@ -318,19 +334,19 @@ namespace J3ML::LinearAlgebra {
/** If a matrix is of form M=R*S, where R is a rotation matrix and S is either identity or a mirroring matrix, then
the matrix M is orthonormal and this function can be used to compute the inverse.
This function is faster than calling InverseOrthogonalUniformScale(), InverseColOrthogonal(), or the generic
Inverse().
Inverted().
This function may not be called if this matrix contains any scaling or shearing, but it may contain mirroring.*/
bool InverseOrthogonalUniformScale();
/// Inverts a rotation matrix.
/// If a matrix is of form M = R*S, where R is a rotation matrix and S is either identity or a mirroring matrix, then
/// the matrix M is orthonormal and this function can be used to compute the inverse.
/// This function is faster than calling InverseOrthogonalUniformScale(), InverseColOrthogonal(), or the generic Inverse()
/// This function is faster than calling InverseOrthogonalUniformScale(), InverseColOrthogonal(), or the generic Inverted()
/// This function may not be called if this matrix contains any scaling or shearing, but it may contain mirroring.
void InverseOrthonormal();
/// Inverts a symmetric matrix.
/** This function is faster than directly calling Inverse()
/** This function is faster than directly calling Inverted()
This function computes 6 LOADs, 9 STOREs, 21 MULs, 1 DIV, 1 CMP, and 8 ADDs.
@return True if computing the inverse succeeded, false otherwise (determinant was zero).
@note If this function fails, the original matrix is not modified.
@@ -385,11 +401,10 @@ namespace J3ML::LinearAlgebra {
/// This function ignores the W component of the given input vector. This component is assumed to be either 0 or 1.
Vector4 operator * (const Vector4& rhs) const;
/// Unary operator + allows this structure to be used in an expression '+x'.
Matrix3x3 operator + () const { return *this;}
Matrix3x3 operator * (const Quaternion& rhs) const
{
return *this * Matrix3x3(rhs);
}
/// Multiplies the two matrices.
Matrix3x3 operator * (const Matrix3x3& rhs) const;
[[nodiscard]] Matrix3x3 Mul(const Matrix3x3& rhs) const;
@@ -454,6 +469,8 @@ namespace J3ML::LinearAlgebra {
This occurs if this matrix has a negative determinant.*/
[[nodiscard]] bool HasNegativeScale() const;
/// Returns true if the column and row vectors of this matrix form an orthonormal set.
/// @note In math terms, there does not exist such a thing as an 'orthonormal matrix'. In math terms, a matrix
/// is orthogonal if the column and row vectors are orthogonal *unit* vectors.
@@ -461,6 +478,9 @@ namespace J3ML::LinearAlgebra {
/// and a matrix is orthonormal if the column and row vectors are orthonormal.
[[nodiscard]] bool IsOrthonormal(float epsilon = 1e-3f) const;
/// Returns true if this Matrix3x3 is equal to the given Matrix3x3, up to given per-element epsilon.
bool Equals(const Matrix3x3& other, float epsilon = 1e-3f) const;
protected: /// Member values
float elems[3][3]{};