bgc-net/BGC/F64Matrix3x3.cs

528 lines
19 KiB
C#

/*
* Copyright 2019-2025 Andrey Pokidov <andrey.pokidov@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
/*
* Author: Andrey Pokidov
* Date: 10 Feb 2019
*/
namespace BGC
{
public struct F64Matrix3x3
{
public double r1c1, r1c2, r1c3;
public double r2c1, r2c2, r2c3;
public double r3c1, r3c2, r3c3;
public F64Matrix3x3()
{
this.r1c1 = 0.0;
this.r1c2 = 0.0;
this.r1c3 = 0.0;
this.r2c1 = 0.0;
this.r2c2 = 0.0;
this.r2c3 = 0.0;
this.r3c1 = 0.0;
this.r3c2 = 0.0;
this.r3c3 = 0.0;
}
public F64Matrix3x3(double d1, double d2, double d3)
{
this.r1c1 = d1;
this.r1c2 = 0.0;
this.r1c3 = 0.0;
this.r2c1 = 0.0;
this.r2c2 = d2;
this.r2c3 = 0.0;
this.r3c1 = 0.0;
this.r3c2 = 0.0;
this.r3c3 = d3;
}
public F64Matrix3x3(in F64Matrix3x3 matrix)
{
this.r1c1 = matrix.r1c1;
this.r1c2 = matrix.r1c2;
this.r1c3 = matrix.r1c3;
this.r2c1 = matrix.r2c1;
this.r2c2 = matrix.r2c2;
this.r2c3 = matrix.r2c3;
this.r3c1 = matrix.r3c1;
this.r3c2 = matrix.r3c2;
this.r3c3 = matrix.r3c3;
}
public F64Matrix3x3(in F32Matrix3x3 matrix)
{
this.r1c1 = matrix.r1c1;
this.r1c2 = matrix.r1c2;
this.r1c3 = matrix.r1c3;
this.r2c1 = matrix.r2c1;
this.r2c2 = matrix.r2c2;
this.r2c3 = matrix.r2c3;
this.r3c1 = matrix.r3c1;
this.r3c2 = matrix.r3c2;
this.r3c3 = matrix.r3c3;
}
public readonly double GetDeterminant()
{
return this.r1c1 * (this.r2c2 * this.r3c3 - this.r2c3 * this.r3c2)
+ this.r1c2 * (this.r2c3 * this.r3c1 - this.r2c1 * this.r3c3)
+ this.r1c3 * (this.r2c1 * this.r3c2 - this.r2c2 * this.r3c1);
}
public readonly bool IsSingular()
{
double determinant = this.GetDeterminant();
return -F64Utility.EPSYLON <= determinant && determinant <= F64Utility.EPSYLON;
}
public void Transpose()
{
(this.r1c2, this.r2c1) = (this.r2c1, this.r1c2);
(this.r1c3, this.r3c1) = (this.r3c1, this.r1c3);
(this.r2c3, this.r3c2) = (this.r3c2, this.r2c3);
}
public bool Invert()
{
double determinant = this.GetDeterminant();
if (-F64Utility.EPSYLON <= determinant && determinant <= F64Utility.EPSYLON) {
return false;
}
double r1c1 = this.r2c2 * this.r3c3 - this.r2c3 * this.r3c2;
double r1c2 = this.r1c3 * this.r3c2 - this.r1c2 * this.r3c3;
double r1c3 = this.r1c2 * this.r2c3 - this.r1c3 * this.r2c2;
double r2c1 = this.r2c3 * this.r3c1 - this.r2c1 * this.r3c3;
double r2c2 = this.r1c1 * this.r3c3 - this.r1c3 * this.r3c1;
double r2c3 = this.r1c3 * this.r2c1 - this.r1c1 * this.r2c3;
double r3c1 = this.r2c1 * this.r3c2 - this.r2c2 * this.r3c1;
double r3c2 = this.r1c2 * this.r3c1 - this.r1c1 * this.r3c2;
double r3c3 = this.r1c1 * this.r2c2 - this.r1c2 * this.r2c1;
this.r1c1 = r1c1 / determinant;
this.r1c2 = r1c2 / determinant;
this.r1c3 = r1c3 / determinant;
this.r2c1 = r2c1 / determinant;
this.r2c2 = r2c2 / determinant;
this.r2c3 = r2c3 / determinant;
this.r3c1 = r3c1 / determinant;
this.r3c2 = r3c2 / determinant;
this.r3c3 = r3c3 / determinant;
return true;
}
public void Reset()
{
this.r1c1 = 0.0;
this.r1c2 = 0.0;
this.r1c3 = 0.0;
this.r2c1 = 0.0;
this.r2c2 = 0.0;
this.r2c3 = 0.0;
this.r3c1 = 0.0;
this.r3c2 = 0.0;
this.r3c3 = 0.0;
}
public void SetToIdentity()
{
this.r1c1 = 1.0;
this.r1c2 = 0.0;
this.r1c3 = 0.0;
this.r2c1 = 0.0;
this.r2c2 = 1.0;
this.r2c3 = 0.0;
this.r3c1 = 0.0;
this.r3c2 = 0.0;
this.r3c3 = 1.0;
}
public void SetToDiagonal(double d1, double d2, double d3)
{
this.r1c1 = d1;
this.r1c2 = 0.0;
this.r1c3 = 0.0;
this.r2c1 = 0.0;
this.r2c2 = d2;
this.r2c3 = 0.0;
this.r2c1 = 0.0;
this.r2c2 = 0.0;
this.r2c3 = d3;
}
public void SetValues(F64Matrix3x3 matrix)
{
this.r1c1 = matrix.r1c1;
this.r1c2 = matrix.r1c2;
this.r1c3 = matrix.r1c3;
this.r2c1 = matrix.r2c1;
this.r2c2 = matrix.r2c2;
this.r2c3 = matrix.r2c3;
this.r3c1 = matrix.r3c1;
this.r3c2 = matrix.r3c2;
this.r3c3 = matrix.r3c3;
}
public void SetValues(F32Matrix3x3 matrix)
{
this.r1c1 = matrix.r1c1;
this.r1c2 = matrix.r1c2;
this.r1c3 = matrix.r1c3;
this.r2c1 = matrix.r2c1;
this.r2c2 = matrix.r2c2;
this.r2c3 = matrix.r2c3;
this.r3c1 = matrix.r3c1;
this.r3c2 = matrix.r3c2;
this.r3c3 = matrix.r3c3;
}
public void SetTransposedOf(in F64Matrix3x3 matrix)
{
this.r1c1 = matrix.r1c1;
this.r2c2 = matrix.r2c2;
this.r3c3 = matrix.r3c3;
(this.r1c2, this.r2c1) = (matrix.r2c1, matrix.r1c2);
(this.r1c3, this.r3c1) = (matrix.r3c1, matrix.r1c3);
(this.r2c3, this.r3c2) = (matrix.r3c2, matrix.r2c3);
}
public void SetTransposedOf(in F32Matrix3x3 matrix)
{
this.r1c1 = matrix.r1c1;
this.r2c2 = matrix.r2c2;
this.r3c3 = matrix.r3c3;
(this.r1c2, this.r2c1) = (matrix.r2c1, matrix.r1c2);
(this.r1c3, this.r3c1) = (matrix.r3c1, matrix.r1c3);
(this.r2c3, this.r3c2) = (matrix.r3c2, matrix.r2c3);
}
public bool SetInvertedOf(in F64Matrix3x3 matrix)
{
double determinant = matrix.GetDeterminant();
if (-F64Utility.EPSYLON <= determinant && determinant <= F64Utility.EPSYLON) {
return false;
}
double r1c1 = matrix.r2c2 * matrix.r3c3 - matrix.r2c3 * matrix.r3c2;
double r1c2 = matrix.r1c3 * matrix.r3c2 - matrix.r1c2 * matrix.r3c3;
double r1c3 = matrix.r1c2 * matrix.r2c3 - matrix.r1c3 * matrix.r2c2;
double r2c1 = matrix.r2c3 * matrix.r3c1 - matrix.r2c1 * matrix.r3c3;
double r2c2 = matrix.r1c1 * matrix.r3c3 - matrix.r1c3 * matrix.r3c1;
double r2c3 = matrix.r1c3 * matrix.r2c1 - matrix.r1c1 * matrix.r2c3;
double r3c1 = matrix.r2c1 * matrix.r3c2 - matrix.r2c2 * matrix.r3c1;
double r3c2 = matrix.r1c2 * matrix.r3c1 - matrix.r1c1 * matrix.r3c2;
double r3c3 = matrix.r1c1 * matrix.r2c2 - matrix.r1c2 * matrix.r2c1;
this.r1c1 = r1c1 / determinant;
this.r1c2 = r1c2 / determinant;
this.r1c3 = r1c3 / determinant;
this.r2c1 = r2c1 / determinant;
this.r2c2 = r2c2 / determinant;
this.r2c3 = r2c3 / determinant;
this.r3c1 = r3c1 / determinant;
this.r3c2 = r3c2 / determinant;
this.r3c3 = r3c3 / determinant;
return true;
}
public void SetRow1(double c1, double c2, double c3)
{
this.r1c1 = c1;
this.r1c2 = c2;
this.r1c3 = c3;
}
public void SetRow2(double c1, double c2, double c3)
{
this.r2c1 = c1;
this.r2c2 = c2;
this.r2c3 = c3;
}
public void SetRow3(double c1, double c2, double c3)
{
this.r3c1 = c1;
this.r3c2 = c2;
this.r3c3 = c3;
}
public void SetColumn1(double r1, double r2, double r3)
{
this.r1c1 = r1;
this.r2c1 = r2;
this.r3c1 = r3;
}
public void SetColumn2(double r1, double r2, double r3)
{
this.r1c2 = r1;
this.r2c2 = r2;
this.r3c2 = r3;
}
public void SetColumn3(double r1, double r2, double r3)
{
this.r1c3 = r1;
this.r2c3 = r2;
this.r3c3 = r3;
}
public static void Add(in F64Matrix3x3 matrix1, in F64Matrix3x3 matrix2, out F64Matrix3x3 sum)
{
sum.r1c1 = matrix1.r1c1 + matrix2.r1c1;
sum.r1c2 = matrix1.r1c2 + matrix2.r1c2;
sum.r1c3 = matrix1.r1c3 + matrix2.r1c3;
sum.r2c1 = matrix1.r2c1 + matrix2.r2c1;
sum.r2c2 = matrix1.r2c2 + matrix2.r2c2;
sum.r2c3 = matrix1.r2c3 + matrix2.r2c3;
sum.r3c1 = matrix1.r3c1 + matrix2.r3c1;
sum.r3c2 = matrix1.r3c2 + matrix2.r3c2;
sum.r3c3 = matrix1.r3c3 + matrix2.r3c3;
}
public static void Subtract(in F64Matrix3x3 minuend, in F64Matrix3x3 subtrahend, out F64Matrix3x3 difference)
{
difference.r1c1 = minuend.r1c1 - subtrahend.r1c1;
difference.r1c2 = minuend.r1c2 - subtrahend.r1c2;
difference.r1c3 = minuend.r1c3 - subtrahend.r1c3;
difference.r2c1 = minuend.r2c1 - subtrahend.r2c1;
difference.r2c2 = minuend.r2c2 - subtrahend.r2c2;
difference.r2c3 = minuend.r2c3 - subtrahend.r2c3;
difference.r3c1 = minuend.r3c1 - subtrahend.r3c1;
difference.r3c2 = minuend.r3c2 - subtrahend.r3c2;
difference.r3c3 = minuend.r3c3 - subtrahend.r3c3;
}
public static void Multiply(in F64Matrix3x3 multiplicand, double multiplier, out F64Matrix3x3 product)
{
product.r1c1 = multiplicand.r1c1 * multiplier;
product.r1c2 = multiplicand.r1c2 * multiplier;
product.r1c3 = multiplicand.r1c3 * multiplier;
product.r2c1 = multiplicand.r2c1 * multiplier;
product.r2c2 = multiplicand.r2c2 * multiplier;
product.r2c3 = multiplicand.r2c3 * multiplier;
product.r3c1 = multiplicand.r3c1 * multiplier;
product.r3c2 = multiplicand.r3c2 * multiplier;
product.r3c3 = multiplicand.r3c3 * multiplier;
}
public static void Divide(in F64Matrix3x3 dividend, double divisor, out F64Matrix3x3 quotient)
{
quotient.r1c1 = dividend.r1c1 / divisor;
quotient.r1c2 = dividend.r1c2 / divisor;
quotient.r1c3 = dividend.r1c3 / divisor;
quotient.r2c1 = dividend.r2c1 / divisor;
quotient.r2c2 = dividend.r2c2 / divisor;
quotient.r2c3 = dividend.r2c3 / divisor;
quotient.r3c1 = dividend.r3c1 / divisor;
quotient.r3c2 = dividend.r3c2 / divisor;
quotient.r3c3 = dividend.r3c3 / divisor;
}
public static void GetWeightedSum2(
double weight1, in F64Matrix3x3 matrix1,
double weight2, in F64Matrix3x3 matrix2,
out F64Matrix3x3 sum)
{
sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2;
sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2;
sum.r1c3 = matrix1.r1c3 * weight1 + matrix2.r1c3 * weight2;
sum.r2c1 = matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2;
sum.r2c2 = matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2;
sum.r2c3 = matrix1.r2c3 * weight1 + matrix2.r2c3 * weight2;
sum.r3c1 = matrix1.r3c1 * weight1 + matrix2.r3c1 * weight2;
sum.r3c2 = matrix1.r3c2 * weight1 + matrix2.r3c2 * weight2;
sum.r3c3 = matrix1.r3c3 * weight1 + matrix2.r3c3 * weight2;
}
public static void GetWeightedSum3(
double weight1, in F64Matrix3x3 matrix1,
double weight2, in F64Matrix3x3 matrix2,
double weight3, in F64Matrix3x3 matrix3,
out F64Matrix3x3 sum)
{
sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2 + matrix3.r1c1 * weight3;
sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2 + matrix3.r1c2 * weight3;
sum.r1c3 = matrix1.r1c3 * weight1 + matrix2.r1c3 * weight2 + matrix3.r1c3 * weight3;
sum.r2c1 = matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2 + matrix3.r2c1 * weight3;
sum.r2c2 = matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2 + matrix3.r2c2 * weight3;
sum.r2c3 = matrix1.r2c3 * weight1 + matrix2.r2c3 * weight2 + matrix3.r2c3 * weight3;
sum.r3c1 = matrix1.r3c1 * weight1 + matrix2.r3c1 * weight2 + matrix3.r3c1 * weight3;
sum.r3c2 = matrix1.r3c2 * weight1 + matrix2.r3c2 * weight2 + matrix3.r3c2 * weight3;
sum.r3c3 = matrix1.r3c3 * weight1 + matrix2.r3c3 * weight2 + matrix3.r3c3 * weight3;
}
public static void GetWeightedSum4(
double weight1, in F64Matrix3x3 matrix1,
double weight2, in F64Matrix3x3 matrix2,
double weight3, in F64Matrix3x3 matrix3,
double weight4, in F64Matrix3x3 matrix4,
out F64Matrix3x3 sum)
{
sum.r1c1 = (matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2) + (matrix3.r1c1 * weight3 + matrix4.r1c1 * weight4);
sum.r1c2 = (matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2) + (matrix3.r1c2 * weight3 + matrix4.r1c2 * weight4);
sum.r1c3 = (matrix1.r1c3 * weight1 + matrix2.r1c3 * weight2) + (matrix3.r1c3 * weight3 + matrix4.r1c3 * weight4);
sum.r2c1 = (matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2) + (matrix3.r2c1 * weight3 + matrix4.r2c1 * weight4);
sum.r2c2 = (matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2) + (matrix3.r2c2 * weight3 + matrix4.r2c2 * weight4);
sum.r2c3 = (matrix1.r2c3 * weight1 + matrix2.r2c3 * weight2) + (matrix3.r2c3 * weight3 + matrix4.r2c3 * weight4);
sum.r3c1 = (matrix1.r3c1 * weight1 + matrix2.r3c1 * weight2) + (matrix3.r3c1 * weight3 + matrix4.r3c1 * weight4);
sum.r3c2 = (matrix1.r3c2 * weight1 + matrix2.r3c2 * weight2) + (matrix3.r3c2 * weight3 + matrix4.r3c2 * weight4);
sum.r3c3 = (matrix1.r3c3 * weight1 + matrix2.r3c3 * weight2) + (matrix3.r3c3 * weight3 + matrix4.r3c3 * weight4);
}
public static void GetWeightedSum5(
double weight1, in F64Matrix3x3 matrix1,
double weight2, in F64Matrix3x3 matrix2,
double weight3, in F64Matrix3x3 matrix3,
double weight4, in F64Matrix3x3 matrix4,
double weight5, in F64Matrix3x3 matrix5,
out F64Matrix3x3 sum)
{
sum.r1c1 = (matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2) + (matrix3.r1c1 * weight3 + matrix4.r1c1 * weight4) + matrix5.r1c1 * weight5;
sum.r1c2 = (matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2) + (matrix3.r1c2 * weight3 + matrix4.r1c2 * weight4) + matrix5.r1c2 * weight5;
sum.r1c3 = (matrix1.r1c3 * weight1 + matrix2.r1c3 * weight2) + (matrix3.r1c3 * weight3 + matrix4.r1c3 * weight4) + matrix5.r1c3 * weight5;
sum.r2c1 = (matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2) + (matrix3.r2c1 * weight3 + matrix4.r2c1 * weight4) + matrix5.r2c1 * weight5;
sum.r2c2 = (matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2) + (matrix3.r2c2 * weight3 + matrix4.r2c2 * weight4) + matrix5.r2c2 * weight5;
sum.r2c3 = (matrix1.r2c3 * weight1 + matrix2.r2c3 * weight2) + (matrix3.r2c3 * weight3 + matrix4.r2c3 * weight4) + matrix5.r2c3 * weight5;
sum.r3c1 = (matrix1.r3c1 * weight1 + matrix2.r3c1 * weight2) + (matrix3.r3c1 * weight3 + matrix4.r3c1 * weight4) + matrix5.r3c1 * weight5;
sum.r3c2 = (matrix1.r3c2 * weight1 + matrix2.r3c2 * weight2) + (matrix3.r3c2 * weight3 + matrix4.r3c2 * weight4) + matrix5.r3c2 * weight5;
sum.r3c3 = (matrix1.r3c3 * weight1 + matrix2.r3c3 * weight2) + (matrix3.r3c3 * weight3 + matrix4.r3c3 * weight4) + matrix5.r3c3 * weight5;
}
public static void GetRightProduct(in F64Matrix3x3 matrix, in F64Vector3 vector, out F64Vector3 result)
{
double x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2 + matrix.r1c3 * vector.x3;
double x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2 + matrix.r2c3 * vector.x3;
double x3 = matrix.r3c1 * vector.x1 + matrix.r3c2 * vector.x2 + matrix.r3c3 * vector.x3;
result.x1 = x1;
result.x2 = x2;
result.x3 = x3;
}
public static void GetLeftProduct(in F64Vector3 vector, in F64Matrix3x3 matrix, out F64Vector3 result)
{
double x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1 + vector.x3 * matrix.r3c1;
double x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2 + vector.x3 * matrix.r3c2;
double x3 = vector.x1 * matrix.r1c3 + vector.x2 * matrix.r2c3 + vector.x3 * matrix.r3c3;
result.x1 = x1;
result.x2 = x2;
result.x3 = x3;
}
public static void LoadZero(out F64Matrix3x3 matrix)
{
matrix.r1c1 = 0.0;
matrix.r1c2 = 0.0;
matrix.r1c3 = 0.0;
matrix.r2c1 = 0.0;
matrix.r2c2 = 0.0;
matrix.r2c3 = 0.0;
matrix.r3c1 = 0.0;
matrix.r3c2 = 0.0;
matrix.r3c3 = 0.0;
}
public static void LoadIdentity(out F64Matrix3x3 matrix)
{
matrix.r1c1 = 1.0;
matrix.r1c2 = 0.0;
matrix.r1c3 = 0.0;
matrix.r2c1 = 0.0;
matrix.r2c2 = 1.0;
matrix.r2c3 = 0.0;
matrix.r3c1 = 0.0;
matrix.r3c2 = 0.0;
matrix.r3c3 = 1.0;
}
public static void LoadDiagonal(double d1, double d2, double d3, out F64Matrix3x3 matrix)
{
matrix.r1c1 = d1;
matrix.r1c2 = 0.0;
matrix.r1c3 = 0.0;
matrix.r2c1 = 0.0;
matrix.r2c2 = d2;
matrix.r2c3 = 0.0;
matrix.r3c1 = 0.0;
matrix.r3c2 = 0.0;
matrix.r3c3 = d3;
}
}
}