Inverse, cofactor and adjugate matrices
This commit is contained in:
parent
cb1bec0328
commit
d0b3c7347c
@ -66,6 +66,33 @@ interface IDoubleMatrix<T : IDoubleMatrix<T>> : IMatrixGetterDouble {
|
||||
* This matrix determinant. If matrix is not square matrix, null is returned.
|
||||
*/
|
||||
val determinant: Double?
|
||||
|
||||
/**
|
||||
* This matrix' inverse matrix (this * I = identity).
|
||||
*
|
||||
* This operation is computation intense, do cache its result.
|
||||
*
|
||||
* If this matrix is not square matrix, or determinant is zero, null is returned.
|
||||
*/
|
||||
val inverse: T?
|
||||
|
||||
/**
|
||||
* This matrix' cofactor matrix.
|
||||
*
|
||||
* This operation is computation intense, do cache its result.
|
||||
*
|
||||
* If this matrix is not square matrix, null is returned.
|
||||
*/
|
||||
val cofactor: T?
|
||||
|
||||
/**
|
||||
* This matrix' adjugate matrix.
|
||||
*
|
||||
* This operation is computation intense, do cache its result.
|
||||
*
|
||||
* If this matrix is not square matrix, null is returned.
|
||||
*/
|
||||
val adjugate: T?
|
||||
}
|
||||
|
||||
interface IMutableDoubleMatrix<T : IMutableDoubleMatrix<T>> : IMatrixSetterDouble {
|
||||
|
@ -66,6 +66,33 @@ interface IFloatMatrix<T : IFloatMatrix<T>> : IMatrixGetterFloat {
|
||||
* This matrix determinant. If matrix is not square matrix, null is returned.
|
||||
*/
|
||||
val determinant: Float?
|
||||
|
||||
/**
|
||||
* This matrix' inverse matrix (this * I = identity).
|
||||
*
|
||||
* This operation is computation intense, do cache its result.
|
||||
*
|
||||
* If this matrix is not square matrix, or determinant is zero, null is returned.
|
||||
*/
|
||||
val inverse: T?
|
||||
|
||||
/**
|
||||
* This matrix' cofactor matrix.
|
||||
*
|
||||
* This operation is computation intense, do cache its result.
|
||||
*
|
||||
* If this matrix is not square matrix, null is returned.
|
||||
*/
|
||||
val cofactor: T?
|
||||
|
||||
/**
|
||||
* This matrix' adjugate matrix.
|
||||
*
|
||||
* This operation is computation intense, do cache its result.
|
||||
*
|
||||
* If this matrix is not square matrix, null is returned.
|
||||
*/
|
||||
val adjugate: T?
|
||||
}
|
||||
|
||||
interface IMutableFloatMatrix<T : IMutableFloatMatrix<T>> : IMatrixSetterFloat {
|
||||
|
@ -5,6 +5,8 @@ import ru.dbotthepony.kvector.api.IMatrix
|
||||
import ru.dbotthepony.kvector.api.ISquareMatrix
|
||||
import ru.dbotthepony.kvector.api.ITransposable
|
||||
import ru.dbotthepony.kvector.matrix.*
|
||||
import ru.dbotthepony.kvector.matrix.ndouble.*
|
||||
import ru.dbotthepony.kvector.matrix.nfloat.*
|
||||
import ru.dbotthepony.kvector.vector.ndouble.Vector2d
|
||||
import ru.dbotthepony.kvector.vector.ndouble.Vector3d
|
||||
import ru.dbotthepony.kvector.vector.ndouble.Vector4d
|
||||
@ -33,6 +35,153 @@ interface IMatrix2d<T : IMatrix2d<T>> : IMatrix<T>, IDoubleMatrix<T>, ITransposa
|
||||
val c1: Vector2d
|
||||
val r0: Vector2d
|
||||
val r1: Vector2d
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4d],
|
||||
* setting last two rows and columns to 0
|
||||
*/
|
||||
fun toMatrix4d(): Matrix4d {
|
||||
return Matrix4d(
|
||||
c00, c01, 0.0, 0.0,
|
||||
c10, c11, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3d],
|
||||
* setting last row and column to 0
|
||||
*/
|
||||
fun toMatrix3d(): Matrix3d {
|
||||
return Matrix3d(
|
||||
c00, c01, 0.0,
|
||||
c10, c11, 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2d]
|
||||
*/
|
||||
fun toMatrix2d(): Matrix2d {
|
||||
return Matrix2d(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4d],
|
||||
* setting last two columns and rows to 0
|
||||
*/
|
||||
fun toMutableMatrix4d(): MutableMatrix4d {
|
||||
return MutableMatrix4d(
|
||||
c00, c01, 0.0, 0.0,
|
||||
c10, c11, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3d],
|
||||
* setting last column and row to 0
|
||||
*/
|
||||
fun toMutableMatrix3d(): MutableMatrix3d {
|
||||
return MutableMatrix3d(
|
||||
c00, c01, 0.0,
|
||||
c10, c11, 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2d]
|
||||
*/
|
||||
fun toMutableMatrix2d(): MutableMatrix2d {
|
||||
return MutableMatrix2d(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4f],
|
||||
* casing all [Double]s to [Float]s,
|
||||
* setting last two columns and rows to 0
|
||||
*/
|
||||
fun toMatrix4f(): Matrix4f {
|
||||
return Matrix4f(
|
||||
c00.toFloat(), c01.toFloat(), 0f, 0f,
|
||||
c10.toFloat(), c11.toFloat(), 0f, 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3f],
|
||||
* casing all [Double]s to [Float]s,
|
||||
* setting last column and row to 0
|
||||
*/
|
||||
fun toMatrix3f(): Matrix3f {
|
||||
return Matrix3f(
|
||||
c00.toFloat(), c01.toFloat(), 0f,
|
||||
c10.toFloat(), c11.toFloat(), 0f,
|
||||
0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2f],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMatrix2f(): Matrix2f {
|
||||
return Matrix2f(
|
||||
c00.toFloat(), c01.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4f],
|
||||
* setting last two columns and rows to 0,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix4f(): MutableMatrix4f {
|
||||
return MutableMatrix4f(
|
||||
c00.toFloat(), c01.toFloat(), 0f, 0f,
|
||||
c10.toFloat(), c11.toFloat(), 0f, 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3f],
|
||||
* setting last column and row to 0,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix3f(): MutableMatrix3f {
|
||||
return MutableMatrix3f(
|
||||
c00.toFloat(), c01.toFloat(), 0f,
|
||||
c10.toFloat(), c11.toFloat(), 0f,
|
||||
0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2f],
|
||||
* truncating last row and column,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix2f(): MutableMatrix2f {
|
||||
return MutableMatrix2f(
|
||||
c00.toFloat(), c01.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,6 +232,152 @@ interface IMatrix3d<T : IMatrix3d<T>> : IMatrix<T>, IDoubleMatrix<T>, ITransposa
|
||||
val r2: Vector3d
|
||||
|
||||
override val translation: Vector2d get() = Vector2d(r02, r12)
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4d],
|
||||
* setting last row and column to 0
|
||||
*/
|
||||
fun toMatrix4d(): Matrix4d {
|
||||
return Matrix4d(
|
||||
c00, c01, c02, 0.0,
|
||||
c10, c11, c12, 0.0,
|
||||
c20, c21, c22, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3d],
|
||||
*/
|
||||
fun toMatrix3d(): Matrix3d {
|
||||
return Matrix3d(
|
||||
c00, c01, c02,
|
||||
c10, c11, c12,
|
||||
c20, c21, c22,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2d],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMatrix2d(): Matrix2d {
|
||||
return Matrix2d(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4d],
|
||||
* setting last column and row to 0
|
||||
*/
|
||||
fun toMutableMatrix4d(): MutableMatrix4d {
|
||||
return MutableMatrix4d(
|
||||
c00, c01, c02, 0.0,
|
||||
c10, c11, c12, 0.0,
|
||||
c20, c21, c22, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3d]
|
||||
*/
|
||||
fun toMutableMatrix3d(): MutableMatrix3d {
|
||||
return MutableMatrix3d(
|
||||
c00, c01, c02,
|
||||
c10, c11, c12,
|
||||
c20, c21, c22,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2d],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMutableMatrix2d(): MutableMatrix2d {
|
||||
return MutableMatrix2d(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4f],
|
||||
* casing all [Double]s to [Float]s,
|
||||
* setting last column and row to 0
|
||||
*/
|
||||
fun toMatrix4f(): Matrix4f {
|
||||
return Matrix4f(
|
||||
c00.toFloat(), c01.toFloat(), c02.toFloat(), 0f,
|
||||
c10.toFloat(), c11.toFloat(), c12.toFloat(), 0f,
|
||||
c20.toFloat(), c21.toFloat(), c22.toFloat(), 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3f],
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMatrix3f(): Matrix3f {
|
||||
return Matrix3f(
|
||||
c00.toFloat(), c01.toFloat(), c02.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(), c12.toFloat(),
|
||||
c20.toFloat(), c21.toFloat(), c22.toFloat(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2f],
|
||||
* truncating last row and column,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMatrix2f(): Matrix2f {
|
||||
return Matrix2f(
|
||||
c00.toFloat(), c01.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4f],
|
||||
* setting last column and row to 0,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix4f(): MutableMatrix4f {
|
||||
return MutableMatrix4f(
|
||||
c00.toFloat(), c01.toFloat(), c02.toFloat(), 0f,
|
||||
c10.toFloat(), c11.toFloat(), c12.toFloat(), 0f,
|
||||
c20.toFloat(), c21.toFloat(), c22.toFloat(), 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3f],
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix3f(): MutableMatrix3f {
|
||||
return MutableMatrix3f(
|
||||
c00.toFloat(), c01.toFloat(), c02.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(), c12.toFloat(),
|
||||
c20.toFloat(), c21.toFloat(), c22.toFloat(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2f],
|
||||
* truncating last row and column,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix2f(): MutableMatrix2f {
|
||||
return MutableMatrix2f(
|
||||
c00.toFloat(), c01.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,4 +458,150 @@ interface IMatrix4d<T : IMatrix4d<T>> : IMatrix<T>, IDoubleMatrix<T>, ITransposa
|
||||
val r3: Vector4d
|
||||
|
||||
override val translation: Vector3d get() = Vector3d(r03, r13, r23)
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4d]
|
||||
*/
|
||||
fun toMatrix4d(): Matrix4d {
|
||||
return Matrix4d(
|
||||
c00, c01, c02, c03,
|
||||
c10, c11, c12, c13,
|
||||
c20, c21, c22, c23,
|
||||
c30, c31, c32, c33,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3d],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMatrix3d(): Matrix3d {
|
||||
return Matrix3d(
|
||||
c00, c01, c02,
|
||||
c10, c11, c12,
|
||||
c20, c21, c22,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2d],
|
||||
* truncating two last rows and columns
|
||||
*/
|
||||
fun toMatrix2d(): Matrix2d {
|
||||
return Matrix2d(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4d]
|
||||
*/
|
||||
fun toMutableMatrix4d(): MutableMatrix4d {
|
||||
return MutableMatrix4d(
|
||||
c00, c01, c02, c03,
|
||||
c10, c11, c12, c13,
|
||||
c20, c21, c22, c23,
|
||||
c30, c31, c32, c33,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3d],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMutableMatrix3d(): MutableMatrix3d {
|
||||
return MutableMatrix3d(
|
||||
c00, c01, c02,
|
||||
c10, c11, c12,
|
||||
c20, c21, c22,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2d],
|
||||
* truncating two last rows and columns
|
||||
*/
|
||||
fun toMutableMatrix2d(): MutableMatrix2d {
|
||||
return MutableMatrix2d(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4f],
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMatrix4f(): Matrix4f {
|
||||
return Matrix4f(
|
||||
c00.toFloat(), c01.toFloat(), c02.toFloat(), c03.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(), c12.toFloat(), c13.toFloat(),
|
||||
c20.toFloat(), c21.toFloat(), c22.toFloat(), c23.toFloat(),
|
||||
c30.toFloat(), c31.toFloat(), c32.toFloat(), c33.toFloat(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3f],
|
||||
* truncating last row and column,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMatrix3f(): Matrix3f {
|
||||
return Matrix3f(
|
||||
c00.toFloat(), c01.toFloat(), c02.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(), c12.toFloat(),
|
||||
c20.toFloat(), c21.toFloat(), c22.toFloat(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2f],
|
||||
* truncating two last rows and columns,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMatrix2f(): Matrix2f {
|
||||
return Matrix2f(
|
||||
c00.toFloat(), c01.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4f],
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix4f(): MutableMatrix4f {
|
||||
return MutableMatrix4f(
|
||||
c00.toFloat(), c01.toFloat(), c02.toFloat(), c03.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(), c12.toFloat(), c13.toFloat(),
|
||||
c20.toFloat(), c21.toFloat(), c22.toFloat(), c23.toFloat(),
|
||||
c30.toFloat(), c31.toFloat(), c32.toFloat(), c33.toFloat(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3f],
|
||||
* truncating last row and column,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix3f(): MutableMatrix3f {
|
||||
return MutableMatrix3f(
|
||||
c00.toFloat(), c01.toFloat(), c02.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(), c12.toFloat(),
|
||||
c20.toFloat(), c21.toFloat(), c22.toFloat(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2f],
|
||||
* truncating two last rows and columns,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix2f(): MutableMatrix2f {
|
||||
return MutableMatrix2f(
|
||||
c00.toFloat(), c01.toFloat(),
|
||||
c10.toFloat(), c11.toFloat(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ import ru.dbotthepony.kvector.api.IMatrix
|
||||
import ru.dbotthepony.kvector.api.ISquareMatrix
|
||||
import ru.dbotthepony.kvector.api.ITransposable
|
||||
import ru.dbotthepony.kvector.matrix.*
|
||||
import ru.dbotthepony.kvector.matrix.ndouble.*
|
||||
import ru.dbotthepony.kvector.matrix.nfloat.*
|
||||
import ru.dbotthepony.kvector.vector.nfloat.*
|
||||
|
||||
/**
|
||||
@ -34,6 +36,156 @@ interface IMatrix2f<T : IMatrix2f<T>> : IMatrix<T>, IFloatMatrix<T>, ITransposab
|
||||
val c1: Vector2f
|
||||
val r0: Vector2f
|
||||
val r1: Vector2f
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4d],
|
||||
* setting last two rows and columns to 0,
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMatrix4d(): Matrix4d {
|
||||
return Matrix4d(
|
||||
c00.toDouble(), c01.toDouble(), 0.0, 0.0,
|
||||
c10.toDouble(), c11.toDouble(), 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3d],
|
||||
* setting last row and column to 0,
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMatrix3d(): Matrix3d {
|
||||
return Matrix3d(
|
||||
c00.toDouble(), c01.toDouble(), 0.0,
|
||||
c10.toDouble(), c11.toDouble(), 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2d],
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMatrix2d(): Matrix2d {
|
||||
return Matrix2d(
|
||||
c00.toDouble(), c01.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4d],
|
||||
* setting last two columns and rows to 0,
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMutableMatrix4d(): MutableMatrix4d {
|
||||
return MutableMatrix4d(
|
||||
c00.toDouble(), c01.toDouble(), 0.0, 0.0,
|
||||
c10.toDouble(), c11.toDouble(), 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3d],
|
||||
* setting last column and row to 0,
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMutableMatrix3d(): MutableMatrix3d {
|
||||
return MutableMatrix3d(
|
||||
c00.toDouble(), c01.toDouble(), 0.0,
|
||||
c10.toDouble(), c11.toDouble(), 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2d],
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMutableMatrix2d(): MutableMatrix2d {
|
||||
return MutableMatrix2d(
|
||||
c00.toDouble(), c01.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4f],
|
||||
* setting last two columns and rows to 0
|
||||
*/
|
||||
fun toMatrix4f(): Matrix4f {
|
||||
return Matrix4f(
|
||||
c00, c01, 0f, 0f,
|
||||
c10, c11, 0f, 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3f],
|
||||
* setting last column and row to 0
|
||||
*/
|
||||
fun toMatrix3f(): Matrix3f {
|
||||
return Matrix3f(
|
||||
c00, c01, 0f,
|
||||
c10, c11, 0f,
|
||||
0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2f],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMatrix2f(): Matrix2f {
|
||||
return Matrix2f(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4f],
|
||||
* setting last two columns and rows to 0,
|
||||
*/
|
||||
fun toMutableMatrix4f(): MutableMatrix4f {
|
||||
return MutableMatrix4f(
|
||||
c00, c01, 0f, 0f,
|
||||
c10, c11, 0f, 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3f],
|
||||
* setting last column and row to 0,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix3f(): MutableMatrix3f {
|
||||
return MutableMatrix3f(
|
||||
c00, c01, 0f,
|
||||
c10, c11, 0f,
|
||||
0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2f],
|
||||
* truncating last row and column,
|
||||
* casing all [Double]s to [Float]s
|
||||
*/
|
||||
fun toMutableMatrix2f(): MutableMatrix2f {
|
||||
return MutableMatrix2f(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,6 +236,152 @@ interface IMatrix3f<T : IMatrix3f<T>> : IMatrix<T>, IFloatMatrix<T>, ITransposab
|
||||
val r2: Vector3f
|
||||
|
||||
override val translation: Vector2f get() = Vector2f(r02, r12)
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4d],
|
||||
* setting last row and column to 0,
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMatrix4d(): Matrix4d {
|
||||
return Matrix4d(
|
||||
c00.toDouble(), c01.toDouble(), c02.toDouble(), 0.0,
|
||||
c10.toDouble(), c11.toDouble(), c12.toDouble(), 0.0,
|
||||
c20.toDouble(), c21.toDouble(), c22.toDouble(), 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3d],
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMatrix3d(): Matrix3d {
|
||||
return Matrix3d(
|
||||
c00.toDouble(), c01.toDouble(), c02.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(), c12.toDouble(),
|
||||
c20.toDouble(), c21.toDouble(), c22.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2d],
|
||||
* truncating last row and column,
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMatrix2d(): Matrix2d {
|
||||
return Matrix2d(
|
||||
c00.toDouble(), c01.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4d],
|
||||
* setting last column and row to 0,
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMutableMatrix4d(): MutableMatrix4d {
|
||||
return MutableMatrix4d(
|
||||
c00.toDouble(), c01.toDouble(), c02.toDouble(), 0.0,
|
||||
c10.toDouble(), c11.toDouble(), c12.toDouble(), 0.0,
|
||||
c20.toDouble(), c21.toDouble(), c22.toDouble(), 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3d],
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMutableMatrix3d(): MutableMatrix3d {
|
||||
return MutableMatrix3d(
|
||||
c00.toDouble(), c01.toDouble(), c02.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(), c12.toDouble(),
|
||||
c20.toDouble(), c21.toDouble(), c22.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2d],
|
||||
* truncating last row and column,
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMutableMatrix2d(): MutableMatrix2d {
|
||||
return MutableMatrix2d(
|
||||
c00.toDouble(), c01.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4f],
|
||||
* setting last column and row to 0
|
||||
*/
|
||||
fun toMatrix4f(): Matrix4f {
|
||||
return Matrix4f(
|
||||
c00, c01, c02, 0f,
|
||||
c10, c11, c12, 0f,
|
||||
c20, c21, c22, 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3f]
|
||||
*/
|
||||
fun toMatrix3f(): Matrix3f {
|
||||
return Matrix3f(
|
||||
c00, c01, c02,
|
||||
c10, c11, c12,
|
||||
c20, c21, c22,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2f],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMatrix2f(): Matrix2f {
|
||||
return Matrix2f(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4f],
|
||||
* setting last column and row to 0
|
||||
*/
|
||||
fun toMutableMatrix4f(): MutableMatrix4f {
|
||||
return MutableMatrix4f(
|
||||
c00, c01, c02, 0f,
|
||||
c10, c11, c12, 0f,
|
||||
c20, c21, c22, 0f,
|
||||
0f, 0f, 0f, 0f,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3f]
|
||||
*/
|
||||
fun toMutableMatrix3f(): MutableMatrix3f {
|
||||
return MutableMatrix3f(
|
||||
c00, c01, c02,
|
||||
c10, c11, c12,
|
||||
c20, c21, c22,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2f],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMutableMatrix2f(): MutableMatrix2f {
|
||||
return MutableMatrix2f(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,4 +462,148 @@ interface IMatrix4f<T : IMatrix4f<T>> : IMatrix<T>, IFloatMatrix<T>, ITransposab
|
||||
val r3: Vector4f
|
||||
|
||||
override val translation: Vector3f get() = Vector3f(r03, r13, r23)
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4d],
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMatrix4d(): Matrix4d {
|
||||
return Matrix4d(
|
||||
c00.toDouble(), c01.toDouble(), c02.toDouble(), c03.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(), c12.toDouble(), c13.toDouble(),
|
||||
c20.toDouble(), c21.toDouble(), c22.toDouble(), c23.toDouble(),
|
||||
c30.toDouble(), c31.toDouble(), c32.toDouble(), c33.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3d],
|
||||
* truncating last row and column,
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMatrix3d(): Matrix3d {
|
||||
return Matrix3d(
|
||||
c00.toDouble(), c01.toDouble(), c02.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(), c12.toDouble(),
|
||||
c20.toDouble(), c21.toDouble(), c22.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2d],
|
||||
* truncating two last rows and columns,
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMatrix2d(): Matrix2d {
|
||||
return Matrix2d(
|
||||
c00.toDouble(), c01.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4d],
|
||||
* casting all [Float]s to [Double]s
|
||||
*/
|
||||
fun toMutableMatrix4d(): MutableMatrix4d {
|
||||
return MutableMatrix4d(
|
||||
c00.toDouble(), c01.toDouble(), c02.toDouble(), c03.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(), c12.toDouble(), c13.toDouble(),
|
||||
c20.toDouble(), c21.toDouble(), c22.toDouble(), c23.toDouble(),
|
||||
c30.toDouble(), c31.toDouble(), c32.toDouble(), c33.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3d],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMutableMatrix3d(): MutableMatrix3d {
|
||||
return MutableMatrix3d(
|
||||
c00.toDouble(), c01.toDouble(), c02.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(), c12.toDouble(),
|
||||
c20.toDouble(), c21.toDouble(), c22.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2d],
|
||||
* truncating two last rows and columns
|
||||
*/
|
||||
fun toMutableMatrix2d(): MutableMatrix2d {
|
||||
return MutableMatrix2d(
|
||||
c00.toDouble(), c01.toDouble(),
|
||||
c10.toDouble(), c11.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix4f]
|
||||
*/
|
||||
fun toMatrix4f(): Matrix4f {
|
||||
return Matrix4f(
|
||||
c00, c01, c02, c03,
|
||||
c10, c11, c12, c13,
|
||||
c20, c21, c22, c23,
|
||||
c30, c31, c32, c33,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix3f],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMatrix3f(): Matrix3f {
|
||||
return Matrix3f(
|
||||
c00, c01, c02,
|
||||
c10, c11, c12,
|
||||
c20, c21, c22,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [Matrix2f],
|
||||
* truncating two last rows and columns
|
||||
*/
|
||||
fun toMatrix2f(): Matrix2f {
|
||||
return Matrix2f(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix4f]
|
||||
*/
|
||||
fun toMutableMatrix4f(): MutableMatrix4f {
|
||||
return MutableMatrix4f(
|
||||
c00, c01, c02, c03,
|
||||
c10, c11, c12, c13,
|
||||
c20, c21, c22, c23,
|
||||
c30, c31, c32, c33,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix3f],
|
||||
* truncating last row and column
|
||||
*/
|
||||
fun toMutableMatrix3f(): MutableMatrix3f {
|
||||
return MutableMatrix3f(
|
||||
c00, c01, c02,
|
||||
c10, c11, c12,
|
||||
c20, c21, c22,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this matrix as [MutableMatrix2f],
|
||||
* truncating two last rows and columns
|
||||
*/
|
||||
fun toMutableMatrix2f(): MutableMatrix2f {
|
||||
return MutableMatrix2f(
|
||||
c00, c01,
|
||||
c10, c11,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -316,14 +316,16 @@ private fun load(matrix: IMatrixGetterLong, buffers: Array<Long2Dimensional>): L
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs new complement matrix from [input] representing square matrix, by taking out [column] and [row], and load result into [buffer].
|
||||
* Constructs new complement matrix from [input] representing square matrix,
|
||||
* by taking out [column] and [row], and load result into [buffer].
|
||||
*
|
||||
* @throws IllegalArgumentException if [column] or [row] is out of bounds, or if [input] does not represent a square matrix
|
||||
* @throws IllegalArgumentException if [column] or [row] is out of bounds,
|
||||
* or if [input] does not represent a square matrix
|
||||
*
|
||||
* @return [buffer]
|
||||
*/
|
||||
fun complementMatrix(input: IMatrixGetterDouble, column: Int, row: Int, buffer: Double2Dimensional): Double2Dimensional {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.rows} rows, ${input.columns} columns)" }
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
require(column < input.columns) { "$column < ${input.columns}" }
|
||||
require(row < input.rows) { "$row < ${input.rows}" }
|
||||
|
||||
@ -349,14 +351,16 @@ fun complementMatrix(input: IMatrixGetterDouble, column: Int, row: Int, buffer:
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs new complement matrix from [input] representing square matrix, by taking out [column] and [row], and load result into [buffer].
|
||||
* Constructs new complement matrix from [input] representing square matrix,
|
||||
* by taking out [column] and [row], and load result into [buffer].
|
||||
*
|
||||
* @throws IllegalArgumentException if [column] or [row] is out of bounds, or if [input] does not represent a square matrix
|
||||
* @throws IllegalArgumentException if [column] or [row] is out of bounds,
|
||||
* or if [input] does not represent a square matrix
|
||||
*
|
||||
* @return [buffer]
|
||||
*/
|
||||
fun complementMatrix(input: IMatrixGetterFloat, column: Int, row: Int, buffer: Float2Dimensional): Float2Dimensional {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.rows} rows, ${input.columns} columns)" }
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
require(column < input.columns) { "$column < ${input.columns}" }
|
||||
require(row < input.rows) { "$row < ${input.rows}" }
|
||||
|
||||
@ -382,14 +386,16 @@ fun complementMatrix(input: IMatrixGetterFloat, column: Int, row: Int, buffer: F
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs new complement matrix from [input] representing square matrix, by taking out [column] and [row], and load result into [buffer].
|
||||
* Constructs new complement matrix from [input] representing square matrix,
|
||||
* by taking out [column] and [row], and load result into [buffer].
|
||||
*
|
||||
* @throws IllegalArgumentException if [column] or [row] is out of bounds, or if [input] does not represent a square matrix
|
||||
* @throws IllegalArgumentException if [column] or [row] is out of bounds,
|
||||
* or if [input] does not represent a square matrix
|
||||
*
|
||||
* @return [buffer]
|
||||
*/
|
||||
fun complementMatrix(input: IMatrixGetterInt, column: Int, row: Int, buffer: Int2Dimensional): Int2Dimensional {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.rows} rows, ${input.columns} columns)" }
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
require(column < input.columns) { "$column < ${input.columns}" }
|
||||
require(row < input.rows) { "$row < ${input.rows}" }
|
||||
|
||||
@ -415,14 +421,16 @@ fun complementMatrix(input: IMatrixGetterInt, column: Int, row: Int, buffer: Int
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs new complement matrix from [input] representing square matrix, by taking out [column] and [row], and load result into [buffer].
|
||||
* Constructs new complement matrix from [input] representing square matrix,
|
||||
* by taking out [column] and [row], and load result into [buffer].
|
||||
*
|
||||
* @throws IllegalArgumentException if [column] or [row] is out of bounds, or if [input] does not represent a square matrix
|
||||
* @throws IllegalArgumentException if [column] or [row] is out of bounds,
|
||||
* or if [input] does not represent a square matrix
|
||||
*
|
||||
* @return [buffer]
|
||||
*/
|
||||
fun complementMatrix(input: IMatrixGetterLong, column: Int, row: Int, buffer: Long2Dimensional): Long2Dimensional {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.rows} rows, ${input.columns} columns)" }
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
require(column < input.columns) { "$column < ${input.columns}" }
|
||||
require(row < input.rows) { "$row < ${input.rows}" }
|
||||
|
||||
@ -447,7 +455,184 @@ fun complementMatrix(input: IMatrixGetterLong, column: Int, row: Int, buffer: Lo
|
||||
return buffer
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes cofactor matrix of specified square matrix [input],
|
||||
* returning result as [Double2Dimensional]
|
||||
*
|
||||
* This operation requires n * n determinant calculations of matrix,
|
||||
* so do cache result of this function in performance critical context.
|
||||
*
|
||||
* @throws IllegalArgumentException if provided [input] is not a square matrix
|
||||
* @return 2d array containing result matrix
|
||||
*/
|
||||
fun cofactorMatrix(input: IMatrixGetterDouble): Double2Dimensional {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
|
||||
if (input.rows == 1) {
|
||||
return Double2Dimensional(1, 1).also { it[0, 0] = input[0, 0] }
|
||||
} else if (input.rows == 2) {
|
||||
return Double2Dimensional(2, 2).also {
|
||||
it[0, 0] = input[1, 1]
|
||||
it[1, 0] = -input[1, 0]
|
||||
it[0, 1] = -input[0, 1]
|
||||
it[1, 1] = input[0, 0]
|
||||
}
|
||||
}
|
||||
|
||||
val result = Double2Dimensional(input.columns, input.rows)
|
||||
val buffers = Array(input.rows) { Double2Dimensional(it + 1, it + 1) }
|
||||
|
||||
for (column in 0 until input.columns) {
|
||||
for (row in 0 until input.rows) {
|
||||
val minor = matrixDeterminant(complementMatrix(input, column, row, buffers[input.columns - 2]), input.columns - 1, buffers)
|
||||
val cofactor = (-1.0).pow(row + column) * minor
|
||||
result[column, row] = cofactor
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes cofactor matrix of specified square matrix [input],
|
||||
* returning result as [Float2Dimensional]
|
||||
*
|
||||
* This operation requires n * n determinant calculations of matrix,
|
||||
* so do cache result of this function in performance critical context.
|
||||
*
|
||||
* @throws IllegalArgumentException if provided [input] is not a square matrix
|
||||
* @return 2d array containing result matrix
|
||||
*/
|
||||
fun cofactorMatrix(input: IMatrixGetterFloat): Float2Dimensional {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
|
||||
if (input.rows == 1) {
|
||||
return Float2Dimensional(1, 1).also { it[0, 0] = input[0, 0] }
|
||||
} else if (input.rows == 2) {
|
||||
return Float2Dimensional(2, 2).also {
|
||||
it[0, 0] = input[1, 1]
|
||||
it[1, 0] = -input[1, 0]
|
||||
it[0, 1] = -input[0, 1]
|
||||
it[1, 1] = input[0, 0]
|
||||
}
|
||||
}
|
||||
|
||||
val result = Float2Dimensional(input.columns, input.rows)
|
||||
val buffers = Array(input.rows) { Float2Dimensional(it + 1, it + 1) }
|
||||
|
||||
for (column in 0 until input.columns) {
|
||||
for (row in 0 until input.rows) {
|
||||
val minor = matrixDeterminant(complementMatrix(input, column, row, buffers[input.columns - 2]), input.columns - 1, buffers)
|
||||
val cofactor = (-1f).pow(row + column) * minor
|
||||
result[column, row] = cofactor
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes adjugate matrix of specified square matrix [input],
|
||||
* returning result as [Double2Dimensional],
|
||||
*
|
||||
* [https://en.wikipedia.org/wiki/Adjugate_matrix]
|
||||
*
|
||||
* This operation requires n * n determinant calculations of matrix,
|
||||
* so do cache result of this function in performance critical context.
|
||||
*
|
||||
* @throws IllegalArgumentException if provided [input] is not a square matrix
|
||||
* @return 2d array containing result matrix
|
||||
*/
|
||||
fun adjugateMatrix(input: IMatrixGetterDouble): Double2Dimensional {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
return transposeMatrix(cofactorMatrix(input))
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes adjugate matrix of specified square matrix [input],
|
||||
* returning result as [Float2Dimensional],
|
||||
*
|
||||
* [https://en.wikipedia.org/wiki/Adjugate_matrix]
|
||||
*
|
||||
* This operation requires n * n determinant calculations of matrix,
|
||||
* so do cache result of this function in performance critical context.
|
||||
*
|
||||
* @throws IllegalArgumentException if provided [input] is not a square matrix
|
||||
* @return 2d array containing result matrix
|
||||
*/
|
||||
fun adjugateMatrix(input: IMatrixGetterFloat): Float2Dimensional {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
return transposeMatrix(cofactorMatrix(input))
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes inverse matrix of specified square matrix [input],
|
||||
* returning result as [Double2Dimensional],
|
||||
*
|
||||
* This operation requires 1 + n * n determinant calculations of original matrix,
|
||||
* so do cache result of this function in performance critical context.
|
||||
*
|
||||
* If determinant is zero, null is returned.
|
||||
*
|
||||
* @throws IllegalArgumentException if provided [input] is not a square matrix
|
||||
* @return 2d array containing result matrix, or null if determinant is zero.
|
||||
*/
|
||||
fun inverseMatrix(input: IMatrixGetterDouble): Double2Dimensional? {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
|
||||
var determinant = matrixDeterminant(input)
|
||||
|
||||
if (determinant == 0.0)
|
||||
return null
|
||||
|
||||
determinant = 1.0 / determinant
|
||||
val adjugate = adjugateMatrix(input)
|
||||
|
||||
for (column in 0 until input.columns) {
|
||||
for (row in 0 until input.rows) {
|
||||
adjugate[column, row] *= determinant
|
||||
}
|
||||
}
|
||||
|
||||
return adjugate
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes inverse matrix of specified square matrix [input],
|
||||
* returning result as [Float2Dimensional],
|
||||
*
|
||||
* This operation requires 1 + n * n determinant calculations of original matrix,
|
||||
* so do cache result of this function in performance critical context.
|
||||
*
|
||||
* If determinant is zero, null is returned.
|
||||
*
|
||||
* @throws IllegalArgumentException if provided [input] is not a square matrix
|
||||
* @return 2d array containing result matrix, or null if determinant is zero.
|
||||
*/
|
||||
fun inverseMatrix(input: IMatrixGetterFloat): Float2Dimensional? {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
|
||||
var determinant = matrixDeterminant(input)
|
||||
|
||||
if (determinant == 0f)
|
||||
return null
|
||||
|
||||
determinant = 1f / determinant
|
||||
val adjugate = adjugateMatrix(input)
|
||||
|
||||
for (column in 0 until input.columns) {
|
||||
for (row in 0 until input.rows) {
|
||||
adjugate[column, row] *= determinant
|
||||
}
|
||||
}
|
||||
|
||||
return adjugate
|
||||
}
|
||||
|
||||
private fun matrixDeterminant(input: Double2Dimensional, size: Int, buffers: Array<Double2Dimensional>): Double {
|
||||
if (input.rows == 1)
|
||||
return input[0, 0]
|
||||
|
||||
val concrete = matrixConcreteDeterminant(input)
|
||||
|
||||
if (concrete != null) {
|
||||
@ -468,19 +653,19 @@ private fun matrixDeterminant(input: Double2Dimensional, size: Int, buffers: Arr
|
||||
/**
|
||||
* Recursive determinant finder of specified structure representing square matrix.
|
||||
*
|
||||
* @throws IllegalArgumentException if [matrix] structure is not square matrix
|
||||
* @throws IllegalArgumentException if [input] structure is not square matrix
|
||||
*/
|
||||
fun matrixDeterminant(matrix: IMatrixGetterDouble): Double {
|
||||
require(matrix.rows == matrix.columns) { "Provided matrix is not square matrix (${matrix.rows} rows, ${matrix.columns} columns)" }
|
||||
fun matrixDeterminant(input: IMatrixGetterDouble): Double {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
|
||||
val concrete = matrixConcreteDeterminant(matrix)
|
||||
val concrete = matrixConcreteDeterminant(input)
|
||||
|
||||
if (concrete != null) {
|
||||
return concrete
|
||||
}
|
||||
|
||||
val buffers = Array(matrix.rows) { Double2Dimensional(it + 1, it + 1) }
|
||||
return matrixDeterminant(load(matrix, buffers), matrix.columns, buffers)
|
||||
val buffers = Array(input.rows) { Double2Dimensional(it + 1, it + 1) }
|
||||
return matrixDeterminant(load(input, buffers), input.columns, buffers)
|
||||
}
|
||||
|
||||
private fun matrixDeterminant(input: Float2Dimensional, size: Int, buffers: Array<Float2Dimensional>): Float {
|
||||
@ -504,18 +689,18 @@ private fun matrixDeterminant(input: Float2Dimensional, size: Int, buffers: Arra
|
||||
/**
|
||||
* Recursive determinant finder of specified structure representing square matrix.
|
||||
*
|
||||
* @throws IllegalArgumentException if [matrix] structure is not square matrix
|
||||
* @throws IllegalArgumentException if [input] structure is not square matrix
|
||||
*/
|
||||
fun matrixDeterminant(matrix: IMatrixGetterFloat): Float {
|
||||
require(matrix.rows == matrix.columns) { "Provided matrix is not square matrix (${matrix.rows} rows, ${matrix.columns} columns)" }
|
||||
fun matrixDeterminant(input: IMatrixGetterFloat): Float {
|
||||
require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" }
|
||||
|
||||
val concrete = matrixConcreteDeterminant(matrix)
|
||||
val concrete = matrixConcreteDeterminant(input)
|
||||
|
||||
if (concrete != null) {
|
||||
return concrete
|
||||
}
|
||||
|
||||
val buffers = Array(matrix.rows) { Float2Dimensional(it + 1, it + 1) }
|
||||
return matrixDeterminant(load(matrix, buffers), matrix.columns, buffers).toFloat()
|
||||
val buffers = Array(input.rows) { Float2Dimensional(it + 1, it + 1) }
|
||||
return matrixDeterminant(load(input, buffers), input.columns, buffers).toFloat()
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,8 @@
|
||||
package ru.dbotthepony.kvector.matrix.ndouble
|
||||
|
||||
import ru.dbotthepony.kvector.api.*
|
||||
import ru.dbotthepony.kvector.matrix.*
|
||||
import ru.dbotthepony.kvector.matrix.generated.MultiplicationsDouble
|
||||
import ru.dbotthepony.kvector.matrix.matrixDeterminant
|
||||
import ru.dbotthepony.kvector.matrix.multiplyMatrix
|
||||
import ru.dbotthepony.kvector.matrix.transposeMatrix
|
||||
import ru.dbotthepony.kvector.narray.Double2Dimensional
|
||||
|
||||
private fun checkRows(value: Int): Int {
|
||||
@ -153,6 +151,31 @@ abstract class AbstractMatrixVd<T : AbstractMatrixVd<T>> protected constructor(
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override val inverse: T?
|
||||
get() {
|
||||
if (!isSquareMatrix)
|
||||
return null
|
||||
|
||||
val result = inverseMatrix(memory) ?: return null
|
||||
return factorize(result)
|
||||
}
|
||||
|
||||
override val cofactor: T?
|
||||
get() {
|
||||
if (!isSquareMatrix)
|
||||
return null
|
||||
|
||||
return factorize(cofactorMatrix(memory))
|
||||
}
|
||||
|
||||
override val adjugate: T?
|
||||
get() {
|
||||
if (!isSquareMatrix)
|
||||
return null
|
||||
|
||||
return factorize(adjugateMatrix(memory))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,10 +4,8 @@
|
||||
package ru.dbotthepony.kvector.matrix.nfloat
|
||||
|
||||
import ru.dbotthepony.kvector.api.*
|
||||
import ru.dbotthepony.kvector.matrix.*
|
||||
import ru.dbotthepony.kvector.matrix.generated.MultiplicationsFloat
|
||||
import ru.dbotthepony.kvector.matrix.matrixDeterminant
|
||||
import ru.dbotthepony.kvector.matrix.multiplyMatrix
|
||||
import ru.dbotthepony.kvector.matrix.transposeMatrix
|
||||
import ru.dbotthepony.kvector.narray.Float2Dimensional
|
||||
|
||||
private fun checkRows(value: Int): Int {
|
||||
@ -153,6 +151,31 @@ abstract class AbstractMatrixVf<T : AbstractMatrixVf<T>> protected constructor(
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override val inverse: T?
|
||||
get() {
|
||||
if (!isSquareMatrix)
|
||||
return null
|
||||
|
||||
val result = inverseMatrix(memory) ?: return null
|
||||
return factorize(result)
|
||||
}
|
||||
|
||||
override val cofactor: T?
|
||||
get() {
|
||||
if (!isSquareMatrix)
|
||||
return null
|
||||
|
||||
return factorize(cofactorMatrix(memory))
|
||||
}
|
||||
|
||||
override val adjugate: T?
|
||||
get() {
|
||||
if (!isSquareMatrix)
|
||||
return null
|
||||
|
||||
return factorize(adjugateMatrix(memory))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,50 +0,0 @@
|
||||
package ru.dbotthepony.kstarbound.math
|
||||
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
interface IAngle {
|
||||
val pitch: Double
|
||||
val yaw: Double
|
||||
val roll: Double
|
||||
|
||||
fun matrixX(): Matrix4f {
|
||||
val s = sin(pitch).toFloat()
|
||||
val c = cos(pitch).toFloat()
|
||||
|
||||
return Matrix4f(
|
||||
m11 = c, m12 = -s,
|
||||
m21 = s, m22 = c,
|
||||
)
|
||||
}
|
||||
|
||||
fun matrixY(): Matrix4f {
|
||||
val s = sin(yaw).toFloat()
|
||||
val c = cos(yaw).toFloat()
|
||||
|
||||
return Matrix4f(
|
||||
m00 = c, m02 = s,
|
||||
m20 = -s, m22 = c
|
||||
)
|
||||
}
|
||||
|
||||
fun matrixZ(): Matrix4f {
|
||||
val s = sin(roll).toFloat()
|
||||
val c = cos(roll).toFloat()
|
||||
|
||||
return Matrix4f(
|
||||
m00 = c, m01 = -s,
|
||||
m10 = s, m11 = c
|
||||
)
|
||||
}
|
||||
|
||||
fun matrixXYZ(): Matrix4f {
|
||||
return matrixX() * matrixY() * matrixZ()
|
||||
}
|
||||
}
|
||||
|
||||
data class Angle(
|
||||
override val pitch: Double = 0.0,
|
||||
override val yaw: Double = 0.0,
|
||||
override val roll: Double = 0.0,
|
||||
) : IAngle
|
@ -7,9 +7,9 @@ import ru.dbotthepony.kstarbound.world.CHUNK_SIZE
|
||||
import ru.dbotthepony.kstarbound.world.CHUNK_SIZE_FF
|
||||
import ru.dbotthepony.kstarbound.world.CHUNK_SIZEd
|
||||
import ru.dbotthepony.kstarbound.world.ChunkPos
|
||||
import ru.dbotthepony.kvector.matrix.matrixDeterminant
|
||||
import ru.dbotthepony.kvector.matrix.adjugateMatrix
|
||||
import ru.dbotthepony.kvector.matrix.multiplyMatrix
|
||||
import ru.dbotthepony.kvector.matrix.generated.*
|
||||
import ru.dbotthepony.kvector.matrix.inverseMatrix
|
||||
import ru.dbotthepony.kvector.narray.Double2Dimensional
|
||||
|
||||
object MathTests {
|
||||
@ -155,30 +155,4 @@ object MathTests {
|
||||
check(product[1, 1] == 96.0)
|
||||
check(product[2, 1] == 26.0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAlloc() {
|
||||
System.gc()
|
||||
|
||||
var t = System.currentTimeMillis()
|
||||
var escape2 = 0.0
|
||||
|
||||
for (i in 0 .. 8000000) {
|
||||
val matrix = Matrix4d()
|
||||
escape2 += matrix[2, 3]
|
||||
}
|
||||
|
||||
println(System.currentTimeMillis() - t)
|
||||
System.gc()
|
||||
t = System.currentTimeMillis()
|
||||
var escape = 0.0
|
||||
|
||||
for (i in 0 .. 8000000) {
|
||||
val matrix = Double2Dimensional(4, 4)
|
||||
escape += matrix[2, 3]
|
||||
}
|
||||
|
||||
println(System.currentTimeMillis() - t)
|
||||
println(escape)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user