/*
* The MIT License
*
* Copyright (c) 2020-2021 JOML
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.jozufozu.flywheel.repack.joml;
import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.util.*;
/**
* Interface to a read-only view of a 2x2 matrix of double-precision floats.
*
* @author Joseph Burton
*/
public interface Matrix2dc {
/**
* Return the value of the matrix element at column 0 and row 0.
*
* @return the value of the matrix element
*/
double m00();
/**
* Return the value of the matrix element at column 0 and row 1.
*
* @return the value of the matrix element
*/
double m01();
/**
* Return the value of the matrix element at column 1 and row 0.
*
* @return the value of the matrix element
*/
double m10();
/**
* Return the value of the matrix element at column 1 and row 1.
*
* @return the value of the matrix element
*/
double m11();
/**
* Multiply this matrix by the supplied right
matrix and store the result in dest
.
*
* If M
is this
matrix and R
the right
matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* transformation of the right matrix will be applied first!
*
* @param right
* the right operand of the matrix multiplication
* @param dest
* will hold the result
* @return dest
*/
Matrix2d mul(Matrix2dc right, Matrix2d dest);
/**
* Multiply this matrix by the supplied right
matrix and store the result in dest
.
*
* If M
is this
matrix and R
the right
matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
, the
* transformation of the right matrix will be applied first!
*
* @param right
* the right operand of the matrix multiplication
* @param dest
* will hold the result
* @return dest
*/
Matrix2d mul(Matrix2fc right, Matrix2d dest);
/**
* Pre-multiply this matrix by the supplied left
matrix and store the result in dest
.
*
* If M
is this
matrix and L
the left
matrix,
* then the new matrix will be L * M
. So when transforming a
* vector v
with the new matrix by using L * M * v
, the
* transformation of this
matrix will be applied first!
*
* @param left
* the left operand of the matrix multiplication
* @param dest
* the destination matrix, which will hold the result
* @return dest
*/
Matrix2d mulLocal(Matrix2dc left, Matrix2d dest);
/**
* Return the determinant of this matrix.
*
* @return the determinant
*/
double determinant();
/**
* Invert the this
matrix and store the result in dest
.
*
* @param dest
* will hold the result
* @return dest
*/
Matrix2d invert(Matrix2d dest);
/**
* Transpose this
matrix and store the result in dest
.
*
* @param dest
* will hold the result
* @return dest
*/
Matrix2d transpose(Matrix2d dest);
/**
* Get the current values of this
matrix and store them into
* dest
.
*
* @param dest
* the destination matrix
* @return the passed in destination
*/
Matrix2d get(Matrix2d dest);
/**
* Get the current values of this
matrix and store them as
* the rotational component of dest
. All other values of dest
will
* be set to 0.
*
* @see Matrix3x2d#set(Matrix2dc)
*
* @param dest
* the destination matrix
* @return the passed in destination
*/
Matrix3x2d get(Matrix3x2d dest);
/**
* Get the current values of this
matrix and store them as
* the rotational component of dest
. All other values of dest
will
* be set to identity.
*
* @see Matrix3d#set(Matrix2dc)
*
* @param dest
* the destination matrix
* @return the passed in destination
*/
Matrix3d get(Matrix3d dest);
/**
* Get the angle of the rotation component of this
matrix.
*
* This method assumes that there is a valid rotation to be returned, i.e. that
* atan2(-m10, m00) == atan2(m01, m11)
.
*
* @return the angle
*/
double getRotation();
/**
* Store this matrix in column-major order into the supplied {@link DoubleBuffer} at the current
* buffer {@link DoubleBuffer#position() position}.
*
* This method will not increment the position of the given DoubleBuffer. *
* In order to specify the offset into the DoubleBuffer at which * the matrix is stored, use {@link #get(int, DoubleBuffer)}, taking * the absolute position as parameter. * * @see #get(int, DoubleBuffer) * * @param buffer * will receive the values of this matrix in column-major order at its current position * @return the passed in buffer */ DoubleBuffer get(DoubleBuffer buffer); /** * Store this matrix in column-major order into the supplied {@link DoubleBuffer} starting at the specified * absolute buffer position/index. *
* This method will not increment the position of the given DoubleBuffer. * * @param index * the absolute position into the DoubleBuffer * @param buffer * will receive the values of this matrix in column-major order * @return the passed in buffer */ DoubleBuffer get(int index, DoubleBuffer buffer); /** * Store this matrix in column-major order into the supplied {@link ByteBuffer} at the current * buffer {@link ByteBuffer#position() position}. *
* This method will not increment the position of the given ByteBuffer. *
* In order to specify the offset into the ByteBuffer at which * the matrix is stored, use {@link #get(int, ByteBuffer)}, taking * the absolute position as parameter. * * @see #get(int, ByteBuffer) * * @param buffer * will receive the values of this matrix in column-major order at its current position * @return the passed in buffer */ ByteBuffer get(ByteBuffer buffer); /** * Store this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified * absolute buffer position/index. *
* This method will not increment the position of the given ByteBuffer. * * @param index * the absolute position into the ByteBuffer * @param buffer * will receive the values of this matrix in column-major order * @return the passed in buffer */ ByteBuffer get(int index, ByteBuffer buffer); /** * Store the transpose of this matrix in column-major order into the supplied {@link DoubleBuffer} at the current * buffer {@link DoubleBuffer#position() position}. *
* This method will not increment the position of the given DoubleBuffer. *
* In order to specify the offset into the DoubleBuffer at which * the matrix is stored, use {@link #getTransposed(int, DoubleBuffer)}, taking * the absolute position as parameter. * * @see #getTransposed(int, DoubleBuffer) * * @param buffer * will receive the values of this matrix in column-major order at its current position * @return the passed in buffer */ DoubleBuffer getTransposed(DoubleBuffer buffer); /** * Store the transpose of this matrix in column-major order into the supplied {@link DoubleBuffer} starting at the specified * absolute buffer position/index. *
* This method will not increment the position of the given DoubleBuffer. * * @param index * the absolute position into the DoubleBuffer * @param buffer * will receive the values of this matrix in column-major order * @return the passed in buffer */ DoubleBuffer getTransposed(int index, DoubleBuffer buffer); /** * Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} at the current * buffer {@link ByteBuffer#position() position}. *
* This method will not increment the position of the given ByteBuffer. *
* In order to specify the offset into the ByteBuffer at which * the matrix is stored, use {@link #getTransposed(int, ByteBuffer)}, taking * the absolute position as parameter. * * @see #getTransposed(int, ByteBuffer) * * @param buffer * will receive the values of this matrix in column-major order at its current position * @return the passed in buffer */ ByteBuffer getTransposed(ByteBuffer buffer); /** * Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified * absolute buffer position/index. *
* This method will not increment the position of the given ByteBuffer. * * @param index * the absolute position into the ByteBuffer * @param buffer * will receive the values of this matrix in column-major order * @return the passed in buffer */ ByteBuffer getTransposed(int index, ByteBuffer buffer); /** * Store this matrix in column-major order at the given off-heap address. *
* This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`. *
* This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process. * * @param address * the off-heap address where to store this matrix * @return this */ Matrix2dc getToAddress(long address); /** * Store this matrix into the supplied double array in column-major order at the given offset. * * @param arr * the array to write the matrix values into * @param offset * the offset into the array * @return the passed in array */ double[] get(double[] arr, int offset); /** * Store this matrix into the supplied double array in column-major order. *
* In order to specify an explicit offset into the array, use the method {@link #get(double[], int)}.
*
* @see #get(double[], int)
*
* @param arr
* the array to write the matrix values into
* @return the passed in array
*/
double[] get(double[] arr);
/**
* Apply scaling to this
matrix by scaling the base axes by the given xy.x
and
* xy.y
factors, respectively and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
* , the scaling will be applied first!
*
* @param xy
* the factors of the x and y component, respectively
* @param dest
* will hold the result
* @return dest
*/
Matrix2d scale(Vector2dc xy, Matrix2d dest);
/**
* Apply scaling to this matrix by scaling the base axes by the given x and
* y factors and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
* , the scaling will be applied first!
*
* @param x
* the factor of the x component
* @param y
* the factor of the y component
* @param dest
* will hold the result
* @return dest
*/
Matrix2d scale(double x, double y, Matrix2d dest);
/**
* Apply scaling to this matrix by uniformly scaling all base axes by the given xy
factor
* and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be M * S
. So when transforming a
* vector v
with the new matrix by using M * S * v
* , the scaling will be applied first!
*
* @see #scale(double, double, Matrix2d)
*
* @param xy
* the factor for all components
* @param dest
* will hold the result
* @return dest
*/
Matrix2d scale(double xy, Matrix2d dest);
/**
* Pre-multiply scaling to this
matrix by scaling the base axes by the given x and
* y factors and store the result in dest
.
*
* If M
is this
matrix and S
the scaling matrix,
* then the new matrix will be S * M
. So when transforming a
* vector v
with the new matrix by using S * M * v
* , the scaling will be applied last!
*
* @param x
* the factor of the x component
* @param y
* the factor of the y component
* @param dest
* will hold the result
* @return dest
*/
Matrix2d scaleLocal(double x, double y, Matrix2d dest);
/**
* Transform the given vector by this matrix.
*
* @param v
* the vector to transform
* @return v
*/
Vector2d transform(Vector2d v);
/**
* Transform the given vector by this matrix and store the result in dest
.
*
* @param v
* the vector to transform
* @param dest
* will hold the result
* @return dest
*/
Vector2d transform(Vector2dc v, Vector2d dest);
/**
* Transform the vector (x, y)
by this matrix and store the result in dest
.
*
* @param x
* the x coordinate of the vector to transform
* @param y
* the y coordinate of the vector to transform
* @param dest
* will hold the result
* @return dest
*/
Vector2d transform(double x, double y, Vector2d dest);
/**
* Transform the given vector by the transpose of this matrix.
*
* @param v
* the vector to transform
* @return v
*/
Vector2d transformTranspose(Vector2d v);
/**
* Transform the given vector by the transpose of this matrix and store the result in dest
.
*
* @param v
* the vector to transform
* @param dest
* will hold the result
* @return dest
*/
Vector2d transformTranspose(Vector2dc v, Vector2d dest);
/**
* Transform the vector (x, y)
by the transpose of this matrix and store the result in dest
.
*
* @param x
* the x coordinate of the vector to transform
* @param y
* the y coordinate of the vector to transform
* @param dest
* will hold the result
* @return dest
*/
Vector2d transformTranspose(double x, double y, Vector2d dest);
/**
* Apply rotation to this matrix by rotating the given amount of radians
* and store the result in dest
.
*
* The produced rotation will rotate a vector counter-clockwise around the origin. *
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be M * R
. So when transforming a
* vector v
with the new matrix by using M * R * v
* , the rotation will be applied first!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians
* @param dest
* will hold the result
* @return dest
*/
Matrix2d rotate(double ang, Matrix2d dest);
/**
* Pre-multiply a rotation to this matrix by rotating the given amount of radians
* and store the result in dest
.
*
* The produced rotation will rotate a vector counter-clockwise around the origin. *
* If M
is this
matrix and R
the rotation matrix,
* then the new matrix will be R * M
. So when transforming a
* vector v
with the new matrix by using R * M * v
, the
* rotation will be applied last!
*
* Reference: http://en.wikipedia.org
*
* @param ang
* the angle in radians
* @param dest
* will hold the result
* @return dest
*/
Matrix2d rotateLocal(double ang, Matrix2d dest);
/**
* Get the row at the given row
index, starting with 0
.
*
* @param row
* the row index in [0..1]
* @param dest
* will hold the row components
* @return the passed in destination
* @throws IndexOutOfBoundsException if row
is not in [0..1]
*/
Vector2d getRow(int row, Vector2d dest) throws IndexOutOfBoundsException;
/**
* Get the column at the given column
index, starting with 0
.
*
* @param column
* the column index in [0..1]
* @param dest
* will hold the column components
* @return the passed in destination
* @throws IndexOutOfBoundsException if column
is not in [0..1]
*/
Vector2d getColumn(int column, Vector2d dest) throws IndexOutOfBoundsException;
/**
* Get the matrix element value at the given column and row.
*
* @param column
* the colum index in [0..1]
* @param row
* the row index in [0..1]
* @return the element value
*/
double get(int column, int row);
/**
* Compute a normal matrix from this
matrix and store it into dest
.
*
* @param dest
* will hold the result
* @return dest
*/
Matrix2d normal(Matrix2d dest);
/**
* Get the scaling factors of this
matrix for the three base axes.
*
* @param dest
* will hold the scaling factors for x
and y
* @return dest
*/
Vector2d getScale(Vector2d dest);
/**
* Obtain the direction of +X
before the transformation represented by this
matrix is applied.
*
* This method is equivalent to the following code: *
* Matrix2d inv = new Matrix2d(this).invert(); * inv.transform(dir.set(1, 0)).normalize(); ** If
this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveX(Vector2d)} instead.
*
* @param dest
* will hold the direction of +X
* @return dest
*/
Vector2d positiveX(Vector2d dest);
/**
* Obtain the direction of +X
before the transformation represented by this
orthogonal matrix is applied.
* This method only produces correct results if this
is an orthogonal matrix.
* * This method is equivalent to the following code: *
* Matrix2d inv = new Matrix2d(this).transpose(); * inv.transform(dir.set(1, 0)); ** * @param dest * will hold the direction of
+X
* @return dest
*/
Vector2d normalizedPositiveX(Vector2d dest);
/**
* Obtain the direction of +Y
before the transformation represented by this
matrix is applied.
* * This method is equivalent to the following code: *
* Matrix2d inv = new Matrix2d(this).invert(); * inv.transform(dir.set(0, 1)).normalize(); ** If
this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveY(Vector2d)} instead.
*
* @param dest
* will hold the direction of +Y
* @return dest
*/
Vector2d positiveY(Vector2d dest);
/**
* Obtain the direction of +Y
before the transformation represented by this
orthogonal matrix is applied.
* This method only produces correct results if this
is an orthogonal matrix.
* * This method is equivalent to the following code: *
* Matrix2d inv = new Matrix2d(this).transpose(); * inv.transform(dir.set(0, 1)); ** * @param dest * will hold the direction of
+Y
* @return dest
*/
Vector2d normalizedPositiveY(Vector2d dest);
/**
* Component-wise add this
and other
and store the result in dest
.
*
* @param other
* the other addend
* @param dest
* will hold the result
* @return dest
*/
Matrix2d add(Matrix2dc other, Matrix2d dest);
/**
* Component-wise subtract subtrahend
from this
and store the result in dest
.
*
* @param subtrahend
* the subtrahend
* @param dest
* will hold the result
* @return dest
*/
Matrix2d sub(Matrix2dc subtrahend, Matrix2d dest);
/**
* Component-wise multiply this
by other
and store the result in dest
.
*
* @param other
* the other matrix
* @param dest
* will hold the result
* @return dest
*/
Matrix2d mulComponentWise(Matrix2dc other, Matrix2d dest);
/**
* Linearly interpolate this
and other
using the given interpolation factor t
* and store the result in dest
.
*
* If t
is 0.0
then the result is this
. If the interpolation factor is 1.0
* then the result is other
.
*
* @param other
* the other matrix
* @param t
* the interpolation factor between 0.0 and 1.0
* @param dest
* will hold the result
* @return dest
*/
Matrix2d lerp(Matrix2dc other, double t, Matrix2d dest);
/**
* Compare the matrix elements of this
matrix with the given matrix using the given delta
* and return whether all of them are equal within a maximum difference of delta
.
*
* Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
* and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
* data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
*
* @param m
* the other matrix
* @param delta
* the allowed maximum difference
* @return true
whether all of the matrix elements are equal; false
otherwise
*/
boolean equals(Matrix2dc m, double delta);
/**
* Determine whether all matrix elements are finite floating-point values, that
* is, they are not {@link Double#isNaN() NaN} and not
* {@link Double#isInfinite() infinity}.
*
* @return {@code true} if all components are finite floating-point values;
* {@code false} otherwise
*/
boolean isFinite();
}