476 lines
27 KiB
C++
476 lines
27 KiB
C++
#pragma once
|
|
|
|
|
|
|
|
#include <J3ML/LinearAlgebra/Vector2.hpp>
|
|
#include <J3ML/LinearAlgebra/Vector3.hpp>
|
|
#include <J3ML/LinearAlgebra/Quaternion.hpp>
|
|
#include <J3ML/Algorithm/RNG.hpp>
|
|
|
|
using namespace J3ML::Algorithm;
|
|
|
|
#include <cstring>
|
|
|
|
namespace J3ML::LinearAlgebra {
|
|
|
|
|
|
|
|
/// A 3-by-3 matrix for linear transformations of 3D geometry.
|
|
/* This can represent any kind of linear transformations of 3D geometry, which include
|
|
* rotation, scale, shear, mirroring, and orthographic projection.
|
|
* A 3x3 matrix cannot represent translation, which requires a 3x4, or perspective projection (4x4).
|
|
* The elements of this matrix are
|
|
* m_00, m_01, m_02
|
|
* m_10, m_11, m_12
|
|
* m_20, m_21, m_22
|
|
*
|
|
* The element m_yx is the value on the row y and column x.
|
|
* You can access m_yx using the double-bracket notation m[y][x], or using the member function At.
|
|
*
|
|
* @note The member functions in this class use the convention that transforms are applied to
|
|
* vectors in the form M * v. This means that "Matrix3x3 M, M1, M2; M = M1 * M2;" gives a transformation M
|
|
* that applies M2 first, followed by M1 second. */
|
|
class Matrix3x3 {
|
|
public: /// Constant Values
|
|
enum { Rows = 3 };
|
|
enum { Cols = 3 };
|
|
public: /// Constant Members
|
|
static const Matrix3x3 Zero;
|
|
static const Matrix3x3 Identity;
|
|
static const Matrix3x3 NaN;
|
|
public: /// Constructors
|
|
/// Creates a new Matrix3x3 with uninitalized member values.
|
|
Matrix3x3() = default;
|
|
|
|
Matrix3x3(const Matrix3x3& rhs) { Set(rhs); }
|
|
/// Creates a new Matrix3x3 by setting all matrix elements equal to val.
|
|
explicit Matrix3x3(float val);
|
|
/// Creates a new Matrix3x3 by explicitly specifying all the matrix elements.
|
|
/// The elements are specified in row-major format, i.e. the first row first followed by the second and third row.
|
|
/// E.g. The element m10 denotes the scalar at second (idx 1) row, first (idx 0) column.
|
|
Matrix3x3(float m00, float m01, float m02,
|
|
float m10, float m11, float m12,
|
|
float m20, float m21, float m22);
|
|
/// Constructs the matrix by explicitly specifying the three column vectors.
|
|
/** @param col0 The first column. If this matrix represents a change-of-basis transformation, this parameter is the world-space
|
|
direction of the local X axis.
|
|
@param col1 The second column. If this matrix represents a change-of-basis transformation, this parameter is the world-space
|
|
direction of the local Y axis.
|
|
@param col2 The third column. If this matrix represents a change-of-basis transformation, this parameter is the world-space
|
|
direction of the local Z axis. */
|
|
Matrix3x3(const Vector3& col0, const Vector3& col1, const Vector3& col2);
|
|
/// Constructs this matrix3x3 from the given quaternion.
|
|
explicit Matrix3x3(const Quaternion& orientation);
|
|
|
|
//explicit Matrix3x3(const AxisAngle& orientation);
|
|
explicit Matrix3x3(const AxisAngle& orientation) : Matrix3x3(Quaternion(orientation)) {};
|
|
|
|
/// Constructs this Matrix3x3 from a pointer to an array of floats.
|
|
explicit Matrix3x3(const float *data);
|
|
/// Creates a new Matrix3x3 that rotates about one of the principal axes by the given angle.
|
|
/// Calling RotateX, RotateY, or RotateZ is slightly faster than calling the more generic RotateAxisAngle function.
|
|
static Matrix3x3 RotateX(float radians);
|
|
/// [similarOverload: RotateX] [hideIndex]
|
|
static Matrix3x3 RotateY(float radians);
|
|
/// [similarOverload: RotateX] [hideIndex]
|
|
static Matrix3x3 RotateZ(float radians);
|
|
/// Creates a new M3x3 that rotates about the given axis by the given angle
|
|
static Matrix3x3 RotateAxisAngle(const Vector3& axis, float angleRadians);
|
|
/// Creates a matrix that rotates the sourceDirection vector to coincide with the targetDirection vector.]
|
|
/** Both input direction vectors must be normalized.
|
|
@note There are infinite such rotations - this function returns the rotation that has the shortest angle
|
|
(when decomposed to axis-angle notation)
|
|
@return An orthonormal matrix M with a determinant of +1. For the matrix M it holds that
|
|
M * sourceDirection = targetDirection */
|
|
static Matrix3x3 RotateFromTo(const Vector3& source, const Vector3& direction);
|
|
/// Creates a LookAt matrix.
|
|
/** A LookAt matrix is a rotation matrix that orients an object to face towards a specified target direction.
|
|
* @param forward Specifies the forward direction in the local space of the object. This is the direction
|
|
the model is facing at in its own local/object space, often +X (1,0,0), +Y (0,1,0), or +Z (0,0,1). The
|
|
vector to pass in here depends on the conventions you or your modeling software is using, and it is best
|
|
pick one convention for all your objects, and be consistent.
|
|
* @param target Specifies the desired world space direction the object should look at. This function
|
|
will compute a rotation matrix which will rotate the localForward vector to orient towards this targetDirection
|
|
vector. This input parameter must be a normalized vector.
|
|
* @param localUp Specifies the up direction in the local space of the object. This is the up direction the model
|
|
was authored in, often +Y (0,1,0) or +Z (0,0,1). The vector to pass in here depends on the conventions you
|
|
or your modeling software is using, and it is best to pick one convention for all your objects, and be
|
|
consistent. This input parameter must be a normalized vector. This vector must be perpendicular to the
|
|
vector localForward, i.e. localForward.Dot(localUp) == 0.
|
|
* @param worldUp Specifies the global up direction of the scene in world space. Simply rotating one vector to
|
|
coincide with another (localForward->targetDirection) would cause the up direction of the resulting
|
|
orientation to drift (e.g. the model could be looking at its target its head slanted sideways). To keep
|
|
the up direction straight, this function orients the localUp direction of the model to point towards the
|
|
specified worldUp direction (as closely as possible). The worldUp and targetDirection vectors cannot be
|
|
collinear, but they do not need to be perpendicular either.
|
|
* @return A matrix that maps the given local space forward direction vector to point towards the given target
|
|
direction, and the given local up direction towards the given target world up direction. This matrix can be
|
|
used as the 'world transform' of an object. THe returned matrix M is orthogonal with a determinant of +1.
|
|
For the matrix M it holds that M * localForward = targetDirection, and M * localUp lies in the plane spanned by
|
|
the vectors targetDirection and worldUp.
|
|
* @see RotateFromTo()
|
|
* @note Be aware that the convention of a 'LookAt' matrix in J3ML differs from e.g. GLM. In J3ML, the returned
|
|
matrix is a mapping from local space to world space, meaning that the returned matrix can be used as the 'world transform'
|
|
for any 3D object (camera or not). The view space is the local space of the camera, so this function returns the mapping
|
|
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.
|
|
// This function creates a new matrix M in the form M = R * S
|
|
// where R is a rotation matrix and S is a scale matrix.
|
|
// Transforming a vector v using this matrix computes the vector
|
|
// v' == M * v == R*S*v == (R * (S * v)) which means the scale operation
|
|
// is applied to the vector first, followed by rotation, and finally translation
|
|
static Matrix3x3 FromRS(const Quaternion& rotate, const Vector3& scale);
|
|
static Matrix3x3 FromRS(const Matrix3x3 &rotate, const Vector3& scale);
|
|
/// Creates a new transformation matrix that scales by the given factors.
|
|
// This matrix scales with respect to origin.
|
|
static Matrix3x3 FromScale(float sx, float sy, float sz);
|
|
static Matrix3x3 FromScale(const Vector3& scale);
|
|
public: /// Member Methods
|
|
/// Sets this matrix to perform rotation about the positive X axis which passes through the origin
|
|
/// [similarOverload: SetRotatePart] [hideIndex]
|
|
void SetRotatePartX(float angle);
|
|
/// Sets this matrix to perform rotation about the positive Y axis.
|
|
void SetRotatePartY(float angle);
|
|
/// Sets this matrix to perform rotation about the positive Z axis.
|
|
void SetRotatePartZ(float angle);
|
|
|
|
/// Sets this matrix to perform a rotation about the given axis and angle.
|
|
void SetRotatePart(const Vector3& a, float angle);
|
|
|
|
void SetRotatePart(const AxisAngle& axisAngle);
|
|
/// Sets this matrix to perform the rotation expressed by the given quaternion.
|
|
void SetRotatePart(const Quaternion& quat);
|
|
|
|
|
|
Vector3 ForwardDir() const;
|
|
Vector3 BackwardDir() const;
|
|
Vector3 LeftDir() const;
|
|
Vector3 RightDir() const;
|
|
Vector3 UpDir() const;
|
|
Vector3 DownDir() const;
|
|
|
|
/// Returns the given row.
|
|
/** @param row The zero-based index [0, 2] of the row to get. */
|
|
Vector3 GetRow(int index) const;
|
|
Vector3 Row(int index) const;
|
|
/// This method also allows assignment to the retrieved row.
|
|
Vector3& Row(int row);
|
|
|
|
/// Returns only the first-three elements of the given row.
|
|
Vector3 GetRow3(int index) const;
|
|
Vector3 Row3(int index) const;
|
|
/// This method also allows assignment to the retrieved row.
|
|
Vector3& Row3(int index);
|
|
|
|
/// Returns the given column.
|
|
/** @param col The zero-based index [0, 2] of the column to get. */
|
|
[[nodiscard]] Vector3 GetColumn(int index) const;
|
|
[[nodiscard]] Vector3 Column(int index) const;
|
|
[[nodiscard]] Vector3 Col(int index) const;
|
|
/// This method also allows assignment to the retrieved column.
|
|
//Vector3& Col(int index);
|
|
|
|
/// Returns only the first three elements of the given column.
|
|
[[nodiscard]] Vector3 GetColumn3(int index) const;
|
|
[[nodiscard]] Vector3 Column3(int index) const;
|
|
[[nodiscard]] Vector3 Col3(int index) const;
|
|
/// This method also allows assignment to the retrieved column.
|
|
//Vector3& Col3(int index);
|
|
|
|
/// Sets the value of a given row.
|
|
/** @param row The index of the row to a set, in the range [0-2].
|
|
@param data A pointer to an array of 3 floats that contain the new x, y, and z values for the row.*/
|
|
void SetRow(int row, const float* data);
|
|
void SetRow(int row, const Vector3 & data);
|
|
void SetRow(int row, float x, float y, float z);
|
|
|
|
/// Sets the value of a given column.
|
|
/** @param column The index of the column to set, in the range [0-2]
|
|
@param data A pointer to an array of 3 floats that contain the new x, y, and z values for the column.*/
|
|
void SetColumn(int column, const float* data);
|
|
void SetColumn(int column, const Vector3 & data);
|
|
void SetColumn(int column, float x, float y, float z);
|
|
|
|
|
|
/// Sets a single element of this matrix
|
|
/** @param row The row index (y-coordinate) of the element to set, in the range [0-2].
|
|
@param col The col index (x-coordinate) of the element to set, in the range [0-2].
|
|
@param value The new value to set to the cell [row][col]. */
|
|
void SetAt(int x, int y, float value);
|
|
|
|
|
|
/// Sets this matrix to equal the identity.
|
|
void SetIdentity();
|
|
|
|
/// Swaps two columns.
|
|
void SwapColumns(int col1, int col2);
|
|
|
|
/// Swaps two rows.
|
|
void SwapRows(int row1, int row2);
|
|
|
|
float &At(int row, int col);
|
|
[[nodiscard]] float At(int x, int y) const;
|
|
|
|
/// Sets this to be a copy of the matrix rhs.
|
|
void Set(const Matrix3x3 &rhs);
|
|
/// Sets all values of this matrix/
|
|
void Set(float _00, float _01, float _02,
|
|
float _10, float _11, float _12,
|
|
float _20, float _21, float _22);
|
|
/// Sets all values of this matrix.
|
|
/// @param valuesThe values in this array will be copied over to this matrix. The source must contain 9 floats in row-major order
|
|
/// (the same order as the Set() function aove has its input parameters in).
|
|
void Set(const float *p);
|
|
|
|
/// Orthonormalizes the basis formed by the column vectors of this matrix.
|
|
void Orthonormalize(int c0, int c1, int c2);
|
|
|
|
/// Accesses this structure as a float array.
|
|
/// @return A pointer to the upper-left element. The data is contiguous in memory.
|
|
/// ptr[0] gives the element [0][0], ptr[1] is [0][1]. ptr[2] is [0][2]
|
|
inline float* ptr() { return &elems[0][0];}
|
|
[[nodiscard]] inline const float* ptr() const {return &elems[0][0];}
|
|
|
|
/// Attempts to convert this matrix to a quaternion. Returns false if the conversion cannot succeed (this matrix was not a rotation
|
|
/// matrix, and there is scaling ,shearing, or mirroring in this matrix)
|
|
bool TryConvertToQuat(Quaternion& q) const;
|
|
|
|
/// Returns the main diagonal.
|
|
/// The main diagonal consists of the elements at m[0][0], m[1][1], m[2][2]
|
|
[[nodiscard]] Vector3 Diagonal() const;
|
|
/// Returns the local +X/+Y/+Z axis in world space.
|
|
/// This is the same as transforming the vector{1,0,0} by this matrix.
|
|
[[nodiscard]] Vector3 WorldX() const;
|
|
/// Returns the local +Y axis in world space.
|
|
/// This is the same as transforming the vector{0,1,0} by this matrix.
|
|
[[nodiscard]] Vector3 WorldY() const;
|
|
/// Returns the local +Z axis in world space.
|
|
/// This is the same as transforming the vector{0,0,1} by this matrix.
|
|
[[nodiscard]] Vector3 WorldZ() const;
|
|
|
|
/// Computes the determinant of this matrix.
|
|
// If the determinant is nonzero, this matrix is invertible.
|
|
// If the determinant is negative, this matrix performs reflection about some axis.
|
|
// From http://msdn.microsoft.com/en-us/library/bb204853(VS.85).aspx :
|
|
// "If the determinant is positive, the basis is said to be "positively" oriented (or right-handed).
|
|
// If the determinant is negative, the basis is said to be "negatively" oriented (or left-handed)."
|
|
// @note This function computes 9 LOADs, 9 MULs and 5 ADDs. */
|
|
[[nodiscard]] float Determinant() const;
|
|
|
|
/// Computes the determinant of a symmetric matrix.
|
|
/** This function can be used to compute the determinant of a matrix in the case the matrix is known beforehand
|
|
to be symmetric. This function is slightly faster than Determinant().
|
|
* @return
|
|
*/
|
|
[[nodiscard]] float DeterminantSymmetric() const;
|
|
|
|
// Returns an inverted copy of this matrix.
|
|
[[nodiscard]] Matrix3x3 Inverted() const;
|
|
|
|
// Returns a transposed copy of this matrix.
|
|
[[nodiscard]] Matrix3x3 Transposed() const;
|
|
|
|
/// Returns the inverse transpose of this matrix.
|
|
/// Use the matrix to transform covariant vectors (normal vectors).
|
|
[[nodiscard]] Matrix3x3 InverseTransposed() const;
|
|
|
|
/// Computes the inverse transpose of this matrix.
|
|
/// Use the matrix to transform covariant vectors (normal vectors).
|
|
bool InverseTranspose();
|
|
|
|
/// Inverts this matrix using numerically stable Gaussian elimination.
|
|
/// @return Returns true on success, false otherwise;
|
|
bool Inverse(float epsilon = 1e-6f);
|
|
|
|
/// Inverts this matrix using Cramer's rule.
|
|
/// @return Returns true on success, false otherwise.
|
|
bool InverseFast(float epsilon = 1e-6f);
|
|
|
|
|
|
/// Solves the linear equation Ax=b.
|
|
/** The matrix A in the equations is this matrix. */
|
|
bool SolveAxb(Vector3 b, Vector3& x) const;
|
|
|
|
/// Inverts a column-orthogonal matrix.
|
|
/** 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 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.
|
|
The returned matrix will be column-orthogonal if the original matrix M was row-orthogonal as well.
|
|
(in which case S had uniform scale, InverseOrthogonalUniformScale() could have been used instead)*/
|
|
bool InverseColOrthogonal();
|
|
|
|
/// 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
|
|
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 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 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.
|
|
@note This function operates in-place. */
|
|
bool InverseSymmetric();
|
|
|
|
/// Transposes this matrix.
|
|
/// This operation swaps all elements with respect to the diagonal.
|
|
void Transpose();
|
|
|
|
|
|
/// Removes the scaling performed by this matrix. That is, decomposes this matrix M into a form M = M' * S, where
|
|
/// M' has unitary column vectors and S is a diagonal matrix. Then replaces this matrix with M'
|
|
/// @note This function assumes that this matrix does not contain projection (the fourth row of this matrix is [0 0 0 1]).
|
|
/// @note This function does not remove reflection (-1 scale along some axis).
|
|
void RemoveScale();
|
|
|
|
|
|
// Transforms the given vectors by this matrix M, i.e. returns M * (x,y,z)
|
|
[[nodiscard]] Vector2 Transform(const Vector2& rhs) const;
|
|
[[nodiscard]] Vector3 Transform(const Vector3& rhs) const;
|
|
|
|
/// Performs a batch transformation of the given array.
|
|
void BatchTransform(Vector3 *pointArray, int numPoints) const;
|
|
/// Performs a batch transformation of the given array.
|
|
void BatchTransform(Vector3 *pointArray, int numPoints, int stride) const;
|
|
/// Performs a batch transformation of the given array.
|
|
/// This function ignores the w component of the input vectors. These components are assumed to be either 0 or 1.
|
|
void BatchTransform(Vector4 *vectorArray, int numVectors) const;
|
|
/// Performs a batch transformation of the given array.
|
|
/// This function ignores the w component of the input vectors. These components are assumed to be either 0 or 1.
|
|
void BatchTransform(Vector4 *vectorArray, int numVectors, int stride) const;
|
|
|
|
/// Returns the sum of the diagonal elements of this matrix.
|
|
[[nodiscard]] float Trace() const;
|
|
|
|
|
|
Matrix3x3 ScaleBy(const Vector3& rhs);
|
|
[[nodiscard]] Vector3 GetScale() const;
|
|
|
|
/// Scales the given row by a scalar value.
|
|
void ScaleRow(int row, float scalar);
|
|
/// Scales the given column by a scalar value.
|
|
void ScaleCol(int col, float scalar);
|
|
|
|
Vector3 operator[](int row) const;
|
|
|
|
/// Transforms the given vector by this matrix (in the order M * v).
|
|
Vector2 operator * (const Vector2& rhs) const;
|
|
Vector3 operator * (const Vector3& rhs) const;
|
|
/// Transforms the given vector by this matrix (in the order M * v).
|
|
/// 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;}
|
|
|
|
|
|
/// Multiplies the two matrices.
|
|
Matrix3x3 operator * (const Matrix3x3& rhs) const;
|
|
[[nodiscard]] Matrix3x3 Mul(const Matrix3x3& rhs) const;
|
|
/// Multiplies the two matrices.
|
|
Matrix4x4 operator * (const Matrix4x4& rhs) const;
|
|
[[nodiscard]] Matrix4x4 Mul(const Matrix4x4& rhs) const;
|
|
|
|
[[nodiscard]] Vector2 Mul(const Vector2& rhs) const;
|
|
[[nodiscard]] Vector3 Mul(const Vector3& rhs) const;
|
|
[[nodiscard]] Vector4 Mul(const Vector4& rhs) const;
|
|
|
|
/// Converts the quaternion to a M3x3 and multiplies the two matrices together.
|
|
Matrix3x3 operator *(const Quaternion& rhs) const;
|
|
|
|
[[nodiscard]] Matrix3x3 Mul(const Quaternion& rhs) const;
|
|
|
|
// Returns true if the column vectors of this matrix are all perpendicular to each other.
|
|
[[nodiscard]] bool IsColOrthogonal(float epsilon = 1e-3f) const;
|
|
[[nodiscard]] bool IsColOrthogonal3(float epsilon = 1e-3f) const { return IsColOrthogonal(epsilon);}
|
|
// Returns true if the row vectors of this matrix are all perpendicular to each other.
|
|
[[nodiscard]] bool IsRowOrthogonal(float epsilon = 1e-3f) const;
|
|
|
|
|
|
[[nodiscard]] bool HasUniformScale(float epsilon = 1e-3f) const;
|
|
|
|
[[nodiscard]] Vector3 ExtractScale() const;
|
|
|
|
|
|
/// Tests if this matrix does not contain any NaNs or infs
|
|
/// @return Returns true if the entries of this M3x3 are all finite.
|
|
[[nodiscard]] bool IsFinite() const;
|
|
|
|
/// Tests if this is the identity matrix.
|
|
/// @return Returns true if this matrix is the identity matrix, up to the given epsilon.
|
|
[[nodiscard]] bool IsIdentity(float epsilon = 1e-3f) const;
|
|
/// Tests if this matrix is in lower triangular form.
|
|
/// @return Returns true if this matrix is in lower triangular form, up to the given epsilon.
|
|
[[nodiscard]] bool IsLowerTriangular(float epsilon = 1e-3f) const;
|
|
/// Tests if this matrix is in upper triangular form.
|
|
/// @return Returns true if this matrix is in upper triangular form, up to the given epsilon.
|
|
[[nodiscard]] bool IsUpperTriangular(float epsilon = 1e-3f) const;
|
|
/// Tests if this matrix has an inverse.
|
|
/// @return Returns true if this matrix can be inverted, up to the given epsilon.
|
|
[[nodiscard]] bool IsInvertible(float epsilon = 1e-3f) const;
|
|
/// Tests if this matrix is symmetric (M == M^T).
|
|
/// The test compares the elements for equality. Up to the given epsilon. A matrix is symmetric if it is its own transpose.
|
|
[[nodiscard]] bool IsSymmetric(float epsilon = 1e-3f) const;
|
|
/// Tests if this matrix is skew-symmetric (M == -M^T).
|
|
/// The test compares the elements of this matrix up to the given epsilon. A matrix M is skew-symmetric if the identity M=-M^T holds.
|
|
[[nodiscard]] bool IsSkewSymmetric(float epsilon = 1e-3f) const;
|
|
/// Returns true if this matrix does not perform any scaling,
|
|
/** A matrix does not do any scaling if the column vectors of this matrix are normalized in length,
|
|
compared to the given epsilon. Note that this matrix may still perform reflection,
|
|
i.e. it has a -1 scale along some axis.
|
|
@note This function only examines the upper 3-by-3 part of this matrix.
|
|
@note This function assumes that this matrix does not contain projection (the fourth row of this matrix is [0,0,0,1] */
|
|
[[nodiscard]] bool HasUnitaryScale(float epsilon = 1e-3f) const;
|
|
/// Returns true if this matrix performs a reflection along some plane.
|
|
/** In 3D space, an even number of reflections corresponds to a rotation about some axis, so a matrix consisting of
|
|
an odd number of consecutive mirror operations can only reflect about one axis. A matrix that contains reflection reverses
|
|
the handedness of the coordinate system. This function tests if this matrix does perform mirroring.
|
|
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.
|
|
/// In terms of this library however, a matrix is orthogonal if its column and row vectors are orthogonal. (no need to be unitary),
|
|
/// 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]{};
|
|
};
|
|
} |