From 72d06a23b2b2d0be83ab5971f8cd592230c05bbf Mon Sep 17 00:00:00 2001 From: Andrey Pokidov Date: Tue, 19 Nov 2024 00:44:50 +0700 Subject: [PATCH] =?UTF-8?q?=D0=91=D0=BE=D0=BB=D1=8C=D1=88=D0=BE=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=B8=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D1=80=D0=B5=D1=84=D0=B0?= =?UTF-8?q?=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3=20=D1=83=D0=B3=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20/=20Big=20renaming=20and=20refactoring=20of=20an?= =?UTF-8?q?gles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Geometry.Net.sln => BGC.Net.sln | 74 +- {Geometry => BGC}/Angle.cs | 96 +- Geometry/Geometry.csproj => BGC/BGC.csproj | 26 +- BGC/F32Angle.cs | 133 +++ BGC/F32Degrees.cs | 68 ++ .../SPMatrix2x2.cs => BGC/F32Matrix2x2.cs | 704 +++++------ .../SPMatrix2x3.cs => BGC/F32Matrix2x3.cs | 70 +- .../SPMatrix3x2.cs => BGC/F32Matrix3x2.cs | 70 +- .../SPMatrix3x3.cs => BGC/F32Matrix3x3.cs | 1064 ++++++++--------- .../F32MatrixProduct.cs | 20 +- .../SPQuaternion.cs => BGC/F32Quaternion.cs | 406 +++---- BGC/F32Radians.cs | 76 ++ .../SPRotation3.cs => BGC/F32Rotation3.cs | 8 +- BGC/F32Turns.cs | 63 + Geometry/SPUtility.cs => BGC/F32Utility.cs | 42 +- Geometry/SPVector2.cs => BGC/F32Vector2.cs | 154 +-- Geometry/SPVector3.cs => BGC/F32Vector3.cs | 160 +-- Geometry/SPVersor.cs => BGC/F32Versor.cs | 732 ++++++------ BGC/F64Angle.cs | 133 +++ BGC/F64Degrees.cs | 68 ++ .../DPMatrix2x2.cs => BGC/F64Matrix2x2.cs | 704 +++++------ .../DPMatrix2x3.cs => BGC/F64Matrix2x3.cs | 70 +- .../DPMatrix3x2.cs => BGC/F64Matrix3x2.cs | 70 +- .../DPMatrix3x3.cs => BGC/F64Matrix3x3.cs | 82 +- .../F64MatrixProduct.cs | 20 +- .../DPQuaternion.cs => BGC/F64Quaternion.cs | 408 +++---- BGC/F64Radians.cs | 75 ++ BGC/F64Turns.cs | 63 + Geometry/DPUtility.cs => BGC/F64Utility.cs | 40 +- Geometry/DPVector2.cs => BGC/F64Vector2.cs | 154 +-- Geometry/DPVector3.cs => BGC/F64Vector3.cs | 794 ++++++------ Geometry/DPVersor.cs => BGC/F64Versor.cs | 58 +- .../BGCDev.csproj | 28 +- {GeometryDev => BGCDev}/Program.cs | 158 +-- .../BGCTest.csproj | 36 +- .../F32Vector2Test.cs | 38 +- Geometry/DPAngle.cs | 305 ----- Geometry/SPAngle.cs | 306 ----- 38 files changed, 3819 insertions(+), 3757 deletions(-) rename Geometry.Net.sln => BGC.Net.sln (78%) rename {Geometry => BGC}/Angle.cs (94%) rename Geometry/Geometry.csproj => BGC/BGC.csproj (50%) create mode 100644 BGC/F32Angle.cs create mode 100644 BGC/F32Degrees.cs rename Geometry/SPMatrix2x2.cs => BGC/F32Matrix2x2.cs (75%) rename Geometry/SPMatrix2x3.cs => BGC/F32Matrix2x3.cs (81%) rename Geometry/SPMatrix3x2.cs => BGC/F32Matrix3x2.cs (81%) rename Geometry/SPMatrix3x3.cs => BGC/F32Matrix3x3.cs (85%) rename Geometry/SPMatrixProduct.cs => BGC/F32MatrixProduct.cs (87%) rename Geometry/SPQuaternion.cs => BGC/F32Quaternion.cs (77%) create mode 100644 BGC/F32Radians.cs rename Geometry/SPRotation3.cs => BGC/F32Rotation3.cs (88%) create mode 100644 BGC/F32Turns.cs rename Geometry/SPUtility.cs => BGC/F32Utility.cs (88%) rename Geometry/SPVector2.cs => BGC/F32Vector2.cs (60%) rename Geometry/SPVector3.cs => BGC/F32Vector3.cs (66%) rename Geometry/SPVersor.cs => BGC/F32Versor.cs (78%) create mode 100644 BGC/F64Angle.cs create mode 100644 BGC/F64Degrees.cs rename Geometry/DPMatrix2x2.cs => BGC/F64Matrix2x2.cs (75%) rename Geometry/DPMatrix2x3.cs => BGC/F64Matrix2x3.cs (81%) rename Geometry/DPMatrix3x2.cs => BGC/F64Matrix3x2.cs (81%) rename Geometry/DPMatrix3x3.cs => BGC/F64Matrix3x3.cs (87%) rename Geometry/DPMatrixProduct.cs => BGC/F64MatrixProduct.cs (87%) rename Geometry/DPQuaternion.cs => BGC/F64Quaternion.cs (77%) create mode 100644 BGC/F64Radians.cs create mode 100644 BGC/F64Turns.cs rename Geometry/DPUtility.cs => BGC/F64Utility.cs (89%) rename Geometry/DPVector2.cs => BGC/F64Vector2.cs (60%) rename Geometry/DPVector3.cs => BGC/F64Vector3.cs (64%) rename Geometry/DPVersor.cs => BGC/F64Versor.cs (81%) rename GeometryDev/GeometryDev.csproj => BGCDev/BGCDev.csproj (64%) rename {GeometryDev => BGCDev}/Program.cs (61%) rename GeometryTest/GeometryTest.csproj => BGCTest/BGCTest.csproj (78%) rename GeometryTest/Vector2FloatTest.cs => BGCTest/F32Vector2Test.cs (56%) delete mode 100644 Geometry/DPAngle.cs delete mode 100644 Geometry/SPAngle.cs diff --git a/Geometry.Net.sln b/BGC.Net.sln similarity index 78% rename from Geometry.Net.sln rename to BGC.Net.sln index 0ba42a8..e3c2cb2 100644 --- a/Geometry.Net.sln +++ b/BGC.Net.sln @@ -1,37 +1,37 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Geometry", "Geometry\Geometry.csproj", "{D1869DF0-7B61-4B6F-8C66-6EEF3916FE0A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeometryDev", "GeometryDev\GeometryDev.csproj", "{3D09FF57-02E6-449D-9DE7-0843633FCBA0}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeometryTest", "GeometryTest\GeometryTest.csproj", "{51A07B27-43FF-4A12-AEC1-50D32EDA3815}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D1869DF0-7B61-4B6F-8C66-6EEF3916FE0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D1869DF0-7B61-4B6F-8C66-6EEF3916FE0A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D1869DF0-7B61-4B6F-8C66-6EEF3916FE0A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D1869DF0-7B61-4B6F-8C66-6EEF3916FE0A}.Release|Any CPU.Build.0 = Release|Any CPU - {3D09FF57-02E6-449D-9DE7-0843633FCBA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3D09FF57-02E6-449D-9DE7-0843633FCBA0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3D09FF57-02E6-449D-9DE7-0843633FCBA0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3D09FF57-02E6-449D-9DE7-0843633FCBA0}.Release|Any CPU.Build.0 = Release|Any CPU - {51A07B27-43FF-4A12-AEC1-50D32EDA3815}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {51A07B27-43FF-4A12-AEC1-50D32EDA3815}.Debug|Any CPU.Build.0 = Debug|Any CPU - {51A07B27-43FF-4A12-AEC1-50D32EDA3815}.Release|Any CPU.ActiveCfg = Release|Any CPU - {51A07B27-43FF-4A12-AEC1-50D32EDA3815}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {040DE977-0DDC-4EEA-8EBC-CBCA41289BBE} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BGC", "BGC\BGC.csproj", "{D1869DF0-7B61-4B6F-8C66-6EEF3916FE0A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BGCDev", "BGCDev\BGCDev.csproj", "{3D09FF57-02E6-449D-9DE7-0843633FCBA0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BGCTest", "BGCTest\BGCTest.csproj", "{51A07B27-43FF-4A12-AEC1-50D32EDA3815}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D1869DF0-7B61-4B6F-8C66-6EEF3916FE0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1869DF0-7B61-4B6F-8C66-6EEF3916FE0A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1869DF0-7B61-4B6F-8C66-6EEF3916FE0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1869DF0-7B61-4B6F-8C66-6EEF3916FE0A}.Release|Any CPU.Build.0 = Release|Any CPU + {3D09FF57-02E6-449D-9DE7-0843633FCBA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D09FF57-02E6-449D-9DE7-0843633FCBA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D09FF57-02E6-449D-9DE7-0843633FCBA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D09FF57-02E6-449D-9DE7-0843633FCBA0}.Release|Any CPU.Build.0 = Release|Any CPU + {51A07B27-43FF-4A12-AEC1-50D32EDA3815}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51A07B27-43FF-4A12-AEC1-50D32EDA3815}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51A07B27-43FF-4A12-AEC1-50D32EDA3815}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51A07B27-43FF-4A12-AEC1-50D32EDA3815}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {040DE977-0DDC-4EEA-8EBC-CBCA41289BBE} + EndGlobalSection +EndGlobal diff --git a/Geometry/Angle.cs b/BGC/Angle.cs similarity index 94% rename from Geometry/Angle.cs rename to BGC/Angle.cs index 049296a..cc23133 100644 --- a/Geometry/Angle.cs +++ b/BGC/Angle.cs @@ -1,48 +1,48 @@ -/* - * Copyright 2019-2025 Andrey Pokidov - * - * 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. - */ - - -/* - * Author: Andrey Pokidov - * Date: 1 Feb 2019 - */ - -namespace Geometry -{ - public enum AngleUnit - { - RADIANS = 1, - DEGREES = 2, - TURNS = 3, - - } - - public enum AngleRange - { - /// - /// The measure of an angle with a range of: - /// [0, 360) degrees, [0, 2xPI) radians, [0, 1) turns, [0, 400) gradians - /// - UNSIGNED_RANGE = 1, - - /// - /// The measure of an angle with a range of: - /// (-180, 180] degrees, (-PI, PI] radians, (-0.5, 0.5] turns, (-200, 200] gradians - /// - SIGNED_RANGE = 2 - } -} - +/* + * Copyright 2019-2025 Andrey Pokidov + * + * 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. + */ + + +/* + * Author: Andrey Pokidov + * Date: 1 Feb 2019 + */ + +namespace BGC +{ + public enum AngleUnit + { + RADIANS = 1, + DEGREES = 2, + TURNS = 3, + + } + + public enum AngleRange + { + /// + /// The measure of an angle with a range of: + /// [0, 360) degrees, [0, 2xPI) radians, [0, 1) turns, [0, 400) gradians + /// + UNSIGNED_RANGE = 1, + + /// + /// The measure of an angle with a range of: + /// (-180, 180] degrees, (-PI, PI] radians, (-0.5, 0.5] turns, (-200, 200] gradians + /// + SIGNED_RANGE = 2 + } +} + diff --git a/Geometry/Geometry.csproj b/BGC/BGC.csproj similarity index 50% rename from Geometry/Geometry.csproj rename to BGC/BGC.csproj index ce126fc..0908648 100644 --- a/Geometry/Geometry.csproj +++ b/BGC/BGC.csproj @@ -1,16 +1,10 @@ - - - - net6.0 - enable - enable - - - - - - - - - - + + + + net6.0 + enable + enable + + + + diff --git a/BGC/F32Angle.cs b/BGC/F32Angle.cs new file mode 100644 index 0000000..b2420ba --- /dev/null +++ b/BGC/F32Angle.cs @@ -0,0 +1,133 @@ +/* + * Copyright 2019-2025 Andrey Pokidov + * + * 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: 1 Feb 2019 + */ + +namespace BGC +{ + public static class F32Angle + { + public static float ToRadians(float angle, AngleUnit unit) + { + if (unit == AngleUnit.DEGREES) + { + return angle * F32Degrees.RADIANS_IN_DEGREE; + } + + if (unit == AngleUnit.TURNS) + { + return angle * F32Radians.TWO_PI; + } + + return angle; + } + + public static float ToDegrees(float angle, AngleUnit unit) + { + if (unit == AngleUnit.RADIANS) + { + return angle * F32Radians.DEGREES_IN_RADIAN; + } + + if (unit == AngleUnit.TURNS) + { + return angle * 360.0f; + } + + return angle; + } + + public static float ToTurns(float angle, AngleUnit unit) + { + if (unit == AngleUnit.RADIANS) + { + return angle * F32Radians.TURNS_IN_RADIAN; + } + + if (unit == AngleUnit.DEGREES) + { + return angle * F32Degrees.TURNS_IN_DEGREE; + } + + return angle; + } + + public static float GetFullCircle(AngleUnit unit) + { + if (unit == AngleUnit.DEGREES) + { + return 360.0f; + } + + if (unit == AngleUnit.TURNS) + { + return 1.0f; + } + + return F32Radians.TWO_PI; + } + + public static float GetHalfCircle(AngleUnit unit) + { + if (unit == AngleUnit.DEGREES) + { + return 180.0f; + } + + if (unit == AngleUnit.TURNS) + { + return 0.5f; + } + + return F32Radians.PI; + } + + public static float GetQuarterCircle(AngleUnit unit) + { + if (unit == AngleUnit.DEGREES) + { + return 90.0f; + } + + if (unit == AngleUnit.TURNS) + { + return 0.25f; + } + + return F32Radians.HALF_OF_PI; + } + + public static float Normalize(float angle, AngleUnit unit, AngleRange range) + { + if (unit == AngleUnit.DEGREES) + { + return F32Degrees.Normalize(angle, range); + } + + if (unit == AngleUnit.TURNS) + { + return F32Turns.Normalize(angle, range); + } + + return F32Radians.Normalize(angle, range); + } + } +} diff --git a/BGC/F32Degrees.cs b/BGC/F32Degrees.cs new file mode 100644 index 0000000..31e947e --- /dev/null +++ b/BGC/F32Degrees.cs @@ -0,0 +1,68 @@ + +/* + * Author: Andrey Pokidov + * Date: 18 Nov 2024 + */ + +namespace BGC +{ + public class F32Degrees + { + public const float RADIANS_IN_DEGREE = 1.745329252E-2f; + public const float TURNS_IN_DEGREE = 2.7777777778E-3f; + + public static float ToRadians(float degrees) + { + return degrees * RADIANS_IN_DEGREE; + } + + public static float ToTurns(float degrees) + { + return degrees * TURNS_IN_DEGREE; + } + + public static float ToUnits(float degrees, AngleUnit toUnit) + { + if (toUnit == AngleUnit.RADIANS) + { + return degrees * RADIANS_IN_DEGREE; + } + + if (toUnit == AngleUnit.TURNS) + { + return degrees * TURNS_IN_DEGREE; + } + + return degrees; + } + + public static float Normalize(float radians, AngleRange range) + { + if (range == AngleRange.UNSIGNED_RANGE) + { + if (0.0f <= radians && radians < 360.0f) + { + return radians; + } + } + else + { + if (-180.0f < radians && radians <= 180.0f) + { + return radians; + } + } + + float turns = radians * TURNS_IN_DEGREE; + + turns -= MathF.Floor(turns); + + if (range == AngleRange.SIGNED_RANGE && turns > 0.5f) + { + turns -= 1.0f; + } + + return turns * 360.0f; + } + } +} diff --git a/Geometry/SPMatrix2x2.cs b/BGC/F32Matrix2x2.cs similarity index 75% rename from Geometry/SPMatrix2x2.cs rename to BGC/F32Matrix2x2.cs index 5812376..004b7b1 100644 --- a/Geometry/SPMatrix2x2.cs +++ b/BGC/F32Matrix2x2.cs @@ -1,352 +1,352 @@ -/* - * Copyright 2019-2025 Andrey Pokidov - * - * 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 Geometry -{ - public struct SPMatrix2x2 - { - public float r1c1, r1c2; - - public float r2c1, r2c2; - - public SPMatrix2x2() - { - this.r1c1 = 0.0f; - this.r1c2 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = 0.0f; - } - - public SPMatrix2x2(float d1, float d2) - { - this.r1c1 = d1; - this.r1c2 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = d2; - } - - public SPMatrix2x2(in SPMatrix2x2 matrix) - { - this.r1c1 = matrix.r1c1; - this.r1c2 = matrix.r1c2; - - this.r2c1 = matrix.r2c1; - this.r2c2 = matrix.r2c2; - } - - public SPMatrix2x2(in DPMatrix2x2 matrix) - { - this.r1c1 = (float)matrix.r1c1; - this.r1c2 = (float)matrix.r1c2; - - this.r2c1 = (float)matrix.r2c1; - this.r2c2 = (float)matrix.r2c2; - } - - public readonly float GetDeterminant() - { - return this.r1c1 * this.r2c2 - this.r1c2 * this.r2c1; - } - - public readonly bool IsSingular() - { - float determinant = this.GetDeterminant(); - return -SPUtility.EPSYLON <= determinant && determinant <= SPUtility.EPSYLON; - } - - public void Transpose() - { - (this.r1c2, this.r2c1) = (this.r2c1, this.r1c2); - } - - public bool Invert() - { - float determinant = this.GetDeterminant(); - - if (-SPUtility.EPSYLON <= determinant && determinant <= SPUtility.EPSYLON) - { - return false; - } - - float r1c1 = this.r2c2; - float r1c2 = -this.r1c2; - - float r2c1 = -this.r2c1; - float r2c2 = this.r1c1; - - this.r1c1 = r1c1 / determinant; - this.r1c2 = r1c2 / determinant; - - this.r2c1 = r2c1 / determinant; - this.r2c2 = r2c2 / determinant; - - return true; - } - - public void Reset() - { - this.r1c1 = 0.0f; - this.r1c2 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = 0.0f; - } - - public void SetToIdentity() - { - this.r1c1 = 1.0f; - this.r1c2 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = 1.0f; - } - - public void SetToDiagonal(float d1, float d2) - { - this.r1c1 = d1; - this.r1c2 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = d2; - } - - public void SetValues(in SPMatrix2x2 matrix) - { - this.r1c1 = matrix.r1c1; - this.r1c2 = matrix.r1c2; - - this.r2c1 = matrix.r2c1; - this.r2c2 = matrix.r2c2; - } - - public void SetValues(in DPMatrix2x2 matrix) - { - this.r1c1 = (float)matrix.r1c1; - this.r1c2 = (float)matrix.r1c2; - - this.r2c1 = (float)matrix.r2c1; - this.r2c2 = (float)matrix.r2c2; - } - - public void SetTransposedOf(in SPMatrix2x2 matrix) - { - this.r1c1 = matrix.r1c1; - this.r2c2 = matrix.r2c2; - (this.r1c2, this.r2c1) = (matrix.r2c1, matrix.r1c2); - } - - public void SetTransposedOf(in DPMatrix2x2 matrix) - { - this.r1c1 = (float)matrix.r1c1; - this.r1c2 = (float)matrix.r2c1; - - this.r2c1 = (float)matrix.r1c2; - this.r2c2 = (float)matrix.r2c2; - } - - public bool SetInvertedOf(in SPMatrix2x2 matrix) - { - float determinant = matrix.GetDeterminant(); - - if (-SPUtility.EPSYLON <= determinant && determinant <= SPUtility.EPSYLON) - { - return false; - } - - float r1c1 = matrix.r2c2; - float r1c2 = -matrix.r1c2; - - float r2c1 = -matrix.r2c1; - float r2c2 = matrix.r1c1; - - this.r1c1 = r1c1 / determinant; - this.r1c2 = r1c2 / determinant; - - this.r2c1 = r2c1 / determinant; - this.r2c2 = r2c2 / determinant; - - return true; - } - - public void SetRow1(float c1, float c2) - { - this.r1c1 = c1; - this.r1c2 = c2; - } - - public void SetRow2(float c1, float c2) - { - this.r2c1 = c1; - this.r2c2 = c2; - } - - public void SetColumn1(float r1, float r2) - { - this.r1c1 = r1; - this.r2c1 = r2; - } - - public void SetColumn2(float r1, float r2) - { - this.r1c2 = r1; - this.r2c2 = r2; - } - - public static void Add(in SPMatrix2x2 matrix1, in SPMatrix2x2 matrix2, out SPMatrix2x2 result) - { - result.r1c1 = matrix1.r1c1 + matrix2.r1c1; - result.r1c2 = matrix1.r1c2 + matrix2.r1c2; - - result.r2c1 = matrix1.r2c1 + matrix2.r2c1; - result.r2c2 = matrix1.r2c2 + matrix2.r2c2; - } - - public static void Subtract(in SPMatrix2x2 minuend, in SPMatrix2x2 subtrahend, out SPMatrix2x2 difference) - { - difference.r1c1 = minuend.r1c1 - subtrahend.r1c1; - difference.r1c2 = minuend.r1c2 - subtrahend.r1c2; - - difference.r2c1 = minuend.r2c1 - subtrahend.r2c1; - difference.r2c2 = minuend.r2c2 - subtrahend.r2c2; - } - - public static void Multiply(in SPMatrix2x2 multiplicand, float multiplier, out SPMatrix2x2 product) - { - product.r1c1 = multiplicand.r1c1 * multiplier; - product.r1c2 = multiplicand.r1c2 * multiplier; - - product.r2c1 = multiplicand.r2c1 * multiplier; - product.r2c2 = multiplicand.r2c2 * multiplier; - } - - public static void Divide(in SPMatrix2x2 dividend, float divisor, out SPMatrix2x2 quotient) - { - quotient.r1c1 = dividend.r1c1 / divisor; - quotient.r1c2 = dividend.r1c2 / divisor; - - quotient.r2c1 = dividend.r2c1 / divisor; - quotient.r2c2 = dividend.r2c2 / divisor; - } - - public static void GetWeightedSum2( - float weight1, in SPMatrix2x2 matrix1, - float weight2, in SPMatrix2x2 matrix2, - out SPMatrix2x2 sum) - { - sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2; - sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2; - - sum.r2c1 = matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2; - sum.r2c2 = matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2; - } - - public static void GetWeightedSum3( - float weight1, in SPMatrix2x2 matrix1, - float weight2, in SPMatrix2x2 matrix2, - float weight3, in SPMatrix2x2 matrix3, - out SPMatrix2x2 sum) - { - sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2 + matrix3.r1c1 * weight3; - sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2 + matrix3.r1c2 * weight3; - - sum.r2c1 = matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2 + matrix3.r2c1 * weight3; - sum.r2c2 = matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2 + matrix3.r2c2 * weight3; - } - - public static void GetWeightedSum4( - float weight1, in SPMatrix2x2 matrix1, - float weight2, in SPMatrix2x2 matrix2, - float weight3, in SPMatrix2x2 matrix3, - float weight4, in SPMatrix2x2 matrix4, - out SPMatrix2x2 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.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); - } - - public static void GetWeightedSum5( - float weight1, in SPMatrix2x2 matrix1, - float weight2, in SPMatrix2x2 matrix2, - float weight3, in SPMatrix2x2 matrix3, - float weight4, in SPMatrix2x2 matrix4, - float weight5, in SPMatrix2x2 matrix5, - out SPMatrix2x2 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.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; - } - - public static void GetRightProduct(in SPMatrix2x2 matrix, in SPVector2 vector, out SPVector2 result) - { - float x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2; - float x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2; - - result.x1 = x1; - result.x2 = x2; - } - - public static void GetLeftProduct(in SPVector2 vector, in SPMatrix2x2 matrix, out SPVector2 result) - { - float x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1; - float x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2; - - result.x1 = x1; - result.x2 = x2; - } - - public static void LoadZero(out SPMatrix2x2 matrix) - { - matrix.r1c1 = 0.0f; - matrix.r1c2 = 0.0f; - - matrix.r2c1 = 0.0f; - matrix.r2c2 = 0.0f; - } - - public static void LoadIdentity(out SPMatrix2x2 matrix) - { - matrix.r1c1 = 1.0f; - matrix.r1c2 = 0.0f; - - matrix.r2c1 = 0.0f; - matrix.r2c2 = 1.0f; - } - - public static void LoadDiagonal(float d1, float d2, out SPMatrix2x2 matrix) - { - matrix.r1c1 = d1; - matrix.r1c2 = 0.0f; - - matrix.r2c1 = 0.0f; - matrix.r2c2 = d2; - } - } -} +/* + * Copyright 2019-2025 Andrey Pokidov + * + * 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 F32Matrix2x2 + { + public float r1c1, r1c2; + + public float r2c1, r2c2; + + public F32Matrix2x2() + { + this.r1c1 = 0.0f; + this.r1c2 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = 0.0f; + } + + public F32Matrix2x2(float d1, float d2) + { + this.r1c1 = d1; + this.r1c2 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = d2; + } + + public F32Matrix2x2(in F32Matrix2x2 matrix) + { + this.r1c1 = matrix.r1c1; + this.r1c2 = matrix.r1c2; + + this.r2c1 = matrix.r2c1; + this.r2c2 = matrix.r2c2; + } + + public F32Matrix2x2(in F64Matrix2x2 matrix) + { + this.r1c1 = (float)matrix.r1c1; + this.r1c2 = (float)matrix.r1c2; + + this.r2c1 = (float)matrix.r2c1; + this.r2c2 = (float)matrix.r2c2; + } + + public readonly float GetDeterminant() + { + return this.r1c1 * this.r2c2 - this.r1c2 * this.r2c1; + } + + public readonly bool IsSingular() + { + float determinant = this.GetDeterminant(); + return -F32Utility.EPSYLON <= determinant && determinant <= F32Utility.EPSYLON; + } + + public void Transpose() + { + (this.r1c2, this.r2c1) = (this.r2c1, this.r1c2); + } + + public bool Invert() + { + float determinant = this.GetDeterminant(); + + if (-F32Utility.EPSYLON <= determinant && determinant <= F32Utility.EPSYLON) + { + return false; + } + + float r1c1 = this.r2c2; + float r1c2 = -this.r1c2; + + float r2c1 = -this.r2c1; + float r2c2 = this.r1c1; + + this.r1c1 = r1c1 / determinant; + this.r1c2 = r1c2 / determinant; + + this.r2c1 = r2c1 / determinant; + this.r2c2 = r2c2 / determinant; + + return true; + } + + public void Reset() + { + this.r1c1 = 0.0f; + this.r1c2 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = 0.0f; + } + + public void SetToIdentity() + { + this.r1c1 = 1.0f; + this.r1c2 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = 1.0f; + } + + public void SetToDiagonal(float d1, float d2) + { + this.r1c1 = d1; + this.r1c2 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = d2; + } + + public void SetValues(in F32Matrix2x2 matrix) + { + this.r1c1 = matrix.r1c1; + this.r1c2 = matrix.r1c2; + + this.r2c1 = matrix.r2c1; + this.r2c2 = matrix.r2c2; + } + + public void SetValues(in F64Matrix2x2 matrix) + { + this.r1c1 = (float)matrix.r1c1; + this.r1c2 = (float)matrix.r1c2; + + this.r2c1 = (float)matrix.r2c1; + this.r2c2 = (float)matrix.r2c2; + } + + public void SetTransposedOf(in F32Matrix2x2 matrix) + { + this.r1c1 = matrix.r1c1; + this.r2c2 = matrix.r2c2; + (this.r1c2, this.r2c1) = (matrix.r2c1, matrix.r1c2); + } + + public void SetTransposedOf(in F64Matrix2x2 matrix) + { + this.r1c1 = (float)matrix.r1c1; + this.r1c2 = (float)matrix.r2c1; + + this.r2c1 = (float)matrix.r1c2; + this.r2c2 = (float)matrix.r2c2; + } + + public bool SetInvertedOf(in F32Matrix2x2 matrix) + { + float determinant = matrix.GetDeterminant(); + + if (-F32Utility.EPSYLON <= determinant && determinant <= F32Utility.EPSYLON) + { + return false; + } + + float r1c1 = matrix.r2c2; + float r1c2 = -matrix.r1c2; + + float r2c1 = -matrix.r2c1; + float r2c2 = matrix.r1c1; + + this.r1c1 = r1c1 / determinant; + this.r1c2 = r1c2 / determinant; + + this.r2c1 = r2c1 / determinant; + this.r2c2 = r2c2 / determinant; + + return true; + } + + public void SetRow1(float c1, float c2) + { + this.r1c1 = c1; + this.r1c2 = c2; + } + + public void SetRow2(float c1, float c2) + { + this.r2c1 = c1; + this.r2c2 = c2; + } + + public void SetColumn1(float r1, float r2) + { + this.r1c1 = r1; + this.r2c1 = r2; + } + + public void SetColumn2(float r1, float r2) + { + this.r1c2 = r1; + this.r2c2 = r2; + } + + public static void Add(in F32Matrix2x2 matrix1, in F32Matrix2x2 matrix2, out F32Matrix2x2 result) + { + result.r1c1 = matrix1.r1c1 + matrix2.r1c1; + result.r1c2 = matrix1.r1c2 + matrix2.r1c2; + + result.r2c1 = matrix1.r2c1 + matrix2.r2c1; + result.r2c2 = matrix1.r2c2 + matrix2.r2c2; + } + + public static void Subtract(in F32Matrix2x2 minuend, in F32Matrix2x2 subtrahend, out F32Matrix2x2 difference) + { + difference.r1c1 = minuend.r1c1 - subtrahend.r1c1; + difference.r1c2 = minuend.r1c2 - subtrahend.r1c2; + + difference.r2c1 = minuend.r2c1 - subtrahend.r2c1; + difference.r2c2 = minuend.r2c2 - subtrahend.r2c2; + } + + public static void Multiply(in F32Matrix2x2 multiplicand, float multiplier, out F32Matrix2x2 product) + { + product.r1c1 = multiplicand.r1c1 * multiplier; + product.r1c2 = multiplicand.r1c2 * multiplier; + + product.r2c1 = multiplicand.r2c1 * multiplier; + product.r2c2 = multiplicand.r2c2 * multiplier; + } + + public static void Divide(in F32Matrix2x2 dividend, float divisor, out F32Matrix2x2 quotient) + { + quotient.r1c1 = dividend.r1c1 / divisor; + quotient.r1c2 = dividend.r1c2 / divisor; + + quotient.r2c1 = dividend.r2c1 / divisor; + quotient.r2c2 = dividend.r2c2 / divisor; + } + + public static void GetWeightedSum2( + float weight1, in F32Matrix2x2 matrix1, + float weight2, in F32Matrix2x2 matrix2, + out F32Matrix2x2 sum) + { + sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2; + sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2; + + sum.r2c1 = matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2; + sum.r2c2 = matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2; + } + + public static void GetWeightedSum3( + float weight1, in F32Matrix2x2 matrix1, + float weight2, in F32Matrix2x2 matrix2, + float weight3, in F32Matrix2x2 matrix3, + out F32Matrix2x2 sum) + { + sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2 + matrix3.r1c1 * weight3; + sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2 + matrix3.r1c2 * weight3; + + sum.r2c1 = matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2 + matrix3.r2c1 * weight3; + sum.r2c2 = matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2 + matrix3.r2c2 * weight3; + } + + public static void GetWeightedSum4( + float weight1, in F32Matrix2x2 matrix1, + float weight2, in F32Matrix2x2 matrix2, + float weight3, in F32Matrix2x2 matrix3, + float weight4, in F32Matrix2x2 matrix4, + out F32Matrix2x2 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.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); + } + + public static void GetWeightedSum5( + float weight1, in F32Matrix2x2 matrix1, + float weight2, in F32Matrix2x2 matrix2, + float weight3, in F32Matrix2x2 matrix3, + float weight4, in F32Matrix2x2 matrix4, + float weight5, in F32Matrix2x2 matrix5, + out F32Matrix2x2 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.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; + } + + public static void GetRightProduct(in F32Matrix2x2 matrix, in F32Vector2 vector, out F32Vector2 result) + { + float x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2; + float x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2; + + result.x1 = x1; + result.x2 = x2; + } + + public static void GetLeftProduct(in F32Vector2 vector, in F32Matrix2x2 matrix, out F32Vector2 result) + { + float x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1; + float x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2; + + result.x1 = x1; + result.x2 = x2; + } + + public static void LoadZero(out F32Matrix2x2 matrix) + { + matrix.r1c1 = 0.0f; + matrix.r1c2 = 0.0f; + + matrix.r2c1 = 0.0f; + matrix.r2c2 = 0.0f; + } + + public static void LoadIdentity(out F32Matrix2x2 matrix) + { + matrix.r1c1 = 1.0f; + matrix.r1c2 = 0.0f; + + matrix.r2c1 = 0.0f; + matrix.r2c2 = 1.0f; + } + + public static void LoadDiagonal(float d1, float d2, out F32Matrix2x2 matrix) + { + matrix.r1c1 = d1; + matrix.r1c2 = 0.0f; + + matrix.r2c1 = 0.0f; + matrix.r2c2 = d2; + } + } +} diff --git a/Geometry/SPMatrix2x3.cs b/BGC/F32Matrix2x3.cs similarity index 81% rename from Geometry/SPMatrix2x3.cs rename to BGC/F32Matrix2x3.cs index bf7e134..619b93d 100644 --- a/Geometry/SPMatrix2x3.cs +++ b/BGC/F32Matrix2x3.cs @@ -20,15 +20,15 @@ using System; * Author: Andrey Pokidov * Date: 11 Nov 2024 */ -namespace Geometry +namespace BGC { - public struct SPMatrix2x3 + public struct F32Matrix2x3 { public float r1c1, r1c2; public float r2c1, r2c2; public float r3c1, r3c2; - public SPMatrix2x3() + public F32Matrix2x3() { this.r1c1 = 0.0f; this.r1c2 = 0.0f; @@ -40,7 +40,7 @@ namespace Geometry this.r3c2 = 0.0f; } - public SPMatrix2x3(in SPMatrix2x3 matrix) + public F32Matrix2x3(in F32Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -52,7 +52,7 @@ namespace Geometry this.r3c2 = matrix.r3c2; } - public SPMatrix2x3(in DPMatrix2x3 matrix) + public F32Matrix2x3(in F64Matrix2x3 matrix) { this.r1c1 = (float) matrix.r1c1; this.r1c2 = (float) matrix.r1c2; @@ -64,7 +64,7 @@ namespace Geometry this.r3c2 = (float) matrix.r3c2; } - public SPMatrix2x3(in SPMatrix3x2 matrix) + public F32Matrix2x3(in F32Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -76,7 +76,7 @@ namespace Geometry this.r3c2 = matrix.r2c3; } - public SPMatrix2x3(in DPMatrix3x2 matrix) + public F32Matrix2x3(in F64Matrix3x2 matrix) { this.r1c1 = (float) matrix.r1c1; this.r1c2 = (float) matrix.r2c1; @@ -100,7 +100,7 @@ namespace Geometry this.r3c2 = 0.0f; } - public void SetValues(in SPMatrix2x3 matrix) + public void SetValues(in F32Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -112,7 +112,7 @@ namespace Geometry this.r3c2 = matrix.r3c2; } - public void SetValues(in DPMatrix2x3 matrix) + public void SetValues(in F64Matrix2x3 matrix) { this.r1c1 = (float) matrix.r1c1; this.r1c2 = (float) matrix.r1c2; @@ -124,7 +124,7 @@ namespace Geometry this.r3c2 = (float) matrix.r3c2; } - public void SetTransposed(in SPMatrix3x2 matrix) + public void SetTransposed(in F32Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -136,7 +136,7 @@ namespace Geometry this.r3c2 = matrix.r2c3; } - public void SetTransposed(in DPMatrix3x2 matrix) + public void SetTransposed(in F64Matrix3x2 matrix) { this.r1c1 = (float) matrix.r1c1; this.r1c2 = (float) matrix.r2c1; @@ -180,7 +180,7 @@ namespace Geometry this.r3c2 = r3; } - public static void Add(in SPMatrix2x3 matrix1, in SPMatrix2x3 matrix2, out SPMatrix2x3 sum) + public static void Add(in F32Matrix2x3 matrix1, in F32Matrix2x3 matrix2, out F32Matrix2x3 sum) { sum.r1c1 = matrix1.r1c1 + matrix2.r1c1; sum.r1c2 = matrix1.r1c2 + matrix2.r1c2; @@ -192,7 +192,7 @@ namespace Geometry sum.r3c2 = matrix1.r3c2 + matrix2.r3c2; } - public static void Subtract(in SPMatrix2x3 minuend, in SPMatrix2x3 subtrahend, out SPMatrix2x3 difference) + public static void Subtract(in F32Matrix2x3 minuend, in F32Matrix2x3 subtrahend, out F32Matrix2x3 difference) { difference.r1c1 = minuend.r1c1 - subtrahend.r1c1; difference.r1c2 = minuend.r1c2 - subtrahend.r1c2; @@ -204,7 +204,7 @@ namespace Geometry difference.r3c2 = minuend.r3c2 - subtrahend.r3c2; } - public static void Multiply(in SPMatrix2x3 multiplicand, float multiplier, out SPMatrix2x3 product) + public static void Multiply(in F32Matrix2x3 multiplicand, float multiplier, out F32Matrix2x3 product) { product.r1c1 = multiplicand.r1c1 * multiplier; product.r1c2 = multiplicand.r1c2 * multiplier; @@ -216,7 +216,7 @@ namespace Geometry product.r3c2 = multiplicand.r3c2 * multiplier; } - public static void Divide(in SPMatrix2x3 dividend, float divisor, out SPMatrix2x3 quotient) + public static void Divide(in F32Matrix2x3 dividend, float divisor, out F32Matrix2x3 quotient) { quotient.r1c1 = dividend.r1c1 / divisor; quotient.r1c2 = dividend.r1c2 / divisor; @@ -229,9 +229,9 @@ namespace Geometry } public static void GetWeightedSum2( - float weight1, in SPMatrix2x3 matrix1, - float weight2, in SPMatrix2x3 matrix2, - out SPMatrix2x3 sum) + float weight1, in F32Matrix2x3 matrix1, + float weight2, in F32Matrix2x3 matrix2, + out F32Matrix2x3 sum) { sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2; sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2; @@ -244,10 +244,10 @@ namespace Geometry } public static void GetWeightedSum3( - float weight1, in SPMatrix2x3 matrix1, - float weight2, in SPMatrix2x3 matrix2, - float weight3, in SPMatrix2x3 matrix3, - out SPMatrix2x3 sum) + float weight1, in F32Matrix2x3 matrix1, + float weight2, in F32Matrix2x3 matrix2, + float weight3, in F32Matrix2x3 matrix3, + out F32Matrix2x3 sum) { sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2 + matrix3.r1c1 * weight3; sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2 + matrix3.r1c2 * weight3; @@ -260,11 +260,11 @@ namespace Geometry } public static void GetWeightedSum4( - float weight1, in SPMatrix2x3 matrix1, - float weight2, in SPMatrix2x3 matrix2, - float weight3, in SPMatrix2x3 matrix3, - float weight4, in SPMatrix2x3 matrix4, - out SPMatrix2x3 sum) + float weight1, in F32Matrix2x3 matrix1, + float weight2, in F32Matrix2x3 matrix2, + float weight3, in F32Matrix2x3 matrix3, + float weight4, in F32Matrix2x3 matrix4, + out F32Matrix2x3 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); @@ -277,12 +277,12 @@ namespace Geometry } public static void GetWeightedSum5( - float weight1, in SPMatrix2x3 matrix1, - float weight2, in SPMatrix2x3 matrix2, - float weight3, in SPMatrix2x3 matrix3, - float weight4, in SPMatrix2x3 matrix4, - float weight5, in SPMatrix2x3 matrix5, - out SPMatrix2x3 sum) + float weight1, in F32Matrix2x3 matrix1, + float weight2, in F32Matrix2x3 matrix2, + float weight3, in F32Matrix2x3 matrix3, + float weight4, in F32Matrix2x3 matrix4, + float weight5, in F32Matrix2x3 matrix5, + out F32Matrix2x3 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; @@ -294,14 +294,14 @@ namespace Geometry sum.r3c2 = (matrix1.r3c2 * weight1 + matrix2.r3c2 * weight2) + (matrix3.r3c2 * weight3 + matrix4.r3c2 * weight4) + matrix5.r3c2 * weight5; } - public static void GetRightProduct(in SPMatrix2x3 matrix, in SPVector2 vector, out SPVector3 result) + public static void GetRightProduct(in F32Matrix2x3 matrix, in F32Vector2 vector, out F32Vector3 result) { result.x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2; result.x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2; result.x3 = matrix.r3c1 * vector.x1 + matrix.r3c2 * vector.x2; } - public static void GetLeftProduct(in SPVector3 vector, in SPMatrix2x3 matrix, out SPVector2 result) + public static void GetLeftProduct(in F32Vector3 vector, in F32Matrix2x3 matrix, out F32Vector2 result) { result.x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1 + vector.x3 * matrix.r3c1; result.x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2 + vector.x3 * matrix.r3c2; diff --git a/Geometry/SPMatrix3x2.cs b/BGC/F32Matrix3x2.cs similarity index 81% rename from Geometry/SPMatrix3x2.cs rename to BGC/F32Matrix3x2.cs index 56c0a9b..b284779 100644 --- a/Geometry/SPMatrix3x2.cs +++ b/BGC/F32Matrix3x2.cs @@ -18,14 +18,14 @@ * Author: Andrey Pokidov * Date: 11 Nov 2024 */ -namespace Geometry +namespace BGC { - public struct SPMatrix3x2 + public struct F32Matrix3x2 { public float r1c1, r1c2, r1c3; public float r2c1, r2c2, r2c3; - public SPMatrix3x2() + public F32Matrix3x2() { this.r1c1 = 0.0f; this.r1c2 = 0.0f; @@ -36,7 +36,7 @@ namespace Geometry this.r2c3 = 0.0f; } - public SPMatrix3x2(in SPMatrix3x2 matrix) + public F32Matrix3x2(in F32Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -47,7 +47,7 @@ namespace Geometry this.r2c3 = matrix.r2c3; } - public SPMatrix3x2(in DPMatrix3x2 matrix) + public F32Matrix3x2(in F64Matrix3x2 matrix) { this.r1c1 = (float) matrix.r1c1; this.r1c2 = (float) matrix.r1c2; @@ -58,7 +58,7 @@ namespace Geometry this.r2c3 = (float) matrix.r2c3; } - public SPMatrix3x2(in SPMatrix2x3 matrix) + public F32Matrix3x2(in F32Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -69,7 +69,7 @@ namespace Geometry this.r2c3 = matrix.r3c2; } - public SPMatrix3x2(in DPMatrix2x3 matrix) + public F32Matrix3x2(in F64Matrix2x3 matrix) { this.r1c1 = (float) matrix.r1c1; this.r1c2 = (float) matrix.r2c1; @@ -91,7 +91,7 @@ namespace Geometry this.r2c3 = 0.0f; } - public void SetValues(in SPMatrix3x2 matrix) + public void SetValues(in F32Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -102,7 +102,7 @@ namespace Geometry this.r2c3 = matrix.r2c3; } - public void SetValues(in DPMatrix3x2 matrix) + public void SetValues(in F64Matrix3x2 matrix) { this.r1c1 = (float) matrix.r1c1; this.r1c2 = (float) matrix.r1c2; @@ -113,7 +113,7 @@ namespace Geometry this.r2c3 = (float) matrix.r2c3; } - public void SetTransposed(in SPMatrix2x3 matrix) + public void SetTransposed(in F32Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -124,7 +124,7 @@ namespace Geometry this.r2c3 = matrix.r3c2; } - public void SetTransposed(in DPMatrix2x3 matrix) + public void SetTransposed(in F64Matrix2x3 matrix) { this.r1c1 = (float) matrix.r1c1; this.r1c2 = (float) matrix.r2c1; @@ -167,7 +167,7 @@ namespace Geometry this.r2c3 = r2; } - public static void Add(in SPMatrix3x2 matrix1, in SPMatrix3x2 matrix2, out SPMatrix3x2 sum) + public static void Add(in F32Matrix3x2 matrix1, in F32Matrix3x2 matrix2, out F32Matrix3x2 sum) { sum.r1c1 = matrix1.r1c1 + matrix2.r1c1; sum.r1c2 = matrix1.r1c2 + matrix2.r1c2; @@ -178,7 +178,7 @@ namespace Geometry sum.r2c3 = matrix1.r2c3 + matrix2.r2c3; } - public static void Subtract(in SPMatrix3x2 minuend, in SPMatrix3x2 subtrahend, out SPMatrix3x2 difference) + public static void Subtract(in F32Matrix3x2 minuend, in F32Matrix3x2 subtrahend, out F32Matrix3x2 difference) { difference.r1c1 = minuend.r1c1 - subtrahend.r1c1; difference.r1c2 = minuend.r1c2 - subtrahend.r1c2; @@ -189,7 +189,7 @@ namespace Geometry difference.r2c3 = minuend.r2c3 - subtrahend.r2c3; } - public static void Multiply(in SPMatrix3x2 multiplicand, float multiplier, out SPMatrix3x2 product) + public static void Multiply(in F32Matrix3x2 multiplicand, float multiplier, out F32Matrix3x2 product) { product.r1c1 = multiplicand.r1c1 * multiplier; product.r1c2 = multiplicand.r1c2 * multiplier; @@ -200,7 +200,7 @@ namespace Geometry product.r2c3 = multiplicand.r2c3 * multiplier; } - public static void Divide(in SPMatrix3x2 dividend, float divisor, out SPMatrix3x2 quotient) + public static void Divide(in F32Matrix3x2 dividend, float divisor, out F32Matrix3x2 quotient) { quotient.r1c1 = dividend.r1c1 / divisor; quotient.r1c2 = dividend.r1c2 / divisor; @@ -212,9 +212,9 @@ namespace Geometry } public static void GetWeightedSum2( - float weight1, in SPMatrix3x2 matrix1, - float weight2, in SPMatrix3x2 matrix2, - out SPMatrix3x2 sum) + float weight1, in F32Matrix3x2 matrix1, + float weight2, in F32Matrix3x2 matrix2, + out F32Matrix3x2 sum) { sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2; sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2; @@ -226,10 +226,10 @@ namespace Geometry } public static void GetWeightedSum3( - float weight1, in SPMatrix3x2 matrix1, - float weight2, in SPMatrix3x2 matrix2, - float weight3, in SPMatrix3x2 matrix3, - out SPMatrix3x2 sum) + float weight1, in F32Matrix3x2 matrix1, + float weight2, in F32Matrix3x2 matrix2, + float weight3, in F32Matrix3x2 matrix3, + out F32Matrix3x2 sum) { sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2 + matrix3.r1c1 * weight3; sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2 + matrix3.r1c2 * weight3; @@ -241,11 +241,11 @@ namespace Geometry } public static void GetWeightedSum4( - float weight1, in SPMatrix3x2 matrix1, - float weight2, in SPMatrix3x2 matrix2, - float weight3, in SPMatrix3x2 matrix3, - float weight4, in SPMatrix3x2 matrix4, - out SPMatrix3x2 sum) + float weight1, in F32Matrix3x2 matrix1, + float weight2, in F32Matrix3x2 matrix2, + float weight3, in F32Matrix3x2 matrix3, + float weight4, in F32Matrix3x2 matrix4, + out F32Matrix3x2 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); @@ -257,12 +257,12 @@ namespace Geometry } public static void GetWeightedSum5( - float weight1, in SPMatrix3x2 matrix1, - float weight2, in SPMatrix3x2 matrix2, - float weight3, in SPMatrix3x2 matrix3, - float weight4, in SPMatrix3x2 matrix4, - float weight5, in SPMatrix3x2 matrix5, - out SPMatrix3x2 sum) + float weight1, in F32Matrix3x2 matrix1, + float weight2, in F32Matrix3x2 matrix2, + float weight3, in F32Matrix3x2 matrix3, + float weight4, in F32Matrix3x2 matrix4, + float weight5, in F32Matrix3x2 matrix5, + out F32Matrix3x2 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; @@ -273,13 +273,13 @@ namespace Geometry sum.r2c3 = (matrix1.r2c3 * weight1 + matrix2.r2c3 * weight2) + (matrix3.r2c3 * weight3 + matrix4.r2c3 * weight4) + matrix5.r2c3 * weight5; } - public static void GetRightProduct(in SPMatrix3x2 matrix, in SPVector3 vector, out SPVector2 result) + public static void GetRightProduct(in F32Matrix3x2 matrix, in F32Vector3 vector, out F32Vector2 result) { result.x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2 + matrix.r1c3 * vector.x3; result.x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2 + matrix.r2c3 * vector.x3; } - public static void GetLeftProduct(in SPVector2 vector, in SPMatrix3x2 matrix, out SPVector3 result) + public static void GetLeftProduct(in F32Vector2 vector, in F32Matrix3x2 matrix, out F32Vector3 result) { result.x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1; result.x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2; diff --git a/Geometry/SPMatrix3x3.cs b/BGC/F32Matrix3x3.cs similarity index 85% rename from Geometry/SPMatrix3x3.cs rename to BGC/F32Matrix3x3.cs index 7f1c925..d23b9e1 100644 --- a/Geometry/SPMatrix3x3.cs +++ b/BGC/F32Matrix3x3.cs @@ -1,532 +1,532 @@ -/* - * Copyright 2019-2025 Andrey Pokidov - * - * 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 Geometry -{ - public struct SPMatrix3x3 - { - public float r1c1, r1c2, r1c3; - - public float r2c1, r2c2, r2c3; - - public float r3c1, r3c2, r3c3; - - public SPMatrix3x3() - { - this.r1c1 = 0.0f; - this.r1c2 = 0.0f; - this.r1c3 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = 0.0f; - this.r2c3 = 0.0f; - - this.r3c1 = 0.0f; - this.r3c2 = 0.0f; - this.r3c3 = 0.0f; - } - - public SPMatrix3x3(float d1, float d2, float d3) - { - this.r1c1 = d1; - this.r1c2 = 0.0f; - this.r1c3 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = d2; - this.r2c3 = 0.0f; - - this.r3c1 = 0.0f; - this.r3c2 = 0.0f; - this.r3c3 = d3; - } - - public SPMatrix3x3(in SPMatrix3x3 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 SPMatrix3x3(in DPMatrix3x3 matrix) - { - this.r1c1 = (float)matrix.r1c1; - this.r1c2 = (float)matrix.r1c2; - this.r1c3 = (float)matrix.r1c3; - - this.r2c1 = (float)matrix.r2c1; - this.r2c2 = (float)matrix.r2c2; - this.r2c3 = (float)matrix.r2c3; - - this.r3c1 = (float)matrix.r3c1; - this.r3c2 = (float)matrix.r3c2; - this.r3c3 = (float)matrix.r3c3; - } - - public readonly float 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() - { - float determinant = this.GetDeterminant(); - return -SPUtility.EPSYLON <= determinant && determinant <= SPUtility.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() - { - float determinant = this.GetDeterminant(); - - if (-SPUtility.EPSYLON <= determinant && determinant <= SPUtility.EPSYLON) { - return false; - } - - float r1c1 = this.r2c2 * this.r3c3 - this.r2c3 * this.r3c2; - float r1c2 = this.r1c3 * this.r3c2 - this.r1c2 * this.r3c3; - float r1c3 = this.r1c2 * this.r2c3 - this.r1c3 * this.r2c2; - - float r2c1 = this.r2c3 * this.r3c1 - this.r2c1 * this.r3c3; - float r2c2 = this.r1c1 * this.r3c3 - this.r1c3 * this.r3c1; - float r2c3 = this.r1c3 * this.r2c1 - this.r1c1 * this.r2c3; - - float r3c1 = this.r2c1 * this.r3c2 - this.r2c2 * this.r3c1; - float r3c2 = this.r1c2 * this.r3c1 - this.r1c1 * this.r3c2; - float 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.0f; - this.r1c2 = 0.0f; - this.r1c3 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = 0.0f; - this.r2c3 = 0.0f; - - this.r3c1 = 0.0f; - this.r3c2 = 0.0f; - this.r3c3 = 0.0f; - } - - public void SetToIdentity() - { - this.r1c1 = 1.0f; - this.r1c2 = 0.0f; - this.r1c3 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = 1.0f; - this.r2c3 = 0.0f; - - this.r3c1 = 0.0f; - this.r3c2 = 0.0f; - this.r3c3 = 1.0f; - } - - public void SetToDiagonal(float d1, float d2, float d3) - { - this.r1c1 = d1; - this.r1c2 = 0.0f; - this.r1c3 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = d2; - this.r2c3 = 0.0f; - - this.r2c1 = 0.0f; - this.r2c2 = 0.0f; - this.r2c3 = d3; - } - - public void SetValues(in SPMatrix3x3 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(in DPMatrix3x3 matrix) - { - this.r1c1 = (float)matrix.r1c1; - this.r1c2 = (float)matrix.r1c2; - this.r1c3 = (float)matrix.r1c3; - - this.r2c1 = (float)matrix.r2c1; - this.r2c2 = (float)matrix.r2c2; - this.r2c3 = (float)matrix.r2c3; - - this.r3c1 = (float)matrix.r3c1; - this.r3c2 = (float)matrix.r3c2; - this.r3c3 = (float)matrix.r3c3; - } - - public void SetTransposedOf(in SPMatrix3x3 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 DPMatrix3x3 matrix) - { - this.r1c1 = (float)matrix.r1c1; - this.r1c2 = (float)matrix.r2c1; - this.r1c3 = (float)matrix.r3c1; - - this.r2c1 = (float)matrix.r1c2; - this.r2c2 = (float)matrix.r2c2; - this.r2c3 = (float)matrix.r3c2; - - this.r3c1 = (float)matrix.r1c3; - this.r3c2 = (float)matrix.r2c3; - this.r3c3 = (float)matrix.r3c3; - } - - public bool SetInvertedOf(in SPMatrix3x3 matrix) - { - float determinant = matrix.GetDeterminant(); - - if (-SPUtility.EPSYLON <= determinant && determinant <= SPUtility.EPSYLON) { - return false; - } - - float r1c1 = matrix.r2c2 * matrix.r3c3 - matrix.r2c3 * matrix.r3c2; - float r1c2 = matrix.r1c3 * matrix.r3c2 - matrix.r1c2 * matrix.r3c3; - float r1c3 = matrix.r1c2 * matrix.r2c3 - matrix.r1c3 * matrix.r2c2; - - float r2c1 = matrix.r2c3 * matrix.r3c1 - matrix.r2c1 * matrix.r3c3; - float r2c2 = matrix.r1c1 * matrix.r3c3 - matrix.r1c3 * matrix.r3c1; - float r2c3 = matrix.r1c3 * matrix.r2c1 - matrix.r1c1 * matrix.r2c3; - - float r3c1 = matrix.r2c1 * matrix.r3c2 - matrix.r2c2 * matrix.r3c1; - float r3c2 = matrix.r1c2 * matrix.r3c1 - matrix.r1c1 * matrix.r3c2; - float 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(float c1, float c2, float c3) - { - this.r1c1 = c1; - this.r1c2 = c2; - this.r1c3 = c3; - } - - public void SetRow2(float c1, float c2, float c3) - { - this.r2c1 = c1; - this.r2c2 = c2; - this.r2c3 = c3; - } - - public void SetRow3(float c1, float c2, float c3) - { - this.r3c1 = c1; - this.r3c2 = c2; - this.r3c3 = c3; - } - - public void SetColumn1(float r1, float r2, float r3) - { - this.r1c1 = r1; - this.r2c1 = r2; - this.r3c1 = r3; - } - - public void SetColumn2(float r1, float r2, float r3) - { - this.r1c2 = r1; - this.r2c2 = r2; - this.r3c2 = r3; - } - - public void SetColumn3(float r1, float r2, float r3) - { - this.r1c3 = r1; - this.r2c3 = r2; - this.r3c3 = r3; - } - - public static void Add(in SPMatrix3x3 matrix1, in SPMatrix3x3 matrix2, out SPMatrix3x3 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 SPMatrix3x3 minuend, in SPMatrix3x3 subtrahend, out SPMatrix3x3 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 SPMatrix3x3 multiplicand, float multiplier, out SPMatrix3x3 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 SPMatrix3x3 dividend, float divisor, out SPMatrix3x3 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( - float weight1, in SPMatrix3x3 matrix1, - float weight2, in SPMatrix3x3 matrix2, - out SPMatrix3x3 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( - float weight1, in SPMatrix3x3 matrix1, - float weight2, in SPMatrix3x3 matrix2, - float weight3, in SPMatrix3x3 matrix3, - out SPMatrix3x3 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( - float weight1, in SPMatrix3x3 matrix1, - float weight2, in SPMatrix3x3 matrix2, - float weight3, in SPMatrix3x3 matrix3, - float weight4, in SPMatrix3x3 matrix4, - out SPMatrix3x3 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( - float weight1, in SPMatrix3x3 matrix1, - float weight2, in SPMatrix3x3 matrix2, - float weight3, in SPMatrix3x3 matrix3, - float weight4, in SPMatrix3x3 matrix4, - float weight5, in SPMatrix3x3 matrix5, - out SPMatrix3x3 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 SPMatrix3x3 matrix, in SPVector3 vector, out SPVector3 result) - { - float x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2 + matrix.r1c3 * vector.x3; - float x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2 + matrix.r2c3 * vector.x3; - float 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 SPVector3 vector, in SPMatrix3x3 matrix, out SPVector3 result) - { - float x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1 + vector.x3 * matrix.r3c1; - float x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2 + vector.x3 * matrix.r3c2; - float 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 SPMatrix3x3 matrix) - { - matrix.r1c1 = 0.0f; - matrix.r1c2 = 0.0f; - matrix.r1c3 = 0.0f; - - matrix.r2c1 = 0.0f; - matrix.r2c2 = 0.0f; - matrix.r2c3 = 0.0f; - - matrix.r3c1 = 0.0f; - matrix.r3c2 = 0.0f; - matrix.r3c3 = 0.0f; - } - - public static void LoadIdentity(out SPMatrix3x3 matrix) - { - matrix.r1c1 = 1.0f; - matrix.r1c2 = 0.0f; - matrix.r1c3 = 0.0f; - - matrix.r2c1 = 0.0f; - matrix.r2c2 = 1.0f; - matrix.r2c3 = 0.0f; - - matrix.r3c1 = 0.0f; - matrix.r3c2 = 0.0f; - matrix.r3c3 = 1.0f; - } - - public static void LoadDiagonal(float d1, float d2, float d3, out SPMatrix3x3 matrix) - { - matrix.r1c1 = d1; - matrix.r1c2 = 0.0f; - matrix.r1c3 = 0.0f; - - matrix.r2c1 = 0.0f; - matrix.r2c2 = d2; - matrix.r2c3 = 0.0f; - - matrix.r3c1 = 0.0f; - matrix.r3c2 = 0.0f; - matrix.r3c3 = d3; - } - } -} +/* + * Copyright 2019-2025 Andrey Pokidov + * + * 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 F32Matrix3x3 + { + public float r1c1, r1c2, r1c3; + + public float r2c1, r2c2, r2c3; + + public float r3c1, r3c2, r3c3; + + public F32Matrix3x3() + { + this.r1c1 = 0.0f; + this.r1c2 = 0.0f; + this.r1c3 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = 0.0f; + this.r2c3 = 0.0f; + + this.r3c1 = 0.0f; + this.r3c2 = 0.0f; + this.r3c3 = 0.0f; + } + + public F32Matrix3x3(float d1, float d2, float d3) + { + this.r1c1 = d1; + this.r1c2 = 0.0f; + this.r1c3 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = d2; + this.r2c3 = 0.0f; + + this.r3c1 = 0.0f; + this.r3c2 = 0.0f; + this.r3c3 = d3; + } + + public F32Matrix3x3(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 F32Matrix3x3(in F64Matrix3x3 matrix) + { + this.r1c1 = (float)matrix.r1c1; + this.r1c2 = (float)matrix.r1c2; + this.r1c3 = (float)matrix.r1c3; + + this.r2c1 = (float)matrix.r2c1; + this.r2c2 = (float)matrix.r2c2; + this.r2c3 = (float)matrix.r2c3; + + this.r3c1 = (float)matrix.r3c1; + this.r3c2 = (float)matrix.r3c2; + this.r3c3 = (float)matrix.r3c3; + } + + public readonly float 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() + { + float determinant = this.GetDeterminant(); + return -F32Utility.EPSYLON <= determinant && determinant <= F32Utility.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() + { + float determinant = this.GetDeterminant(); + + if (-F32Utility.EPSYLON <= determinant && determinant <= F32Utility.EPSYLON) { + return false; + } + + float r1c1 = this.r2c2 * this.r3c3 - this.r2c3 * this.r3c2; + float r1c2 = this.r1c3 * this.r3c2 - this.r1c2 * this.r3c3; + float r1c3 = this.r1c2 * this.r2c3 - this.r1c3 * this.r2c2; + + float r2c1 = this.r2c3 * this.r3c1 - this.r2c1 * this.r3c3; + float r2c2 = this.r1c1 * this.r3c3 - this.r1c3 * this.r3c1; + float r2c3 = this.r1c3 * this.r2c1 - this.r1c1 * this.r2c3; + + float r3c1 = this.r2c1 * this.r3c2 - this.r2c2 * this.r3c1; + float r3c2 = this.r1c2 * this.r3c1 - this.r1c1 * this.r3c2; + float 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.0f; + this.r1c2 = 0.0f; + this.r1c3 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = 0.0f; + this.r2c3 = 0.0f; + + this.r3c1 = 0.0f; + this.r3c2 = 0.0f; + this.r3c3 = 0.0f; + } + + public void SetToIdentity() + { + this.r1c1 = 1.0f; + this.r1c2 = 0.0f; + this.r1c3 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = 1.0f; + this.r2c3 = 0.0f; + + this.r3c1 = 0.0f; + this.r3c2 = 0.0f; + this.r3c3 = 1.0f; + } + + public void SetToDiagonal(float d1, float d2, float d3) + { + this.r1c1 = d1; + this.r1c2 = 0.0f; + this.r1c3 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = d2; + this.r2c3 = 0.0f; + + this.r2c1 = 0.0f; + this.r2c2 = 0.0f; + this.r2c3 = d3; + } + + public void SetValues(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 void SetValues(in F64Matrix3x3 matrix) + { + this.r1c1 = (float)matrix.r1c1; + this.r1c2 = (float)matrix.r1c2; + this.r1c3 = (float)matrix.r1c3; + + this.r2c1 = (float)matrix.r2c1; + this.r2c2 = (float)matrix.r2c2; + this.r2c3 = (float)matrix.r2c3; + + this.r3c1 = (float)matrix.r3c1; + this.r3c2 = (float)matrix.r3c2; + this.r3c3 = (float)matrix.r3c3; + } + + 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 void SetTransposedOf(in F64Matrix3x3 matrix) + { + this.r1c1 = (float)matrix.r1c1; + this.r1c2 = (float)matrix.r2c1; + this.r1c3 = (float)matrix.r3c1; + + this.r2c1 = (float)matrix.r1c2; + this.r2c2 = (float)matrix.r2c2; + this.r2c3 = (float)matrix.r3c2; + + this.r3c1 = (float)matrix.r1c3; + this.r3c2 = (float)matrix.r2c3; + this.r3c3 = (float)matrix.r3c3; + } + + public bool SetInvertedOf(in F32Matrix3x3 matrix) + { + float determinant = matrix.GetDeterminant(); + + if (-F32Utility.EPSYLON <= determinant && determinant <= F32Utility.EPSYLON) { + return false; + } + + float r1c1 = matrix.r2c2 * matrix.r3c3 - matrix.r2c3 * matrix.r3c2; + float r1c2 = matrix.r1c3 * matrix.r3c2 - matrix.r1c2 * matrix.r3c3; + float r1c3 = matrix.r1c2 * matrix.r2c3 - matrix.r1c3 * matrix.r2c2; + + float r2c1 = matrix.r2c3 * matrix.r3c1 - matrix.r2c1 * matrix.r3c3; + float r2c2 = matrix.r1c1 * matrix.r3c3 - matrix.r1c3 * matrix.r3c1; + float r2c3 = matrix.r1c3 * matrix.r2c1 - matrix.r1c1 * matrix.r2c3; + + float r3c1 = matrix.r2c1 * matrix.r3c2 - matrix.r2c2 * matrix.r3c1; + float r3c2 = matrix.r1c2 * matrix.r3c1 - matrix.r1c1 * matrix.r3c2; + float 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(float c1, float c2, float c3) + { + this.r1c1 = c1; + this.r1c2 = c2; + this.r1c3 = c3; + } + + public void SetRow2(float c1, float c2, float c3) + { + this.r2c1 = c1; + this.r2c2 = c2; + this.r2c3 = c3; + } + + public void SetRow3(float c1, float c2, float c3) + { + this.r3c1 = c1; + this.r3c2 = c2; + this.r3c3 = c3; + } + + public void SetColumn1(float r1, float r2, float r3) + { + this.r1c1 = r1; + this.r2c1 = r2; + this.r3c1 = r3; + } + + public void SetColumn2(float r1, float r2, float r3) + { + this.r1c2 = r1; + this.r2c2 = r2; + this.r3c2 = r3; + } + + public void SetColumn3(float r1, float r2, float r3) + { + this.r1c3 = r1; + this.r2c3 = r2; + this.r3c3 = r3; + } + + public static void Add(in F32Matrix3x3 matrix1, in F32Matrix3x3 matrix2, out F32Matrix3x3 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 F32Matrix3x3 minuend, in F32Matrix3x3 subtrahend, out F32Matrix3x3 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 F32Matrix3x3 multiplicand, float multiplier, out F32Matrix3x3 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 F32Matrix3x3 dividend, float divisor, out F32Matrix3x3 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( + float weight1, in F32Matrix3x3 matrix1, + float weight2, in F32Matrix3x3 matrix2, + out F32Matrix3x3 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( + float weight1, in F32Matrix3x3 matrix1, + float weight2, in F32Matrix3x3 matrix2, + float weight3, in F32Matrix3x3 matrix3, + out F32Matrix3x3 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( + float weight1, in F32Matrix3x3 matrix1, + float weight2, in F32Matrix3x3 matrix2, + float weight3, in F32Matrix3x3 matrix3, + float weight4, in F32Matrix3x3 matrix4, + out F32Matrix3x3 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( + float weight1, in F32Matrix3x3 matrix1, + float weight2, in F32Matrix3x3 matrix2, + float weight3, in F32Matrix3x3 matrix3, + float weight4, in F32Matrix3x3 matrix4, + float weight5, in F32Matrix3x3 matrix5, + out F32Matrix3x3 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 F32Matrix3x3 matrix, in F32Vector3 vector, out F32Vector3 result) + { + float x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2 + matrix.r1c3 * vector.x3; + float x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2 + matrix.r2c3 * vector.x3; + float 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 F32Vector3 vector, in F32Matrix3x3 matrix, out F32Vector3 result) + { + float x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1 + vector.x3 * matrix.r3c1; + float x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2 + vector.x3 * matrix.r3c2; + float 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 F32Matrix3x3 matrix) + { + matrix.r1c1 = 0.0f; + matrix.r1c2 = 0.0f; + matrix.r1c3 = 0.0f; + + matrix.r2c1 = 0.0f; + matrix.r2c2 = 0.0f; + matrix.r2c3 = 0.0f; + + matrix.r3c1 = 0.0f; + matrix.r3c2 = 0.0f; + matrix.r3c3 = 0.0f; + } + + public static void LoadIdentity(out F32Matrix3x3 matrix) + { + matrix.r1c1 = 1.0f; + matrix.r1c2 = 0.0f; + matrix.r1c3 = 0.0f; + + matrix.r2c1 = 0.0f; + matrix.r2c2 = 1.0f; + matrix.r2c3 = 0.0f; + + matrix.r3c1 = 0.0f; + matrix.r3c2 = 0.0f; + matrix.r3c3 = 1.0f; + } + + public static void LoadDiagonal(float d1, float d2, float d3, out F32Matrix3x3 matrix) + { + matrix.r1c1 = d1; + matrix.r1c2 = 0.0f; + matrix.r1c3 = 0.0f; + + matrix.r2c1 = 0.0f; + matrix.r2c2 = d2; + matrix.r2c3 = 0.0f; + + matrix.r3c1 = 0.0f; + matrix.r3c2 = 0.0f; + matrix.r3c3 = d3; + } + } +} diff --git a/Geometry/SPMatrixProduct.cs b/BGC/F32MatrixProduct.cs similarity index 87% rename from Geometry/SPMatrixProduct.cs rename to BGC/F32MatrixProduct.cs index 1842c13..d443d95 100644 --- a/Geometry/SPMatrixProduct.cs +++ b/BGC/F32MatrixProduct.cs @@ -20,11 +20,11 @@ using System; * Author: Andrey Pokidov * Date: 11 Nov 2024 */ -namespace Geometry +namespace BGC { - public class SPMatrixProduct + public class F32MatrixProduct { - public static void Get2x2At2x2(in SPMatrix2x2 left, in SPMatrix2x2 right, out SPMatrix2x2 product) + public static void Get2x2At2x2(in F32Matrix2x2 left, in F32Matrix2x2 right, out F32Matrix2x2 product) { float r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1; float r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2; @@ -39,7 +39,7 @@ namespace Geometry product.r2c2 = r2c2; } - public static void Get2x2At3x2(in SPMatrix2x2 left, in SPMatrix3x2 right, out SPMatrix3x2 product) + public static void Get2x2At3x2(in F32Matrix2x2 left, in F32Matrix3x2 right, out F32Matrix3x2 product) { float r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1; float r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2; @@ -58,7 +58,7 @@ namespace Geometry product.r2c3 = r2c3; } - public static void Get2x3At2x2(in SPMatrix2x3 left, in SPMatrix2x2 right, out SPMatrix2x3 product) + public static void Get2x3At2x2(in F32Matrix2x3 left, in F32Matrix2x2 right, out F32Matrix2x3 product) { float r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1; float r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2; @@ -79,7 +79,7 @@ namespace Geometry product.r3c2 = r3c2; } - public static void Get2x3At3x2(in SPMatrix2x3 left, in SPMatrix3x2 right, out SPMatrix3x3 product) + public static void Get2x3At3x2(in F32Matrix2x3 left, in F32Matrix3x2 right, out F32Matrix3x3 product) { product.r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1; product.r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2; @@ -94,7 +94,7 @@ namespace Geometry product.r3c3 = left.r3c1 * right.r1c2 + left.r3c2 * right.r2c3; } - public static void Get3x2At3x3(in SPMatrix3x2 left, in SPMatrix3x3 right, out SPMatrix3x2 product) + public static void Get3x2At3x3(in F32Matrix3x2 left, in F32Matrix3x3 right, out F32Matrix3x2 product) { float r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1 + left.r1c3 * right.r3c1; float r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2 + left.r1c3 * right.r3c2; @@ -113,7 +113,7 @@ namespace Geometry product.r2c3 = r2c3; } - public static void Get3x2At2x3(in SPMatrix3x2 left, in SPMatrix2x3 right, out SPMatrix2x2 product) + public static void Get3x2At2x3(in F32Matrix3x2 left, in F32Matrix2x3 right, out F32Matrix2x2 product) { product.r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1 + left.r1c3 * right.r3c1; product.r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2 + left.r1c3 * right.r3c2; @@ -122,7 +122,7 @@ namespace Geometry product.r2c2 = left.r2c1 * right.r1c2 + left.r2c2 * right.r2c2 + left.r2c3 * right.r3c2; } - public static void Get3x3At2x3(in SPMatrix3x3 left, in SPMatrix2x3 right, out SPMatrix2x3 product) + public static void Get3x3At2x3(in F32Matrix3x3 left, in F32Matrix2x3 right, out F32Matrix2x3 product) { float r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1 + left.r1c3 * right.r3c1; float r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2 + left.r1c3 * right.r3c2; @@ -143,7 +143,7 @@ namespace Geometry product.r3c2 = r3c2; } - public static void Get3x3At3x3(in SPMatrix3x3 left, in SPMatrix3x3 right, out SPMatrix3x3 product) + public static void Get3x3At3x3(in F32Matrix3x3 left, in F32Matrix3x3 right, out F32Matrix3x3 product) { float r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1 + left.r1c3 * right.r3c1; float r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2 + left.r1c3 * right.r3c2; diff --git a/Geometry/SPQuaternion.cs b/BGC/F32Quaternion.cs similarity index 77% rename from Geometry/SPQuaternion.cs rename to BGC/F32Quaternion.cs index 13bd4a5..a7755c4 100644 --- a/Geometry/SPQuaternion.cs +++ b/BGC/F32Quaternion.cs @@ -1,203 +1,203 @@ -using System; - -namespace Geometry -{ - public struct SPQuaternion - { - public float s0, x1, x2, x3; - - public SPQuaternion(float s0, float x1, float x2, float x3) - { - this.s0 = s0; - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - } - - public SPQuaternion(in SPQuaternion quaternion) - { - this.s0 = quaternion.s0; - this.x1 = quaternion.x1; - this.x2 = quaternion.x2; - this.x3 = quaternion.x3; - } - - public SPQuaternion(in DPQuaternion quaternion) - { - this.s0 = (float)quaternion.s0; - this.x1 = (float)quaternion.x1; - this.x2 = (float)quaternion.x2; - this.x3 = (float)quaternion.x3; - } - - public void Reset() - { - this.s0 = 0.0f; - this.x1 = 0.0f; - this.x2 = 0.0f; - this.x3 = 0.0f; - } - - public void Conjugate() - { - this.x1 = -this.x1; - this.x2 = -this.x2; - this.x3 = -this.x3; - } - - public void SetValues(float s0, float x1, float x2, float x3) - { - this.s0 = s0; - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - } - - public void SetValues(in SPQuaternion quaternion) - { - this.s0 = quaternion.s0; - this.x1 = quaternion.x1; - this.x2 = quaternion.x2; - this.x3 = quaternion.x3; - } - - public void SetValues(in DPQuaternion quaternion) - { - this.s0 = (float)quaternion.s0; - this.x1 = (float)quaternion.x1; - this.x2 = (float)quaternion.x2; - this.x3 = (float)quaternion.x3; - } - - public void SetConjugateOf(in SPQuaternion quaternion) - { - this.s0 = quaternion.s0; - this.x1 = -quaternion.x1; - this.x2 = -quaternion.x2; - this.x3 = -quaternion.x3; - } - - public readonly void MakeRotationMatrix(out SPMatrix3x3 matrix) - { - float s0s0 = this.s0 * this.s0; - float x1x1 = this.x1 * this.x1; - float x2x2 = this.x2 * this.x2; - float x3x3 = this.x3 * this.x3; - - float squareModule = (s0s0 + x1x1) + (x2x2 + x3x3); - - if (-SPUtility.EPSYLON <= squareModule && squareModule <= SPUtility.EPSYLON) - { - SPMatrix3x3.LoadIdentity(out matrix); - return; - } - - float corrector1; - float corrector2; - - if (1.0f - SPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + SPUtility.TWO_EPSYLON) { - corrector1 = 2.0f - squareModule; - corrector2 = 2.0f * corrector1; - } - else { - corrector1 = 1.0f / squareModule; - corrector2 = 2.0f / squareModule; - } - - float s0x1 = this.s0 * this.x1; - float s0x2 = this.s0 * this.x2; - float s0x3 = this.s0 * this.x3; - float x1x2 = this.x1 * this.x2; - float x1x3 = this.x1 * this.x3; - float x2x3 = this.x2 * this.x3; - - matrix.r1c1 = corrector1 * ((s0s0 + x1x1) - (x2x2 + x3x3)); - matrix.r2c2 = corrector1 * ((s0s0 + x2x2) - (x1x1 + x3x3)); - matrix.r3c3 = corrector1 * ((s0s0 + x3x3) - (x1x1 + x2x2)); - - matrix.r1c2 = corrector2 * (x1x2 - s0x3); - matrix.r2c3 = corrector2 * (x2x3 - s0x1); - matrix.r3c1 = corrector2 * (x1x3 - s0x2); - - matrix.r2c1 = corrector2 * (x1x2 + s0x3); - matrix.r3c2 = corrector2 * (x2x3 + s0x1); - matrix.r1c3 = corrector2 * (x1x3 + s0x2); - } - - public readonly void MakeReverseMatrix(out SPMatrix3x3 matrix) - { - float s0s0 = this.s0 * this.s0; - float x1x1 = this.x1 * this.x1; - float x2x2 = this.x2 * this.x2; - float x3x3 = this.x3 * this.x3; - - float squareModule = (s0s0 + x1x1) + (x2x2 + x3x3); - - if (-SPUtility.EPSYLON <= squareModule && squareModule <= SPUtility.EPSYLON) - { - SPMatrix3x3.LoadIdentity(out matrix); - return; - } - - float corrector1; - float corrector2; - - if (1.0f - SPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + SPUtility.TWO_EPSYLON) { - corrector1 = 2.0f - squareModule; - corrector2 = 2.0f * corrector1; - } - else { - corrector1 = 1.0f / squareModule; - corrector2 = 2.0f / squareModule; - } - - float s0x1 = this.s0 * this.x1; - float s0x2 = this.s0 * this.x2; - float s0x3 = this.s0 * this.x3; - float x1x2 = this.x1 * this.x2; - float x1x3 = this.x1 * this.x3; - float x2x3 = this.x2 * this.x3; - - matrix.r1c1 = corrector1 * ((s0s0 + x1x1) - (x2x2 + x3x3)); - matrix.r2c2 = corrector1 * ((s0s0 + x2x2) - (x1x1 + x3x3)); - matrix.r3c3 = corrector1 * ((s0s0 + x3x3) - (x1x1 + x2x2)); - - matrix.r1c2 = corrector2 * (x1x2 + s0x3); - matrix.r2c3 = corrector2 * (x2x3 + s0x1); - matrix.r3c1 = corrector2 * (x1x3 + s0x2); - - matrix.r2c1 = corrector2 * (x1x2 - s0x3); - matrix.r3c2 = corrector2 * (x2x3 - s0x1); - matrix.r1c3 = corrector2 * (x1x3 - s0x2); - } - - public static void Add(in SPQuaternion quaternion1, in SPQuaternion quaternion2, out SPQuaternion sum) - { - sum.s0 = quaternion1.s0 + quaternion2.s0; - sum.x1 = quaternion1.x1 + quaternion2.x1; - sum.x2 = quaternion1.x2 + quaternion2.x2; - sum.x3 = quaternion1.x3 + quaternion2.x3; - } - - public static void Subtract(in SPQuaternion minuend, in SPQuaternion subtrahend, out SPQuaternion difference) - { - difference.s0 = minuend.s0 - subtrahend.s0; - difference.x1 = minuend.x1 - subtrahend.x1; - difference.x2 = minuend.x2 - subtrahend.x2; - difference.x3 = minuend.x3 - subtrahend.x3; - } - - public static void Multiply(in SPQuaternion left, in SPQuaternion right, out SPQuaternion product) - { - float s0 = (left.s0 * right.s0 - left.x1 * right.x1) - (left.x2 * right.x2 + left.x3 * right.x3); - float x1 = (left.x1 * right.s0 + left.s0 * right.x1) - (left.x3 * right.x2 - left.x2 * right.x3); - float x2 = (left.x2 * right.s0 + left.s0 * right.x2) - (left.x1 * right.x3 - left.x3 * right.x1); - float x3 = (left.x3 * right.s0 + left.s0 * right.x3) - (left.x2 * right.x1 - left.x1 * right.x2); - - product.s0 = s0; - product.x1 = x1; - product.x2 = x2; - product.x3 = x3; - } - } -} +using System; + +namespace BGC +{ + public struct F32Quaternion + { + public float s0, x1, x2, x3; + + public F32Quaternion(float s0, float x1, float x2, float x3) + { + this.s0 = s0; + this.x1 = x1; + this.x2 = x2; + this.x3 = x3; + } + + public F32Quaternion(in F32Quaternion quaternion) + { + this.s0 = quaternion.s0; + this.x1 = quaternion.x1; + this.x2 = quaternion.x2; + this.x3 = quaternion.x3; + } + + public F32Quaternion(in F64Quaternion quaternion) + { + this.s0 = (float)quaternion.s0; + this.x1 = (float)quaternion.x1; + this.x2 = (float)quaternion.x2; + this.x3 = (float)quaternion.x3; + } + + public void Reset() + { + this.s0 = 0.0f; + this.x1 = 0.0f; + this.x2 = 0.0f; + this.x3 = 0.0f; + } + + public void Conjugate() + { + this.x1 = -this.x1; + this.x2 = -this.x2; + this.x3 = -this.x3; + } + + public void SetValues(float s0, float x1, float x2, float x3) + { + this.s0 = s0; + this.x1 = x1; + this.x2 = x2; + this.x3 = x3; + } + + public void SetValues(in F32Quaternion quaternion) + { + this.s0 = quaternion.s0; + this.x1 = quaternion.x1; + this.x2 = quaternion.x2; + this.x3 = quaternion.x3; + } + + public void SetValues(in F64Quaternion quaternion) + { + this.s0 = (float)quaternion.s0; + this.x1 = (float)quaternion.x1; + this.x2 = (float)quaternion.x2; + this.x3 = (float)quaternion.x3; + } + + public void SetConjugateOf(in F32Quaternion quaternion) + { + this.s0 = quaternion.s0; + this.x1 = -quaternion.x1; + this.x2 = -quaternion.x2; + this.x3 = -quaternion.x3; + } + + public readonly void MakeRotationMatrix(out F32Matrix3x3 matrix) + { + float s0s0 = this.s0 * this.s0; + float x1x1 = this.x1 * this.x1; + float x2x2 = this.x2 * this.x2; + float x3x3 = this.x3 * this.x3; + + float squareModule = (s0s0 + x1x1) + (x2x2 + x3x3); + + if (-F32Utility.EPSYLON <= squareModule && squareModule <= F32Utility.EPSYLON) + { + F32Matrix3x3.LoadIdentity(out matrix); + return; + } + + float corrector1; + float corrector2; + + if (1.0f - F32Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + F32Utility.TWO_EPSYLON) { + corrector1 = 2.0f - squareModule; + corrector2 = 2.0f * corrector1; + } + else { + corrector1 = 1.0f / squareModule; + corrector2 = 2.0f / squareModule; + } + + float s0x1 = this.s0 * this.x1; + float s0x2 = this.s0 * this.x2; + float s0x3 = this.s0 * this.x3; + float x1x2 = this.x1 * this.x2; + float x1x3 = this.x1 * this.x3; + float x2x3 = this.x2 * this.x3; + + matrix.r1c1 = corrector1 * ((s0s0 + x1x1) - (x2x2 + x3x3)); + matrix.r2c2 = corrector1 * ((s0s0 + x2x2) - (x1x1 + x3x3)); + matrix.r3c3 = corrector1 * ((s0s0 + x3x3) - (x1x1 + x2x2)); + + matrix.r1c2 = corrector2 * (x1x2 - s0x3); + matrix.r2c3 = corrector2 * (x2x3 - s0x1); + matrix.r3c1 = corrector2 * (x1x3 - s0x2); + + matrix.r2c1 = corrector2 * (x1x2 + s0x3); + matrix.r3c2 = corrector2 * (x2x3 + s0x1); + matrix.r1c3 = corrector2 * (x1x3 + s0x2); + } + + public readonly void MakeReverseMatrix(out F32Matrix3x3 matrix) + { + float s0s0 = this.s0 * this.s0; + float x1x1 = this.x1 * this.x1; + float x2x2 = this.x2 * this.x2; + float x3x3 = this.x3 * this.x3; + + float squareModule = (s0s0 + x1x1) + (x2x2 + x3x3); + + if (-F32Utility.EPSYLON <= squareModule && squareModule <= F32Utility.EPSYLON) + { + F32Matrix3x3.LoadIdentity(out matrix); + return; + } + + float corrector1; + float corrector2; + + if (1.0f - F32Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + F32Utility.TWO_EPSYLON) { + corrector1 = 2.0f - squareModule; + corrector2 = 2.0f * corrector1; + } + else { + corrector1 = 1.0f / squareModule; + corrector2 = 2.0f / squareModule; + } + + float s0x1 = this.s0 * this.x1; + float s0x2 = this.s0 * this.x2; + float s0x3 = this.s0 * this.x3; + float x1x2 = this.x1 * this.x2; + float x1x3 = this.x1 * this.x3; + float x2x3 = this.x2 * this.x3; + + matrix.r1c1 = corrector1 * ((s0s0 + x1x1) - (x2x2 + x3x3)); + matrix.r2c2 = corrector1 * ((s0s0 + x2x2) - (x1x1 + x3x3)); + matrix.r3c3 = corrector1 * ((s0s0 + x3x3) - (x1x1 + x2x2)); + + matrix.r1c2 = corrector2 * (x1x2 + s0x3); + matrix.r2c3 = corrector2 * (x2x3 + s0x1); + matrix.r3c1 = corrector2 * (x1x3 + s0x2); + + matrix.r2c1 = corrector2 * (x1x2 - s0x3); + matrix.r3c2 = corrector2 * (x2x3 - s0x1); + matrix.r1c3 = corrector2 * (x1x3 - s0x2); + } + + public static void Add(in F32Quaternion quaternion1, in F32Quaternion quaternion2, out F32Quaternion sum) + { + sum.s0 = quaternion1.s0 + quaternion2.s0; + sum.x1 = quaternion1.x1 + quaternion2.x1; + sum.x2 = quaternion1.x2 + quaternion2.x2; + sum.x3 = quaternion1.x3 + quaternion2.x3; + } + + public static void Subtract(in F32Quaternion minuend, in F32Quaternion subtrahend, out F32Quaternion difference) + { + difference.s0 = minuend.s0 - subtrahend.s0; + difference.x1 = minuend.x1 - subtrahend.x1; + difference.x2 = minuend.x2 - subtrahend.x2; + difference.x3 = minuend.x3 - subtrahend.x3; + } + + public static void Multiply(in F32Quaternion left, in F32Quaternion right, out F32Quaternion product) + { + float s0 = (left.s0 * right.s0 - left.x1 * right.x1) - (left.x2 * right.x2 + left.x3 * right.x3); + float x1 = (left.x1 * right.s0 + left.s0 * right.x1) - (left.x3 * right.x2 - left.x2 * right.x3); + float x2 = (left.x2 * right.s0 + left.s0 * right.x2) - (left.x1 * right.x3 - left.x3 * right.x1); + float x3 = (left.x3 * right.s0 + left.s0 * right.x3) - (left.x2 * right.x1 - left.x1 * right.x2); + + product.s0 = s0; + product.x1 = x1; + product.x2 = x2; + product.x3 = x3; + } + } +} diff --git a/BGC/F32Radians.cs b/BGC/F32Radians.cs new file mode 100644 index 0000000..4ee56d7 --- /dev/null +++ b/BGC/F32Radians.cs @@ -0,0 +1,76 @@ + +/* + * Author: Andrey Pokidov + * Date: 18 Nov 2024 + */ + +namespace BGC +{ + public class F32Radians + { + public const float PI = 3.1415926536f; + public const float TWO_PI = 6.2831853072f; + public const float HALF_OF_PI = 1.5707963268f; + public const float THIRD_OF_PI = 1.0471975512f; + public const float FOURTH_OF_PI = 0.7853981634f; + public const float SIXTH_OF_PI = 0.5235987756f; + + public const float DEGREES_IN_RADIAN = 57.295779513f; + public const float TURNS_IN_RADIAN = 0.1591549431f; + + public static float ToDegrees(float radians) + { + return radians * DEGREES_IN_RADIAN; + } + + public static float ToTurns(float radians) + { + return radians * TURNS_IN_RADIAN; + } + + public static float ToUnits(float radians, AngleUnit toUnit) + { + if (toUnit == AngleUnit.DEGREES) + { + return radians * DEGREES_IN_RADIAN; + } + + if (toUnit == AngleUnit.TURNS) + { + return radians * TURNS_IN_RADIAN; + } + + return radians; + } + + public static float Normalize(float radians, AngleRange range) + { + if (range == AngleRange.UNSIGNED_RANGE) + { + if (0.0 <= radians && radians < TWO_PI) + { + return radians; + } + + } + else + { + if (-PI < radians && radians <= PI) + { + return radians; + } + } + + float turns = radians * TURNS_IN_RADIAN; + + turns -= MathF.Floor(turns); + + if (range == AngleRange.SIGNED_RANGE && turns > 0.5f) + { + turns -= 1.0f; + } + + return turns * TWO_PI; + } + } +} diff --git a/Geometry/SPRotation3.cs b/BGC/F32Rotation3.cs similarity index 88% rename from Geometry/SPRotation3.cs rename to BGC/F32Rotation3.cs index ce96b64..4a4345d 100644 --- a/Geometry/SPRotation3.cs +++ b/BGC/F32Rotation3.cs @@ -21,15 +21,15 @@ using System; * Date: 2 Feb 2019 */ -namespace Geometry +namespace BGC { - public struct SPRotation3 + public struct F32Rotation3 { private float angle; - private SPVector3 axis; + private F32Vector3 axis; - public SPRotation3(SPRotation3 rotation) + public F32Rotation3(F32Rotation3 rotation) { this.angle = rotation.angle; this.axis = rotation.axis; diff --git a/BGC/F32Turns.cs b/BGC/F32Turns.cs new file mode 100644 index 0000000..437d172 --- /dev/null +++ b/BGC/F32Turns.cs @@ -0,0 +1,63 @@ + +/* + * Author: Andrey Pokidov + * Date: 18 Nov 2024 + */ + +namespace BGC +{ + public class F32Turns + { + public static float ToRadians(float turns) + { + return turns * F32Radians.TWO_PI; + } + + public static float ToDegrees(float turns) + { + return turns * 360.0f; + } + + public static float ToUnits(float turns, AngleUnit toUnit) + { + if (toUnit == AngleUnit.RADIANS) + { + return turns * F32Radians.TWO_PI; + } + + if (toUnit == AngleUnit.DEGREES) + { + return turns * 360.0f; + } + + return turns; + } + + public static float Normalize(float turns, AngleRange range) + { + if (range == AngleRange.UNSIGNED_RANGE) + { + if (0.0f <= turns && turns < 1.0f) + { + return turns; + } + } + else + { + if (-0.5f < turns && turns <= 0.5f) + { + return turns; + } + } + + float rest = turns - MathF.Floor(turns); + + if (range == AngleRange.SIGNED_RANGE && rest > 0.5f) + { + rest -= 1.0f; + } + + return rest; + } + } +} diff --git a/Geometry/SPUtility.cs b/BGC/F32Utility.cs similarity index 88% rename from Geometry/SPUtility.cs rename to BGC/F32Utility.cs index 25a1738..2b3948c 100644 --- a/Geometry/SPUtility.cs +++ b/BGC/F32Utility.cs @@ -1,21 +1,21 @@ -using System; - -namespace Geometry -{ - public class SPUtility - { - public const float EPSYLON = 5E-7f; - public const float TWO_EPSYLON = 1E-6f; - public const float SQUARE_EPSYLON = 2.5E-13f; - - public const float EPSYLON_EFFECTIVENESS_LIMIT = 1.0f; - - public const float ONE_THIRD = 0.333333333f; - public const float ONE_SIXTH = 0.166666667f; - public const float ONE_NINETH = 0.111111111f; - - public const float GOLDEN_RATIO_HIGH = 1.618034f; - public const float GOLDEN_RATIO_LOW = 0.618034f; - } -} - +using System; + +namespace BGC +{ + public class F32Utility + { + public const float EPSYLON = 5E-7f; + public const float TWO_EPSYLON = 1E-6f; + public const float SQUARE_EPSYLON = 2.5E-13f; + + public const float EPSYLON_EFFECTIVENESS_LIMIT = 1.0f; + + public const float ONE_THIRD = 0.333333333f; + public const float ONE_SIXTH = 0.166666667f; + public const float ONE_NINETH = 0.111111111f; + + public const float GOLDEN_RATIO_HIGH = 1.618034f; + public const float GOLDEN_RATIO_LOW = 0.618034f; + } +} + diff --git a/Geometry/SPVector2.cs b/BGC/F32Vector2.cs similarity index 60% rename from Geometry/SPVector2.cs rename to BGC/F32Vector2.cs index 8528097..5d54e23 100644 --- a/Geometry/SPVector2.cs +++ b/BGC/F32Vector2.cs @@ -21,28 +21,28 @@ using System; * Date: 1 Feb 2019 */ -namespace Geometry +namespace BGC { - public struct SPVector2 + public struct F32Vector2 { - public static readonly SPVector2 ZERO = new SPVector2(0.0f, 0.0f); + public static readonly F32Vector2 ZERO = new F32Vector2(0.0f, 0.0f); public float x1; public float x2; - public SPVector2(float x1, float x2) + public F32Vector2(float x1, float x2) { this.x1 = x1; this.x2 = x2; } - public SPVector2(in SPVector2 vector) + public F32Vector2(in F32Vector2 vector) { this.x1 = vector.x1; this.x2 = vector.x2; } - public SPVector2(in DPVector2 vector) + public F32Vector2(in F64Vector2 vector) { this.x1 = (float)vector.x1; this.x2 = (float)vector.x2; @@ -62,12 +62,12 @@ namespace Geometry { float squareModule = this.GetSquareModule(); - if (1.0f - SPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + SPUtility.TWO_EPSYLON) + if (1.0f - F32Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + F32Utility.TWO_EPSYLON) { return 1; } - if (squareModule <= SPUtility.SQUARE_EPSYLON) + if (squareModule <= F32Utility.SQUARE_EPSYLON) { this.Reset(); return 0; @@ -81,23 +81,23 @@ namespace Geometry return 1; } - public readonly SPVector2 GetNormalized() + public readonly F32Vector2 GetNormalized() { float squareModule = this.GetSquareModule(); - if (1.0f - SPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + SPUtility.TWO_EPSYLON) + if (1.0f - F32Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + F32Utility.TWO_EPSYLON) { return this; } - if (squareModule <= SPUtility.SQUARE_EPSYLON) + if (squareModule <= F32Utility.SQUARE_EPSYLON) { return ZERO; } float module = MathF.Sqrt(squareModule); - return new SPVector2( + return new F32Vector2( this.x1 / module, this.x2 / module ); @@ -111,13 +111,13 @@ namespace Geometry public readonly bool IsZero() { - return this.GetSquareModule() <= SPUtility.SQUARE_EPSYLON; + return this.GetSquareModule() <= F32Utility.SQUARE_EPSYLON; } public readonly bool IsUnit() { float squareModule = this.GetSquareModule(); - return 1.0f - SPUtility.TWO_EPSYLON <= squareModule && squareModule <= SPUtility.EPSYLON; + return 1.0f - F32Utility.TWO_EPSYLON <= squareModule && squareModule <= F32Utility.EPSYLON; } public void Reset() @@ -132,25 +132,25 @@ namespace Geometry this.x2 = x2; } - public void SetValues(in SPVector2 vector) + public void SetValues(in F32Vector2 vector) { this.x1 = vector.x1; this.x2 = vector.x2; } - public void SetValues(in DPVector2 vector) + public void SetValues(in F64Vector2 vector) { this.x1 = (float)vector.x1; this.x2 = (float)vector.x2; } - public void SetReverseOf(in SPVector2 vector) + public void SetReverseOf(in F32Vector2 vector) { this.x1 = -vector.x1; this.x2 = -vector.x2; } - public void SetReverseOf(in DPVector2 vector) + public void SetReverseOf(in F64Vector2 vector) { this.x1 = -(float)vector.x1; this.x2 = -(float)vector.x2; @@ -160,34 +160,34 @@ namespace Geometry return String.Format("SPVector2({0}, {1})", this.x1, this.x2); } - public static void Add(in SPVector2 vector1, in SPVector2 vector2, out SPVector2 sum) + public static void Add(in F32Vector2 vector1, in F32Vector2 vector2, out F32Vector2 sum) { sum.x1 = vector1.x1 + vector2.x1; sum.x2 = vector1.x2 + vector2.x2; } - public static void Subtract(in SPVector2 minuend, in SPVector2 subtrahend, out SPVector2 difference) + public static void Subtract(in F32Vector2 minuend, in F32Vector2 subtrahend, out F32Vector2 difference) { difference.x1 = minuend.x1 - subtrahend.x1; difference.x2 = minuend.x2 - subtrahend.x2; } - public static void Muliply(in SPVector2 multiplicand, float multiplier, out SPVector2 product) + public static void Muliply(in F32Vector2 multiplicand, float multiplier, out F32Vector2 product) { product.x1 = multiplicand.x1 * multiplier; product.x2 = multiplicand.x2 * multiplier; } - public static void Divide(in SPVector2 dividend, float divisor, out SPVector2 quotient) + public static void Divide(in F32Vector2 dividend, float divisor, out F32Vector2 quotient) { quotient.x1 = dividend.x1 / divisor; quotient.x2 = dividend.x2 / divisor; } public static void GetWeightedSum2( - float weight1, in SPVector2 vector1, - float weight2, in SPVector2 vector2, - out SPVector2 sum + float weight1, in F32Vector2 vector1, + float weight2, in F32Vector2 vector2, + out F32Vector2 sum ) { sum.x1 = vector1.x1 * weight1 + vector2.x1 * weight2; @@ -195,10 +195,10 @@ namespace Geometry } public static void GetWeightedSum3( - float weight1, in SPVector2 vector1, - float weight2, in SPVector2 vector2, - float weight3, in SPVector2 vector3, - out SPVector2 sum + float weight1, in F32Vector2 vector1, + float weight2, in F32Vector2 vector2, + float weight3, in F32Vector2 vector3, + out F32Vector2 sum ) { sum.x1 = vector1.x1 * weight1 + vector2.x1 * weight2 + vector3.x1 * weight3; @@ -206,11 +206,11 @@ namespace Geometry } public static void GetWeightedSum4( - float weight1, in SPVector2 vector1, - float weight2, in SPVector2 vector2, - float weight3, in SPVector2 vector3, - float weight4, in SPVector2 vector4, - out SPVector2 sum + float weight1, in F32Vector2 vector1, + float weight2, in F32Vector2 vector2, + float weight3, in F32Vector2 vector3, + float weight4, in F32Vector2 vector4, + out F32Vector2 sum ) { sum.x1 = (vector1.x1 * weight1 + vector2.x1 * weight2) + (vector3.x1 * weight3 + vector4.x1 * weight4); @@ -218,12 +218,12 @@ namespace Geometry } public static void GetWeightedSum5( - float weight1, in SPVector2 vector1, - float weight2, in SPVector2 vector2, - float weight3, in SPVector2 vector3, - float weight4, in SPVector2 vector4, - float weight5, in SPVector2 vector5, - out SPVector2 sum + float weight1, in F32Vector2 vector1, + float weight2, in F32Vector2 vector2, + float weight3, in F32Vector2 vector3, + float weight4, in F32Vector2 vector4, + float weight5, in F32Vector2 vector5, + out F32Vector2 sum ) { sum.x1 = (vector1.x1 * weight1 + vector2.x1 * weight2) + (vector3.x1 * weight3 + vector4.x1 * weight4); @@ -231,9 +231,9 @@ namespace Geometry } public static void GetMean2( - in SPVector2 vector1, - in SPVector2 vector2, - out SPVector2 result + in F32Vector2 vector1, + in F32Vector2 vector2, + out F32Vector2 result ) { result.x1 = (vector1.x1 + vector2.x1) * 0.5f; @@ -241,22 +241,22 @@ namespace Geometry } public static void GetMean3( - in SPVector2 vector1, - in SPVector2 vector2, - in SPVector2 vector3, - out SPVector2 result + in F32Vector2 vector1, + in F32Vector2 vector2, + in F32Vector2 vector3, + out F32Vector2 result ) { - result.x1 = (vector1.x1 + vector2.x1 + vector3.x1) * SPUtility.ONE_THIRD; - result.x2 = (vector1.x2 + vector2.x2 + vector3.x2) * SPUtility.ONE_THIRD; + result.x1 = (vector1.x1 + vector2.x1 + vector3.x1) * F32Utility.ONE_THIRD; + result.x2 = (vector1.x2 + vector2.x2 + vector3.x2) * F32Utility.ONE_THIRD; } public static void GetMean4( - in SPVector2 vector1, - in SPVector2 vector2, - in SPVector2 vector3, - in SPVector2 vector4, - out SPVector2 result + in F32Vector2 vector1, + in F32Vector2 vector2, + in F32Vector2 vector3, + in F32Vector2 vector4, + out F32Vector2 result ) { result.x1 = ((vector1.x1 + vector2.x1) + (vector3.x1 + vector4.x1)) * 0.25f; @@ -264,60 +264,60 @@ namespace Geometry } public static void GetMean5( - in SPVector2 vector1, - in SPVector2 vector2, - in SPVector2 vector3, - in SPVector2 vector4, - in SPVector2 vector5, - out SPVector2 result + in F32Vector2 vector1, + in F32Vector2 vector2, + in F32Vector2 vector3, + in F32Vector2 vector4, + in F32Vector2 vector5, + out F32Vector2 result ) { result.x1 = ((vector1.x1 + vector2.x1) + (vector3.x1 + vector4.x1) + vector5.x1) * 0.2f; result.x2 = ((vector1.x2 + vector2.x2) + (vector3.x2 + vector4.x2) + vector5.x2) * 0.2f; } - public static float GetScalarProduct(in SPVector2 vector1, in SPVector2 vector2) + public static float GetScalarProduct(in F32Vector2 vector1, in F32Vector2 vector2) { return vector1.x1 * vector2.x1 + vector1.x2 * vector2.x2; } - public static float GetCrossProduct(in SPVector2 vector1, in SPVector2 vector2) + public static float GetCrossProduct(in F32Vector2 vector1, in F32Vector2 vector2) { return vector1.x1 * vector2.x2 - vector1.x2 * vector2.x1; } - public static float GetAngle(in SPVector2 vector1, in SPVector2 vector2, AngleUnit unit) + public static float GetAngle(in F32Vector2 vector1, in F32Vector2 vector2, AngleUnit unit) { float squareModule1 = vector1.GetSquareModule(); - if (squareModule1 <= SPUtility.SQUARE_EPSYLON) + if (squareModule1 <= F32Utility.SQUARE_EPSYLON) { return 0.0f; } float squareModule2 = vector2.GetSquareModule(); - if (squareModule2 <= SPUtility.SQUARE_EPSYLON) + if (squareModule2 <= F32Utility.SQUARE_EPSYLON) { return 0.0f; } - float cosine = SPVector2.GetScalarProduct(vector1, vector2) / MathF.Sqrt(squareModule1 * squareModule2); + float cosine = F32Vector2.GetScalarProduct(vector1, vector2) / MathF.Sqrt(squareModule1 * squareModule2); - if (1.0f - SPUtility.EPSYLON <= cosine) + if (1.0f - F32Utility.EPSYLON <= cosine) { return 0.0f; } - if (cosine <= -(1.0f - SPUtility.EPSYLON)) + if (cosine <= -(1.0f - F32Utility.EPSYLON)) { - return SPAngle.GetHalfCircle(unit); + return F32Angle.GetHalfCircle(unit); } - return SPAngle.ConvertFromRadians(MathF.Acos(cosine), unit); + return F32Radians.ToUnits(MathF.Acos(cosine), unit); } - public static float GetSquareDistance(in SPVector2 vector1, in SPVector2 vector2) + public static float GetSquareDistance(in F32Vector2 vector1, in F32Vector2 vector2) { float dx1 = vector1.x1 - vector2.x1; float dx2 = vector1.x2 - vector2.x2; @@ -325,29 +325,29 @@ namespace Geometry return dx1 * dx1 + dx2 * dx2; } - public static float GetDistance(in SPVector2 vector1, in SPVector2 vector2) + public static float GetDistance(in F32Vector2 vector1, in F32Vector2 vector2) { return MathF.Sqrt(GetSquareDistance(vector1, vector2)); } - public static bool AreEqual(in SPVector2 vector1, in SPVector2 vector2) + public static bool AreEqual(in F32Vector2 vector1, in F32Vector2 vector2) { float squareModule1 = vector1.GetSquareModule(); float squareModule2 = vector2.GetSquareModule(); float squareModule3 = GetSquareDistance(vector1, vector2); // 2.0f means dimension amount - if (squareModule1 < SPUtility.EPSYLON_EFFECTIVENESS_LIMIT || squareModule2 < SPUtility.EPSYLON_EFFECTIVENESS_LIMIT) + if (squareModule1 < F32Utility.EPSYLON_EFFECTIVENESS_LIMIT || squareModule2 < F32Utility.EPSYLON_EFFECTIVENESS_LIMIT) { - return squareModule3 < (2.0f * SPUtility.SQUARE_EPSYLON); + return squareModule3 < (2.0f * F32Utility.SQUARE_EPSYLON); } if (squareModule1 <= squareModule2) { - return squareModule3 <= (2.0f * SPUtility.SQUARE_EPSYLON) * squareModule2; + return squareModule3 <= (2.0f * F32Utility.SQUARE_EPSYLON) * squareModule2; } - return squareModule3 <= (2.0f * SPUtility.SQUARE_EPSYLON) * squareModule1; + return squareModule3 <= (2.0f * F32Utility.SQUARE_EPSYLON) * squareModule1; } } } diff --git a/Geometry/SPVector3.cs b/BGC/F32Vector3.cs similarity index 66% rename from Geometry/SPVector3.cs rename to BGC/F32Vector3.cs index d911809..0c9c6bf 100644 --- a/Geometry/SPVector3.cs +++ b/BGC/F32Vector3.cs @@ -21,31 +21,31 @@ using System; * Date: 1 Feb 2019 */ -namespace Geometry +namespace BGC { - public struct SPVector3 + public struct F32Vector3 { - public static readonly SPVector3 ZERO = new SPVector3(0.0f, 0.0f, 0.0f); + public static readonly F32Vector3 ZERO = new F32Vector3(0.0f, 0.0f, 0.0f); public float x1; public float x2; public float x3; - public SPVector3(float x1, float x2, float x3) + public F32Vector3(float x1, float x2, float x3) { this.x1 = x1; this.x2 = x2; this.x3 = x3; } - public SPVector3(in SPVector3 vector) + public F32Vector3(in F32Vector3 vector) { this.x1 = vector.x1; this.x2 = vector.x2; this.x3 = vector.x3; } - public SPVector3(in DPVector3 vector) + public F32Vector3(in F64Vector3 vector) { this.x1 = (float)vector.x1; this.x2 = (float)vector.x2; @@ -66,12 +66,12 @@ namespace Geometry { float squareModule = this.GetSquareModule(); - if (1.0f - SPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + SPUtility.TWO_EPSYLON) + if (1.0f - F32Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + F32Utility.TWO_EPSYLON) { return 1; } - if (squareModule <= SPUtility.SQUARE_EPSYLON) + if (squareModule <= F32Utility.SQUARE_EPSYLON) { this.Reset(); return 0; @@ -86,23 +86,23 @@ namespace Geometry return 1; } - public readonly SPVector3 GetNormalized() + public readonly F32Vector3 GetNormalized() { float squareModule = this.GetSquareModule(); - if (1.0f - SPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + SPUtility.TWO_EPSYLON) + if (1.0f - F32Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0f + F32Utility.TWO_EPSYLON) { return this; } - if (squareModule <= SPUtility.SQUARE_EPSYLON) + if (squareModule <= F32Utility.SQUARE_EPSYLON) { return ZERO; } float module = MathF.Sqrt(squareModule); - return new SPVector3( + return new F32Vector3( this.x1 / module, this.x2 / module, this.x3 / module @@ -118,13 +118,13 @@ namespace Geometry public readonly bool IsZero() { - return this.GetSquareModule() <= SPUtility.SQUARE_EPSYLON; + return this.GetSquareModule() <= F32Utility.SQUARE_EPSYLON; } public readonly bool IsUnit() { float squareModule = this.GetSquareModule(); - return 1.0f - SPUtility.TWO_EPSYLON <= squareModule && squareModule <= SPUtility.EPSYLON; + return 1.0f - F32Utility.TWO_EPSYLON <= squareModule && squareModule <= F32Utility.EPSYLON; } public void Reset() @@ -141,28 +141,28 @@ namespace Geometry this.x3 = x3; } - public void SetValues(in DPVector3 vector) + public void SetValues(in F64Vector3 vector) { this.x1 = (float)vector.x1; this.x2 = (float)vector.x2; this.x3 = (float)vector.x3; } - public void SetValues(in SPVector3 vector) + public void SetValues(in F32Vector3 vector) { this.x1 = vector.x1; this.x2 = vector.x2; this.x3 = vector.x3; } - public void SetReverseOf(in SPVector3 vector) + public void SetReverseOf(in F32Vector3 vector) { this.x1 = -vector.x1; this.x2 = -vector.x2; this.x3 = -vector.x3; } - public void SetReverseOf(in DPVector3 vector) + public void SetReverseOf(in F64Vector3 vector) { this.x1 = -(float)vector.x1; this.x2 = -(float)vector.x2; @@ -174,28 +174,28 @@ namespace Geometry return String.Format("SPVector3({0}, {1}, {2})", this.x1, this.x2, this.x3); } - public static void Add(in SPVector3 vector1, in SPVector3 vector2, out SPVector3 sum) + public static void Add(in F32Vector3 vector1, in F32Vector3 vector2, out F32Vector3 sum) { sum.x1 = vector1.x1 + vector2.x1; sum.x2 = vector1.x2 + vector2.x2; sum.x3 = vector1.x3 + vector2.x3; } - public static void Subtract(in SPVector3 minuend, in SPVector3 subtrahend, out SPVector3 difference) + public static void Subtract(in F32Vector3 minuend, in F32Vector3 subtrahend, out F32Vector3 difference) { difference.x1 = minuend.x1 - subtrahend.x1; difference.x2 = minuend.x2 - subtrahend.x2; difference.x3 = minuend.x3 - subtrahend.x3; } - public static void Muliply(in SPVector3 multiplicand, float multiplier, out SPVector3 product) + public static void Muliply(in F32Vector3 multiplicand, float multiplier, out F32Vector3 product) { product.x1 = multiplicand.x1 * multiplier; product.x2 = multiplicand.x2 * multiplier; product.x3 = multiplicand.x3 * multiplier; } - public static void Divide(in SPVector3 dividend, float divisor, out SPVector3 quotient) + public static void Divide(in F32Vector3 dividend, float divisor, out F32Vector3 quotient) { quotient.x1 = dividend.x1 / divisor; quotient.x2 = dividend.x2 / divisor; @@ -203,9 +203,9 @@ namespace Geometry } public static void GetWeightedSum2( - float weight1, in SPVector3 vector1, - float weight2, in SPVector3 vector2, - out SPVector3 sum + float weight1, in F32Vector3 vector1, + float weight2, in F32Vector3 vector2, + out F32Vector3 sum ) { sum.x1 = vector1.x1 * weight1 + vector2.x1 * weight2; @@ -214,10 +214,10 @@ namespace Geometry } public static void GetWeightedSum3( - float weight1, in SPVector3 vector1, - float weight2, in SPVector3 vector2, - float weight3, in SPVector3 vector3, - out SPVector3 sum + float weight1, in F32Vector3 vector1, + float weight2, in F32Vector3 vector2, + float weight3, in F32Vector3 vector3, + out F32Vector3 sum ) { sum.x1 = vector1.x1 * weight1 + vector2.x1 * weight2 + vector3.x1 * weight3; @@ -226,11 +226,11 @@ namespace Geometry } public static void GetWeightedSum4( - float weight1, in SPVector3 vector1, - float weight2, in SPVector3 vector2, - float weight3, in SPVector3 vector3, - float weight4, in SPVector3 vector4, - out SPVector3 sum + float weight1, in F32Vector3 vector1, + float weight2, in F32Vector3 vector2, + float weight3, in F32Vector3 vector3, + float weight4, in F32Vector3 vector4, + out F32Vector3 sum ) { sum.x1 = (vector1.x1 * weight1 + vector2.x1 * weight2) + (vector3.x1 * weight3 + vector4.x1 * weight4); @@ -239,12 +239,12 @@ namespace Geometry } public static void GetWeightedSum5( - float weight1, in SPVector3 vector1, - float weight2, in SPVector3 vector2, - float weight3, in SPVector3 vector3, - float weight4, in SPVector3 vector4, - float weight5, in SPVector3 vector5, - out SPVector3 sum + float weight1, in F32Vector3 vector1, + float weight2, in F32Vector3 vector2, + float weight3, in F32Vector3 vector3, + float weight4, in F32Vector3 vector4, + float weight5, in F32Vector3 vector5, + out F32Vector3 sum ) { sum.x1 = (vector1.x1 * weight1 + vector2.x1 * weight2) + (vector3.x1 * weight3 + vector4.x1 * weight4) + vector5.x1 * weight5; @@ -253,9 +253,9 @@ namespace Geometry } public static void GetMean2( - in SPVector3 vector1, - in SPVector3 vector2, - out SPVector3 result + in F32Vector3 vector1, + in F32Vector3 vector2, + out F32Vector3 result ) { result.x1 = (vector1.x1 + vector2.x1) * 0.5f; @@ -264,23 +264,23 @@ namespace Geometry } public static void GetMean3( - in SPVector3 vector1, - in SPVector3 vector2, - in SPVector3 vector3, - out SPVector3 result + in F32Vector3 vector1, + in F32Vector3 vector2, + in F32Vector3 vector3, + out F32Vector3 result ) { - result.x1 = (vector1.x1 + vector2.x1 + vector3.x1) * SPUtility.ONE_THIRD; - result.x2 = (vector1.x2 + vector2.x2 + vector3.x2) * SPUtility.ONE_THIRD; - result.x3 = (vector1.x3 + vector2.x3 + vector3.x3) * SPUtility.ONE_THIRD; + result.x1 = (vector1.x1 + vector2.x1 + vector3.x1) * F32Utility.ONE_THIRD; + result.x2 = (vector1.x2 + vector2.x2 + vector3.x2) * F32Utility.ONE_THIRD; + result.x3 = (vector1.x3 + vector2.x3 + vector3.x3) * F32Utility.ONE_THIRD; } public static void GetMean4( - in SPVector3 vector1, - in SPVector3 vector2, - in SPVector3 vector3, - in SPVector3 vector4, - out SPVector3 result + in F32Vector3 vector1, + in F32Vector3 vector2, + in F32Vector3 vector3, + in F32Vector3 vector4, + out F32Vector3 result ) { result.x1 = ((vector1.x1 + vector2.x1) + (vector3.x1 + vector4.x1)) * 0.25f; @@ -289,12 +289,12 @@ namespace Geometry } public static void GetMean5( - in SPVector3 vector1, - in SPVector3 vector2, - in SPVector3 vector3, - in SPVector3 vector4, - in SPVector3 vector5, - out SPVector3 result + in F32Vector3 vector1, + in F32Vector3 vector2, + in F32Vector3 vector3, + in F32Vector3 vector4, + in F32Vector3 vector5, + out F32Vector3 result ) { result.x1 = ((vector1.x1 + vector2.x1) + (vector3.x1 + vector4.x1) + vector5.x1) * 0.2f; @@ -302,12 +302,12 @@ namespace Geometry result.x3 = ((vector1.x3 + vector2.x3) + (vector3.x3 + vector4.x3) + vector5.x3) * 0.2f; } - public static float GetScalarProduct(in SPVector3 vector1, in SPVector3 vector2) + public static float GetScalarProduct(in F32Vector3 vector1, in F32Vector3 vector2) { return vector1.x1 * vector2.x1 + vector1.x2 * vector2.x2 + vector1.x3 * vector2.x3; } - public static void GetCrossProduct(in SPVector3 vector1, in SPVector3 vector2, out SPVector3 result) + public static void GetCrossProduct(in F32Vector3 vector1, in F32Vector3 vector2, out F32Vector3 result) { float x1 = vector1.x2 * vector2.x3 - vector1.x3 * vector2.x2; float x2 = vector1.x3 * vector2.x1 - vector1.x1 * vector2.x3; @@ -318,14 +318,14 @@ namespace Geometry result.x3 = x3; } - public static float GetTripleProduct(in SPVector3 vector1, in SPVector3 vector2, in SPVector3 vector3) + public static float GetTripleProduct(in F32Vector3 vector1, in F32Vector3 vector2, in F32Vector3 vector3) { return vector1.x1 * (vector2.x2 * vector3.x3 - vector2.x3 * vector3.x2) + vector1.x2 * (vector2.x3 * vector3.x1 - vector2.x1 * vector3.x3) + vector1.x3 * (vector2.x1 * vector3.x2 - vector2.x2 * vector3.x1); } - public static void GetDoubleCrossProduct(in SPVector3 vector1, in SPVector3 vector2, in SPVector3 vector3, out SPVector3 result) + public static void GetDoubleCrossProduct(in F32Vector3 vector1, in F32Vector3 vector2, in F32Vector3 vector3, out F32Vector3 result) { // [a x [b x c]] = b * (a, c) - c * (a, b) float ac = GetScalarProduct(vector1, vector3); @@ -336,38 +336,38 @@ namespace Geometry result.x3 = ac * vector2.x3 - ab * vector3.x3; } - public static float GetAngle(in SPVector3 vector1, in SPVector3 vector2, AngleUnit unit) + public static float GetAngle(in F32Vector3 vector1, in F32Vector3 vector2, AngleUnit unit) { float squareModule1 = vector1.GetSquareModule(); - if (squareModule1 <= SPUtility.SQUARE_EPSYLON) + if (squareModule1 <= F32Utility.SQUARE_EPSYLON) { return 0.0f; } float squareModule2 = vector2.GetSquareModule(); - if (squareModule2 <= SPUtility.SQUARE_EPSYLON) + if (squareModule2 <= F32Utility.SQUARE_EPSYLON) { return 0.0f; } - float cosine = SPVector3.GetScalarProduct(vector1, vector2) / MathF.Sqrt(squareModule1 * squareModule2); + float cosine = F32Vector3.GetScalarProduct(vector1, vector2) / MathF.Sqrt(squareModule1 * squareModule2); - if (1.0f - SPUtility.EPSYLON <= cosine) + if (1.0f - F32Utility.EPSYLON <= cosine) { return 0.0f; } - if (cosine <= -(1.0f - SPUtility.EPSYLON)) + if (cosine <= -(1.0f - F32Utility.EPSYLON)) { - return SPAngle.GetHalfCircle(unit); + return F32Angle.GetHalfCircle(unit); } - return SPAngle.ConvertFromRadians(MathF.Acos(cosine), unit); + return F32Radians.ToUnits(MathF.Acos(cosine), unit); } - public static float GetSquareDistance(in SPVector3 vector1, in SPVector3 vector2) + public static float GetSquareDistance(in F32Vector3 vector1, in F32Vector3 vector2) { float dx1 = vector1.x1 - vector2.x1; float dx2 = vector1.x2 - vector2.x2; @@ -376,29 +376,29 @@ namespace Geometry return dx1 * dx1 + dx2 * dx2 + dx3 * dx3; } - public static float GetDistance(in SPVector3 vector1, in SPVector3 vector2) + public static float GetDistance(in F32Vector3 vector1, in F32Vector3 vector2) { return MathF.Sqrt(GetSquareDistance(vector1, vector2)); } - public static bool AreEqual(in SPVector3 vector1, in SPVector3 vector2) + public static bool AreEqual(in F32Vector3 vector1, in F32Vector3 vector2) { float squareModule1 = vector1.GetSquareModule(); float squareModule2 = vector2.GetSquareModule(); float squareModule3 = GetSquareDistance(vector1, vector2); // 3.0f means dimension amount - if (squareModule1 < SPUtility.EPSYLON_EFFECTIVENESS_LIMIT || squareModule2 < SPUtility.EPSYLON_EFFECTIVENESS_LIMIT) + if (squareModule1 < F32Utility.EPSYLON_EFFECTIVENESS_LIMIT || squareModule2 < F32Utility.EPSYLON_EFFECTIVENESS_LIMIT) { - return squareModule3 < (3.0f * SPUtility.SQUARE_EPSYLON); + return squareModule3 < (3.0f * F32Utility.SQUARE_EPSYLON); } if (squareModule1 <= squareModule2) { - return squareModule3 <= (3.0f * SPUtility.SQUARE_EPSYLON) * squareModule2; + return squareModule3 <= (3.0f * F32Utility.SQUARE_EPSYLON) * squareModule2; } - return squareModule3 <= (3.0f * SPUtility.SQUARE_EPSYLON) * squareModule1; + return squareModule3 <= (3.0f * F32Utility.SQUARE_EPSYLON) * squareModule1; } } } diff --git a/Geometry/SPVersor.cs b/BGC/F32Versor.cs similarity index 78% rename from Geometry/SPVersor.cs rename to BGC/F32Versor.cs index 2bf9481..f28306c 100644 --- a/Geometry/SPVersor.cs +++ b/BGC/F32Versor.cs @@ -1,366 +1,366 @@ -/* - * Copyright 2019-2025 Andrey Pokidov - * - * 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. - */ - -/* - * Author: Andrey Pokidov -* Date: 20 Oct 2024 - */ - -namespace Geometry -{ - public struct SPVersor - { - public static readonly SPVersor IDLE = new SPVersor(1.0f, 0.0f, 0.0f, 0.0f, 1.0f); - - private float s0; - private float x1; - private float x2; - private float x3; - private float corrector; - - private SPVersor(float s0, float x1, float x2, float x3, float corrector) - { - this.s0 = s0; - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - this.corrector = corrector; - } - - public SPVersor() - { - this.s0 = 1.0f; - this.x1 = 0.0f; - this.x2 = 0.0f; - this.x3 = 0.0f; - this.corrector = 1.0f; - } - - public SPVersor(float s0, float x1, float x2, float x3) - { - this.s0 = s0; - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - - float squareModule = (s0 * s0 + x1 * x1) + (x2 * x2 + x3 * x3); - - this.corrector = 2.0f - squareModule; - - if (squareModule < 1.0f - SPUtility.TWO_EPSYLON || 1.0f + SPUtility.TWO_EPSYLON < squareModule) - { - this.Normalize(squareModule); - } - else if (s0 < -1.0f + SPUtility.EPSYLON || 1.0f - SPUtility.EPSYLON < s0) - { - this.Reset(); - } - } - - public SPVersor(in SPVersor versor) - { - this.s0 = versor.s0; - this.x1 = versor.x1; - this.x2 = versor.x2; - this.x3 = versor.x3; - this.corrector = versor.corrector; - } - - public SPVersor(in DPVersor versor) - { - this.s0 = (float)versor.GetScalar(); - this.x1 = (float)versor.GetX1(); - this.x2 = (float)versor.GetX2(); - this.x3 = (float)versor.GetX3(); - - float squareModule = (this.s0 * this.s0 + this.x1 * this.x1) + (this.x2 * this.x2 + this.x3 * this.x3); - - this.corrector = 2.0f - squareModule; - - if (squareModule < 1.0f - SPUtility.TWO_EPSYLON || 1.0f + SPUtility.TWO_EPSYLON < squareModule) - { - this.Normalize(squareModule); - } - else if (s0 < -1.0f + SPUtility.EPSYLON || 1.0f - SPUtility.EPSYLON < s0) - { - this.Reset(); - } - } - - public readonly float GetScalar() - { - return this.s0; - } - - public readonly float GetX1() - { - return this.x1; - } - - public readonly float GetX2() - { - return this.x2; - } - - public readonly float GetX3() - { - return this.x3; - } - - public readonly float GetCorrector() - { - return this.corrector; - } - - public readonly bool IsIdle() - { - return this.s0 <= -(1.0f - SPUtility.EPSYLON) || (1.0f - SPUtility.EPSYLON) <= this.s0; - } - - public void Reset() - { - this.s0 = 1.0f; - this.x1 = 0.0f; - this.x2 = 0.0f; - this.x3 = 0.0f; - this.corrector = 1.0f; - } - - public void Invert() - { - this.x1 = -this.x1; - this.x2 = -this.x2; - this.x3 = -this.x3; - } - - public readonly float GetAngle(AngleUnit unit) - { - if (this.s0 <= -(1.0f - SPUtility.TWO_EPSYLON) || 1.0f - SPUtility.TWO_EPSYLON <= this.s0) { - return 0.0f; - } - - if (-SPUtility.EPSYLON <= this.s0 && this.s0 <= SPUtility.EPSYLON) - { - return SPAngle.GetHalfCircle(unit); - } - - return SPAngle.ConvertFromRadians(2.0f * MathF.Acos(s0), unit); - } - - public readonly void MakeRotationMatrix(out SPMatrix3x3 matrix) - { - float s0s0 = this.s0 * this.s0; - float x1x1 = this.x1 * this.x1; - float x2x2 = this.x1 * this.x2; - float x3x3 = this.x1 * this.x3; - - - float s0x1 = this.s0 * this.x1; - float s0x2 = this.s0 * this.x2; - float s0x3 = this.s0 * this.x3; - - float x1x2 = this.x1 * this.x2; - float x1x3 = this.x1 * this.x3; - float x2x3 = this.x2 * this.x3; - - float corrector2 = 2.0f * this.corrector; - - matrix.r1c1 = this.corrector * ((s0s0 + x1x1) - (x2x2 + x3x3)); - matrix.r2c2 = this.corrector * ((s0s0 + x2x2) - (x1x1 + x3x3)); - matrix.r3c3 = this.corrector * ((s0s0 + x3x3) - (x1x1 + x2x2)); - - matrix.r1c2 = corrector2 * (x1x2 - s0x3); - matrix.r2c3 = corrector2 * (x2x3 - s0x1); - matrix.r3c1 = corrector2 * (x1x3 - s0x2); - - matrix.r2c1 = corrector2 * (x1x2 + s0x3); - matrix.r3c2 = corrector2 * (x2x3 + s0x1); - matrix.r1c3 = corrector2 * (x1x3 + s0x2); - } - - public readonly void MakeReverseMatrix(out SPMatrix3x3 matrix) - { - float s0s0 = this.s0 * this.s0; - float x1x1 = this.x1 * this.x1; - float x2x2 = this.x1 * this.x2; - float x3x3 = this.x1 * this.x3; - - - float s0x1 = this.s0 * this.x1; - float s0x2 = this.s0 * this.x2; - float s0x3 = this.s0 * this.x3; - - float x1x2 = this.x1 * this.x2; - float x1x3 = this.x1 * this.x3; - float x2x3 = this.x2 * this.x3; - - float corrector2 = 2.0f * this.corrector; - - matrix.r1c1 = this.corrector * ((s0s0 + x1x1) - (x2x2 + x3x3)); - matrix.r2c2 = this.corrector * ((s0s0 + x2x2) - (x1x1 + x3x3)); - matrix.r3c3 = this.corrector * ((s0s0 + x3x3) - (x1x1 + x2x2)); - - matrix.r1c2 = corrector2 * (x1x2 + s0x3); - matrix.r2c3 = corrector2 * (x2x3 + s0x1); - matrix.r3c1 = corrector2 * (x1x3 + s0x2); - - matrix.r2c1 = corrector2 * (x1x2 - s0x3); - matrix.r3c2 = corrector2 * (x2x3 - s0x1); - matrix.r1c3 = corrector2 * (x1x3 - s0x2); - } - - public void SetValues(float s0, float x1, float x2, float x3) - { - this.s0 = s0; - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - - float squareModule = (s0 * s0 + x1 * x1) + (x2 * x2 + x3 * x3); - - if (squareModule < 1.0f - SPUtility.TWO_EPSYLON || 1.0f + SPUtility.TWO_EPSYLON < squareModule) - { - this.Normalize(squareModule); - return; - } - - if (s0 < -1.0f + SPUtility.EPSYLON || 1.0f - SPUtility.EPSYLON < s0) { - this.Reset(); - return; - } - - this.corrector = 2.0f - squareModule; - } - - public void SetValues(in SPVersor versor) - { - this.s0 = versor.s0; - this.x1 = versor.x1; - this.x2 = versor.x2; - this.x3 = versor.x3; - this.corrector = versor.corrector; - } - - public void SetValues(in DPVersor versor) - { - this.SetValues( - (float)versor.GetScalar(), - (float)versor.GetX1(), - (float)versor.GetX2(), - (float)versor.GetX3() - ); - } - - public void SetInverted(in SPVersor versor) - { - this.s0 = versor.s0; - this.x1 = -versor.x1; - this.x2 = -versor.x2; - this.x3 = -versor.x3; - this.corrector = versor.corrector; - } - - public void SetInverted(in DPVersor versor) - { - this.SetValues( - (float)versor.GetScalar(), - -(float)versor.GetX1(), - -(float)versor.GetX2(), - -(float)versor.GetX3() - ); - } - - public readonly void Turn(in SPVector3 vector, out SPVector3 result) - { - float multiplier = 2.0f * this.corrector; - float tx1 = multiplier * (this.x2 * vector.x3 - this.x3 * vector.x2); - float tx2 = multiplier * (this.x3 * vector.x1 - this.x1 * vector.x3); - float tx3 = multiplier * (this.x1 * vector.x2 - this.x2 * vector.x1); - - float x1 = (vector.x1 + tx1 * this.s0) + (this.x2 * tx3 - this.x3 * tx2); - float x2 = (vector.x2 + tx2 * this.s0) + (this.x3 * tx1 - this.x1 * tx3); - float x3 = (vector.x3 + tx3 * this.s0) + (this.x1 * tx2 - this.x2 * tx1); - - result.x1 = x1; - result.x2 = x2; - result.x3 = x3; - } - - public readonly void TurnBack(in SPVector3 vector, out SPVector3 result) - { - float multiplier = 2.0f * this.corrector; - float tx1 = multiplier * (this.x2 * vector.x3 - this.x3 * vector.x2); - float tx2 = multiplier * (this.x3 * vector.x1 - this.x1 * vector.x3); - float tx3 = multiplier * (this.x1 * vector.x2 - this.x2 * vector.x1); - - float x1 = (vector.x1 - tx1 * this.s0) + (this.x2 * tx3 - this.x3 * tx2); - float x2 = (vector.x2 - tx2 * this.s0) + (this.x3 * tx1 - this.x1 * tx3); - float x3 = (vector.x3 - tx3 * this.s0) + (this.x1 * tx2 - this.x2 * tx1); - - result.x1 = x1; - result.x2 = x2; - result.x3 = x3; - } - - private void Normalize(float squareModule) - { - if (squareModule <= SPUtility.SQUARE_EPSYLON || (this.x1 * this.x1 + this.x2 * this.x2 + this.x3 * this.x3) <= SPUtility.SQUARE_EPSYLON * squareModule) - { - this.Reset(); - return; - } - - float module = MathF.Sqrt(squareModule); - - this.s0 /= module; - this.x1 /= module; - this.x2 /= module; - this.x3 /= module; - - this.corrector = (this.s0 * this.s0 + this.x1 * this.x1) + (this.x2 * this.x2 + this.x3 * this.x3); - } - - public static void Combine(in SPVersor second, in SPVersor first, out SPVersor result) - { - float s0 = (second.s0 * first.s0 - second.x1 * first.x1) - (second.x2 * first.x2 + second.x3 * first.x3); - float x1 = (second.x1 * first.s0 + second.s0 * first.x1) - (second.x3 * first.x2 - second.x2 * first.x3); - float x2 = (second.x2 * first.s0 + second.s0 * first.x2) - (second.x1 * first.x3 - second.x3 * first.x1); - float x3 = (second.x3 * first.s0 + second.s0 * first.x3) - (second.x2 * first.x1 - second.x1 * first.x2); - - float squareModule = (s0 * s0 + x1 * x1) + (x2 * x2 + x3 * x3); - - result.corrector = 2.0f - squareModule; - result.s0 = s0; - result.x1 = x1; - result.x2 = x2; - result.x3 = x3; - - if (squareModule < 1.0f - SPUtility.TWO_EPSYLON || 1.0f + SPUtility.TWO_EPSYLON < squareModule) - { - result.Normalize(squareModule); - } - } - - public static void LoadIdle(out SPVersor versor) - { - versor.corrector = 1.0f; - versor.s0 = 1.0f; - versor.x1 = 0.0f; - versor.x2 = 0.0f; - versor.x3 = 0.0f; - } - } -} +/* + * Copyright 2019-2025 Andrey Pokidov + * + * 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. + */ + +/* + * Author: Andrey Pokidov +* Date: 20 Oct 2024 + */ + +namespace BGC +{ + public struct F32Versor + { + public static readonly F32Versor IDLE = new F32Versor(1.0f, 0.0f, 0.0f, 0.0f, 1.0f); + + private float s0; + private float x1; + private float x2; + private float x3; + private float corrector; + + private F32Versor(float s0, float x1, float x2, float x3, float corrector) + { + this.s0 = s0; + this.x1 = x1; + this.x2 = x2; + this.x3 = x3; + this.corrector = corrector; + } + + public F32Versor() + { + this.s0 = 1.0f; + this.x1 = 0.0f; + this.x2 = 0.0f; + this.x3 = 0.0f; + this.corrector = 1.0f; + } + + public F32Versor(float s0, float x1, float x2, float x3) + { + this.s0 = s0; + this.x1 = x1; + this.x2 = x2; + this.x3 = x3; + + float squareModule = (s0 * s0 + x1 * x1) + (x2 * x2 + x3 * x3); + + this.corrector = 2.0f - squareModule; + + if (squareModule < 1.0f - F32Utility.TWO_EPSYLON || 1.0f + F32Utility.TWO_EPSYLON < squareModule) + { + this.Normalize(squareModule); + } + else if (s0 < -1.0f + F32Utility.EPSYLON || 1.0f - F32Utility.EPSYLON < s0) + { + this.Reset(); + } + } + + public F32Versor(in F32Versor versor) + { + this.s0 = versor.s0; + this.x1 = versor.x1; + this.x2 = versor.x2; + this.x3 = versor.x3; + this.corrector = versor.corrector; + } + + public F32Versor(in F64Versor versor) + { + this.s0 = (float)versor.GetScalar(); + this.x1 = (float)versor.GetX1(); + this.x2 = (float)versor.GetX2(); + this.x3 = (float)versor.GetX3(); + + float squareModule = (this.s0 * this.s0 + this.x1 * this.x1) + (this.x2 * this.x2 + this.x3 * this.x3); + + this.corrector = 2.0f - squareModule; + + if (squareModule < 1.0f - F32Utility.TWO_EPSYLON || 1.0f + F32Utility.TWO_EPSYLON < squareModule) + { + this.Normalize(squareModule); + } + else if (s0 < -1.0f + F32Utility.EPSYLON || 1.0f - F32Utility.EPSYLON < s0) + { + this.Reset(); + } + } + + public readonly float GetScalar() + { + return this.s0; + } + + public readonly float GetX1() + { + return this.x1; + } + + public readonly float GetX2() + { + return this.x2; + } + + public readonly float GetX3() + { + return this.x3; + } + + public readonly float GetCorrector() + { + return this.corrector; + } + + public readonly bool IsIdle() + { + return this.s0 <= -(1.0f - F32Utility.EPSYLON) || (1.0f - F32Utility.EPSYLON) <= this.s0; + } + + public void Reset() + { + this.s0 = 1.0f; + this.x1 = 0.0f; + this.x2 = 0.0f; + this.x3 = 0.0f; + this.corrector = 1.0f; + } + + public void Invert() + { + this.x1 = -this.x1; + this.x2 = -this.x2; + this.x3 = -this.x3; + } + + public readonly float GetAngle(AngleUnit unit) + { + if (this.s0 <= -(1.0f - F32Utility.TWO_EPSYLON) || 1.0f - F32Utility.TWO_EPSYLON <= this.s0) { + return 0.0f; + } + + if (-F32Utility.EPSYLON <= this.s0 && this.s0 <= F32Utility.EPSYLON) + { + return F32Angle.GetHalfCircle(unit); + } + + return F32Radians.ToUnits(2.0f * MathF.Acos(s0), unit); + } + + public readonly void MakeRotationMatrix(out F32Matrix3x3 matrix) + { + float s0s0 = this.s0 * this.s0; + float x1x1 = this.x1 * this.x1; + float x2x2 = this.x1 * this.x2; + float x3x3 = this.x1 * this.x3; + + + float s0x1 = this.s0 * this.x1; + float s0x2 = this.s0 * this.x2; + float s0x3 = this.s0 * this.x3; + + float x1x2 = this.x1 * this.x2; + float x1x3 = this.x1 * this.x3; + float x2x3 = this.x2 * this.x3; + + float corrector2 = 2.0f * this.corrector; + + matrix.r1c1 = this.corrector * ((s0s0 + x1x1) - (x2x2 + x3x3)); + matrix.r2c2 = this.corrector * ((s0s0 + x2x2) - (x1x1 + x3x3)); + matrix.r3c3 = this.corrector * ((s0s0 + x3x3) - (x1x1 + x2x2)); + + matrix.r1c2 = corrector2 * (x1x2 - s0x3); + matrix.r2c3 = corrector2 * (x2x3 - s0x1); + matrix.r3c1 = corrector2 * (x1x3 - s0x2); + + matrix.r2c1 = corrector2 * (x1x2 + s0x3); + matrix.r3c2 = corrector2 * (x2x3 + s0x1); + matrix.r1c3 = corrector2 * (x1x3 + s0x2); + } + + public readonly void MakeReverseMatrix(out F32Matrix3x3 matrix) + { + float s0s0 = this.s0 * this.s0; + float x1x1 = this.x1 * this.x1; + float x2x2 = this.x1 * this.x2; + float x3x3 = this.x1 * this.x3; + + + float s0x1 = this.s0 * this.x1; + float s0x2 = this.s0 * this.x2; + float s0x3 = this.s0 * this.x3; + + float x1x2 = this.x1 * this.x2; + float x1x3 = this.x1 * this.x3; + float x2x3 = this.x2 * this.x3; + + float corrector2 = 2.0f * this.corrector; + + matrix.r1c1 = this.corrector * ((s0s0 + x1x1) - (x2x2 + x3x3)); + matrix.r2c2 = this.corrector * ((s0s0 + x2x2) - (x1x1 + x3x3)); + matrix.r3c3 = this.corrector * ((s0s0 + x3x3) - (x1x1 + x2x2)); + + matrix.r1c2 = corrector2 * (x1x2 + s0x3); + matrix.r2c3 = corrector2 * (x2x3 + s0x1); + matrix.r3c1 = corrector2 * (x1x3 + s0x2); + + matrix.r2c1 = corrector2 * (x1x2 - s0x3); + matrix.r3c2 = corrector2 * (x2x3 - s0x1); + matrix.r1c3 = corrector2 * (x1x3 - s0x2); + } + + public void SetValues(float s0, float x1, float x2, float x3) + { + this.s0 = s0; + this.x1 = x1; + this.x2 = x2; + this.x3 = x3; + + float squareModule = (s0 * s0 + x1 * x1) + (x2 * x2 + x3 * x3); + + if (squareModule < 1.0f - F32Utility.TWO_EPSYLON || 1.0f + F32Utility.TWO_EPSYLON < squareModule) + { + this.Normalize(squareModule); + return; + } + + if (s0 < -1.0f + F32Utility.EPSYLON || 1.0f - F32Utility.EPSYLON < s0) { + this.Reset(); + return; + } + + this.corrector = 2.0f - squareModule; + } + + public void SetValues(in F32Versor versor) + { + this.s0 = versor.s0; + this.x1 = versor.x1; + this.x2 = versor.x2; + this.x3 = versor.x3; + this.corrector = versor.corrector; + } + + public void SetValues(in F64Versor versor) + { + this.SetValues( + (float)versor.GetScalar(), + (float)versor.GetX1(), + (float)versor.GetX2(), + (float)versor.GetX3() + ); + } + + public void SetInverted(in F32Versor versor) + { + this.s0 = versor.s0; + this.x1 = -versor.x1; + this.x2 = -versor.x2; + this.x3 = -versor.x3; + this.corrector = versor.corrector; + } + + public void SetInverted(in F64Versor versor) + { + this.SetValues( + (float)versor.GetScalar(), + -(float)versor.GetX1(), + -(float)versor.GetX2(), + -(float)versor.GetX3() + ); + } + + public readonly void Turn(in F32Vector3 vector, out F32Vector3 result) + { + float multiplier = 2.0f * this.corrector; + float tx1 = multiplier * (this.x2 * vector.x3 - this.x3 * vector.x2); + float tx2 = multiplier * (this.x3 * vector.x1 - this.x1 * vector.x3); + float tx3 = multiplier * (this.x1 * vector.x2 - this.x2 * vector.x1); + + float x1 = (vector.x1 + tx1 * this.s0) + (this.x2 * tx3 - this.x3 * tx2); + float x2 = (vector.x2 + tx2 * this.s0) + (this.x3 * tx1 - this.x1 * tx3); + float x3 = (vector.x3 + tx3 * this.s0) + (this.x1 * tx2 - this.x2 * tx1); + + result.x1 = x1; + result.x2 = x2; + result.x3 = x3; + } + + public readonly void TurnBack(in F32Vector3 vector, out F32Vector3 result) + { + float multiplier = 2.0f * this.corrector; + float tx1 = multiplier * (this.x2 * vector.x3 - this.x3 * vector.x2); + float tx2 = multiplier * (this.x3 * vector.x1 - this.x1 * vector.x3); + float tx3 = multiplier * (this.x1 * vector.x2 - this.x2 * vector.x1); + + float x1 = (vector.x1 - tx1 * this.s0) + (this.x2 * tx3 - this.x3 * tx2); + float x2 = (vector.x2 - tx2 * this.s0) + (this.x3 * tx1 - this.x1 * tx3); + float x3 = (vector.x3 - tx3 * this.s0) + (this.x1 * tx2 - this.x2 * tx1); + + result.x1 = x1; + result.x2 = x2; + result.x3 = x3; + } + + private void Normalize(float squareModule) + { + if (squareModule <= F32Utility.SQUARE_EPSYLON || (this.x1 * this.x1 + this.x2 * this.x2 + this.x3 * this.x3) <= F32Utility.SQUARE_EPSYLON * squareModule) + { + this.Reset(); + return; + } + + float module = MathF.Sqrt(squareModule); + + this.s0 /= module; + this.x1 /= module; + this.x2 /= module; + this.x3 /= module; + + this.corrector = (this.s0 * this.s0 + this.x1 * this.x1) + (this.x2 * this.x2 + this.x3 * this.x3); + } + + public static void Combine(in F32Versor second, in F32Versor first, out F32Versor result) + { + float s0 = (second.s0 * first.s0 - second.x1 * first.x1) - (second.x2 * first.x2 + second.x3 * first.x3); + float x1 = (second.x1 * first.s0 + second.s0 * first.x1) - (second.x3 * first.x2 - second.x2 * first.x3); + float x2 = (second.x2 * first.s0 + second.s0 * first.x2) - (second.x1 * first.x3 - second.x3 * first.x1); + float x3 = (second.x3 * first.s0 + second.s0 * first.x3) - (second.x2 * first.x1 - second.x1 * first.x2); + + float squareModule = (s0 * s0 + x1 * x1) + (x2 * x2 + x3 * x3); + + result.corrector = 2.0f - squareModule; + result.s0 = s0; + result.x1 = x1; + result.x2 = x2; + result.x3 = x3; + + if (squareModule < 1.0f - F32Utility.TWO_EPSYLON || 1.0f + F32Utility.TWO_EPSYLON < squareModule) + { + result.Normalize(squareModule); + } + } + + public static void LoadIdle(out F32Versor versor) + { + versor.corrector = 1.0f; + versor.s0 = 1.0f; + versor.x1 = 0.0f; + versor.x2 = 0.0f; + versor.x3 = 0.0f; + } + } +} diff --git a/BGC/F64Angle.cs b/BGC/F64Angle.cs new file mode 100644 index 0000000..4323fd9 --- /dev/null +++ b/BGC/F64Angle.cs @@ -0,0 +1,133 @@ +/* + * Copyright 2019-2025 Andrey Pokidov + * + * 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: 1 Feb 2019 + */ + +namespace BGC +{ + public static class F64Angle + { + public static double ToRadians(double angle, AngleUnit unit) + { + if (unit == AngleUnit.DEGREES) + { + return angle * F64Degrees.RADIANS_IN_DEGREE; + } + + if (unit == AngleUnit.TURNS) + { + return angle * F64Radians.TWO_PI; + } + + return angle; + } + + public static double ToDegrees(double angle, AngleUnit unit) + { + if (unit == AngleUnit.RADIANS) + { + return angle * F64Radians.DEGREES_IN_RADIAN; + } + + if (unit == AngleUnit.TURNS) + { + return angle * 360.0; + } + + return angle; + } + + public static double ToTurns(double angle, AngleUnit unit) + { + if (unit == AngleUnit.RADIANS) + { + return angle * F64Radians.TURNS_IN_RADIAN; + } + + if (unit == AngleUnit.DEGREES) + { + return angle * F64Degrees.TURNS_IN_DEGREE; + } + + return angle; + } + + public static double GetFullCircle(AngleUnit unit) + { + if (unit == AngleUnit.DEGREES) + { + return 360.0; + } + + if (unit == AngleUnit.TURNS) + { + return 1.0; + } + + return F64Radians.TWO_PI; + } + + public static double GetHalfCircle(AngleUnit unit) + { + if (unit == AngleUnit.DEGREES) + { + return 180.0; + } + + if (unit == AngleUnit.TURNS) + { + return 0.5; + } + + return F64Radians.PI; + } + + public static double GetQuarterCircle(AngleUnit unit) + { + if (unit == AngleUnit.DEGREES) + { + return 90.0; + } + + if (unit == AngleUnit.TURNS) + { + return 0.25; + } + + return F64Radians.HALF_OF_PI; + } + + public static double Normalize(double angle, AngleUnit unit, AngleRange range) + { + if (unit == AngleUnit.DEGREES) + { + return F64Degrees.Normalize(angle, range); + } + + if (unit == AngleUnit.TURNS) + { + return F64Turns.Normalize(angle, range); + } + + return F64Radians.Normalize(angle, range); + } + } +} diff --git a/BGC/F64Degrees.cs b/BGC/F64Degrees.cs new file mode 100644 index 0000000..1f09522 --- /dev/null +++ b/BGC/F64Degrees.cs @@ -0,0 +1,68 @@ + +/* + * Author: Andrey Pokidov + * Date: 18 Nov 2024 + */ + +namespace BGC +{ + public class F64Degrees + { + public const double RADIANS_IN_DEGREE = 1.74532925199432958E-2; + public const double TURNS_IN_DEGREE = 2.77777777777777778E-3; + + public static double ToRadians(double degrees) + { + return degrees * RADIANS_IN_DEGREE; + } + + public static double ToTurns(double degrees) + { + return degrees * TURNS_IN_DEGREE; + } + + public static double ToUnits(double degrees, AngleUnit toUnit) + { + if (toUnit == AngleUnit.RADIANS) + { + return degrees * RADIANS_IN_DEGREE; + } + + if (toUnit == AngleUnit.TURNS) + { + return degrees * TURNS_IN_DEGREE; + } + + return degrees; + } + + public static double Normalize(double degrees, AngleRange range) + { + if (range == AngleRange.UNSIGNED_RANGE) + { + if (0.0 <= degrees && degrees < 360.0) + { + return degrees; + } + } + else + { + if (-180.0 < degrees && degrees <= 180.0) + { + return degrees; + } + } + + double turns = degrees * TURNS_IN_DEGREE; + + turns -= Math.Floor(turns); + + if (range == AngleRange.SIGNED_RANGE && turns > 0.5) + { + turns -= 1.0; + } + + return turns * 360.0; + } + } +} diff --git a/Geometry/DPMatrix2x2.cs b/BGC/F64Matrix2x2.cs similarity index 75% rename from Geometry/DPMatrix2x2.cs rename to BGC/F64Matrix2x2.cs index 37d5b6c..210c222 100644 --- a/Geometry/DPMatrix2x2.cs +++ b/BGC/F64Matrix2x2.cs @@ -1,352 +1,352 @@ -/* - * Copyright 2019-2025 Andrey Pokidov - * - * 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 Geometry -{ - public struct DPMatrix2x2 - { - public double r1c1, r1c2; - - public double r2c1, r2c2; - - public DPMatrix2x2() - { - this.r1c1 = 0.0; - this.r1c2 = 0.0; - - this.r2c1 = 0.0; - this.r2c2 = 0.0; - } - - public DPMatrix2x2(double d1, double d2) - { - this.r1c1 = d1; - this.r1c2 = 0.0; - - this.r2c1 = 0.0; - this.r2c2 = d2; - } - - public DPMatrix2x2(in DPMatrix2x2 matrix) - { - this.r1c1 = matrix.r1c1; - this.r1c2 = matrix.r1c2; - - this.r2c1 = matrix.r2c1; - this.r2c2 = matrix.r2c2; - } - - public DPMatrix2x2(in SPMatrix2x2 matrix) - { - this.r1c1 = matrix.r1c1; - this.r1c2 = matrix.r1c2; - - this.r2c1 = matrix.r2c1; - this.r2c2 = matrix.r2c2; - } - - public readonly double GetDeterminant() - { - return this.r1c1 * this.r2c2 - this.r1c2 * this.r2c1; - } - - public readonly bool IsSingular() - { - double determinant = this.GetDeterminant(); - return -DPUtility.EPSYLON <= determinant && determinant <= DPUtility.EPSYLON; - } - - public void Transpose() - { - (this.r1c2, this.r2c1) = (this.r2c1, this.r1c2); - } - - public bool Invert() - { - double determinant = this.GetDeterminant(); - - if (-DPUtility.EPSYLON <= determinant && determinant <= DPUtility.EPSYLON) - { - return false; - } - - double r1c1 = this.r2c2; - double r1c2 = -this.r1c2; - - double r2c1 = -this.r2c1; - double r2c2 = this.r1c1; - - this.r1c1 = r1c1 / determinant; - this.r1c2 = r1c2 / determinant; - - this.r2c1 = r2c1 / determinant; - this.r2c2 = r2c2 / determinant; - - return true; - } - - public void Reset() - { - this.r1c1 = 0.0; - this.r1c2 = 0.0; - - this.r2c1 = 0.0; - this.r2c2 = 0.0; - } - - public void SetToIdentity() - { - this.r1c1 = 1.0; - this.r1c2 = 0.0; - - this.r2c1 = 0.0; - this.r2c2 = 1.0; - } - - public void SetToDiagonal(double d1, double d2) - { - this.r1c1 = d1; - this.r1c2 = 0.0; - - this.r2c1 = 0.0; - this.r2c2 = d2; - } - - public void SetValues(in DPMatrix2x2 matrix) - { - this.r1c1 = matrix.r1c1; - this.r1c2 = matrix.r1c2; - - this.r2c1 = matrix.r2c1; - this.r2c2 = matrix.r2c2; - } - - public void SetValues(in SPMatrix2x2 matrix) - { - this.r1c1 = matrix.r1c1; - this.r1c2 = matrix.r1c2; - - this.r2c1 = matrix.r2c1; - this.r2c2 = matrix.r2c2; - } - - public void SetTransposedOf(in DPMatrix2x2 matrix) - { - this.r1c1 = matrix.r1c1; - this.r2c2 = matrix.r2c2; - (this.r1c2, this.r2c1) = (matrix.r2c1, matrix.r1c2); - } - - public void SetTransposedOf(in SPMatrix2x2 matrix) - { - this.r1c1 = matrix.r1c1; - this.r1c2 = matrix.r2c1; - - this.r2c1 = matrix.r1c2; - this.r2c2 = matrix.r2c2; - } - - public bool SetInvertedOf(in DPMatrix2x2 matrix) - { - double determinant = matrix.GetDeterminant(); - - if (-DPUtility.EPSYLON <= determinant && determinant <= DPUtility.EPSYLON) - { - return false; - } - - double r1c1 = matrix.r2c2; - double r1c2 = -matrix.r1c2; - - double r2c1 = -matrix.r2c1; - double r2c2 = matrix.r1c1; - - this.r1c1 = r1c1 / determinant; - this.r1c2 = r1c2 / determinant; - - this.r2c1 = r2c1 / determinant; - this.r2c2 = r2c2 / determinant; - - return true; - } - - public void SetRow1(double c1, double c2) - { - this.r1c1 = c1; - this.r1c2 = c2; - } - - public void SetRow2(double c1, double c2) - { - this.r2c1 = c1; - this.r2c2 = c2; - } - - public void SetColumn1(double r1, double r2) - { - this.r1c1 = r1; - this.r2c1 = r2; - } - - public void SetColumn2(double r1, double r2) - { - this.r1c2 = r1; - this.r2c2 = r2; - } - - public static void Add(in DPMatrix2x2 matrix1, in DPMatrix2x2 matrix2, out DPMatrix2x2 sum) - { - sum.r1c1 = matrix1.r1c1 + matrix2.r1c1; - sum.r1c2 = matrix1.r1c2 + matrix2.r1c2; - - sum.r2c1 = matrix1.r2c1 + matrix2.r2c1; - sum.r2c2 = matrix1.r2c2 + matrix2.r2c2; - } - - public static void Subtract(in DPMatrix2x2 minuend, in DPMatrix2x2 subtrahend, out DPMatrix2x2 difference) - { - difference.r1c1 = minuend.r1c1 - subtrahend.r1c1; - difference.r1c2 = minuend.r1c2 - subtrahend.r1c2; - - difference.r2c1 = minuend.r2c1 - subtrahend.r2c1; - difference.r2c2 = minuend.r2c2 - subtrahend.r2c2; - } - - public static void Multiply(in DPMatrix2x2 multiplicand, double multiplier, out DPMatrix2x2 product) - { - product.r1c1 = multiplicand.r1c1 * multiplier; - product.r1c2 = multiplicand.r1c2 * multiplier; - - product.r2c1 = multiplicand.r2c1 * multiplier; - product.r2c2 = multiplicand.r2c2 * multiplier; - } - - public static void Divide(in DPMatrix2x2 dividend, double divisor, out DPMatrix2x2 quotient) - { - quotient.r1c1 = dividend.r1c1 / divisor; - quotient.r1c2 = dividend.r1c2 / divisor; - - quotient.r2c1 = dividend.r2c1 / divisor; - quotient.r2c2 = dividend.r2c2 / divisor; - } - - public static void GetWeightedSum2( - double weight1, in DPMatrix2x2 matrix1, - double weight2, in DPMatrix2x2 matrix2, - out DPMatrix2x2 sum) - { - sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2; - sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2; - - sum.r2c1 = matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2; - sum.r2c2 = matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2; - } - - public static void GetWeightedSum3( - float weight1, in SPMatrix2x2 matrix1, - float weight2, in SPMatrix2x2 matrix2, - float weight3, in SPMatrix2x2 matrix3, - out DPMatrix2x2 sum) - { - sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2 + matrix3.r1c1 * weight3; - sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2 + matrix3.r1c2 * weight3; - - sum.r2c1 = matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2 + matrix3.r2c1 * weight3; - sum.r2c2 = matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2 + matrix3.r2c2 * weight3; - } - - public static void GetWeightedSum4( - float weight1, in SPMatrix2x2 matrix1, - float weight2, in SPMatrix2x2 matrix2, - float weight3, in SPMatrix2x2 matrix3, - float weight4, in SPMatrix2x2 matrix4, - out DPMatrix2x2 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.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); - } - - public static void GetWeightedSum5( - double weight1, in DPMatrix2x2 matrix1, - double weight2, in DPMatrix2x2 matrix2, - double weight3, in DPMatrix2x2 matrix3, - double weight4, in DPMatrix2x2 matrix4, - double weight5, in DPMatrix2x2 matrix5, - out DPMatrix2x2 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.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; - } - - public static void GetRightProduct(in DPMatrix2x2 matrix, in DPVector2 vector, out DPVector2 result) - { - double x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2; - double x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2; - - result.x1 = x1; - result.x2 = x2; - } - - public static void GetLeftProduct(in DPVector2 vector, in DPMatrix2x2 matrix, out DPVector2 result) - { - double x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1; - double x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2; - - result.x1 = x1; - result.x2 = x2; - } - - public static void LoadZero(out DPMatrix2x2 matrix) - { - matrix.r1c1 = 0.0; - matrix.r1c2 = 0.0; - - matrix.r2c1 = 0.0; - matrix.r2c2 = 0.0; - } - - public static void LoadIdentity(out DPMatrix2x2 matrix) - { - matrix.r1c1 = 1.0; - matrix.r1c2 = 0.0; - - matrix.r2c1 = 0.0; - matrix.r2c2 = 1.0; - } - - public static void LoadDiagonal(double d1, double d2, out DPMatrix2x2 matrix) - { - matrix.r1c1 = d1; - matrix.r1c2 = 0.0; - - matrix.r2c1 = 0.0; - matrix.r2c2 = d2; - } - } -} +/* + * Copyright 2019-2025 Andrey Pokidov + * + * 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 F64Matrix2x2 + { + public double r1c1, r1c2; + + public double r2c1, r2c2; + + public F64Matrix2x2() + { + this.r1c1 = 0.0; + this.r1c2 = 0.0; + + this.r2c1 = 0.0; + this.r2c2 = 0.0; + } + + public F64Matrix2x2(double d1, double d2) + { + this.r1c1 = d1; + this.r1c2 = 0.0; + + this.r2c1 = 0.0; + this.r2c2 = d2; + } + + public F64Matrix2x2(in F64Matrix2x2 matrix) + { + this.r1c1 = matrix.r1c1; + this.r1c2 = matrix.r1c2; + + this.r2c1 = matrix.r2c1; + this.r2c2 = matrix.r2c2; + } + + public F64Matrix2x2(in F32Matrix2x2 matrix) + { + this.r1c1 = matrix.r1c1; + this.r1c2 = matrix.r1c2; + + this.r2c1 = matrix.r2c1; + this.r2c2 = matrix.r2c2; + } + + public readonly double GetDeterminant() + { + return this.r1c1 * this.r2c2 - this.r1c2 * this.r2c1; + } + + 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); + } + + public bool Invert() + { + double determinant = this.GetDeterminant(); + + if (-F64Utility.EPSYLON <= determinant && determinant <= F64Utility.EPSYLON) + { + return false; + } + + double r1c1 = this.r2c2; + double r1c2 = -this.r1c2; + + double r2c1 = -this.r2c1; + double r2c2 = this.r1c1; + + this.r1c1 = r1c1 / determinant; + this.r1c2 = r1c2 / determinant; + + this.r2c1 = r2c1 / determinant; + this.r2c2 = r2c2 / determinant; + + return true; + } + + public void Reset() + { + this.r1c1 = 0.0; + this.r1c2 = 0.0; + + this.r2c1 = 0.0; + this.r2c2 = 0.0; + } + + public void SetToIdentity() + { + this.r1c1 = 1.0; + this.r1c2 = 0.0; + + this.r2c1 = 0.0; + this.r2c2 = 1.0; + } + + public void SetToDiagonal(double d1, double d2) + { + this.r1c1 = d1; + this.r1c2 = 0.0; + + this.r2c1 = 0.0; + this.r2c2 = d2; + } + + public void SetValues(in F64Matrix2x2 matrix) + { + this.r1c1 = matrix.r1c1; + this.r1c2 = matrix.r1c2; + + this.r2c1 = matrix.r2c1; + this.r2c2 = matrix.r2c2; + } + + public void SetValues(in F32Matrix2x2 matrix) + { + this.r1c1 = matrix.r1c1; + this.r1c2 = matrix.r1c2; + + this.r2c1 = matrix.r2c1; + this.r2c2 = matrix.r2c2; + } + + public void SetTransposedOf(in F64Matrix2x2 matrix) + { + this.r1c1 = matrix.r1c1; + this.r2c2 = matrix.r2c2; + (this.r1c2, this.r2c1) = (matrix.r2c1, matrix.r1c2); + } + + public void SetTransposedOf(in F32Matrix2x2 matrix) + { + this.r1c1 = matrix.r1c1; + this.r1c2 = matrix.r2c1; + + this.r2c1 = matrix.r1c2; + this.r2c2 = matrix.r2c2; + } + + public bool SetInvertedOf(in F64Matrix2x2 matrix) + { + double determinant = matrix.GetDeterminant(); + + if (-F64Utility.EPSYLON <= determinant && determinant <= F64Utility.EPSYLON) + { + return false; + } + + double r1c1 = matrix.r2c2; + double r1c2 = -matrix.r1c2; + + double r2c1 = -matrix.r2c1; + double r2c2 = matrix.r1c1; + + this.r1c1 = r1c1 / determinant; + this.r1c2 = r1c2 / determinant; + + this.r2c1 = r2c1 / determinant; + this.r2c2 = r2c2 / determinant; + + return true; + } + + public void SetRow1(double c1, double c2) + { + this.r1c1 = c1; + this.r1c2 = c2; + } + + public void SetRow2(double c1, double c2) + { + this.r2c1 = c1; + this.r2c2 = c2; + } + + public void SetColumn1(double r1, double r2) + { + this.r1c1 = r1; + this.r2c1 = r2; + } + + public void SetColumn2(double r1, double r2) + { + this.r1c2 = r1; + this.r2c2 = r2; + } + + public static void Add(in F64Matrix2x2 matrix1, in F64Matrix2x2 matrix2, out F64Matrix2x2 sum) + { + sum.r1c1 = matrix1.r1c1 + matrix2.r1c1; + sum.r1c2 = matrix1.r1c2 + matrix2.r1c2; + + sum.r2c1 = matrix1.r2c1 + matrix2.r2c1; + sum.r2c2 = matrix1.r2c2 + matrix2.r2c2; + } + + public static void Subtract(in F64Matrix2x2 minuend, in F64Matrix2x2 subtrahend, out F64Matrix2x2 difference) + { + difference.r1c1 = minuend.r1c1 - subtrahend.r1c1; + difference.r1c2 = minuend.r1c2 - subtrahend.r1c2; + + difference.r2c1 = minuend.r2c1 - subtrahend.r2c1; + difference.r2c2 = minuend.r2c2 - subtrahend.r2c2; + } + + public static void Multiply(in F64Matrix2x2 multiplicand, double multiplier, out F64Matrix2x2 product) + { + product.r1c1 = multiplicand.r1c1 * multiplier; + product.r1c2 = multiplicand.r1c2 * multiplier; + + product.r2c1 = multiplicand.r2c1 * multiplier; + product.r2c2 = multiplicand.r2c2 * multiplier; + } + + public static void Divide(in F64Matrix2x2 dividend, double divisor, out F64Matrix2x2 quotient) + { + quotient.r1c1 = dividend.r1c1 / divisor; + quotient.r1c2 = dividend.r1c2 / divisor; + + quotient.r2c1 = dividend.r2c1 / divisor; + quotient.r2c2 = dividend.r2c2 / divisor; + } + + public static void GetWeightedSum2( + double weight1, in F64Matrix2x2 matrix1, + double weight2, in F64Matrix2x2 matrix2, + out F64Matrix2x2 sum) + { + sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2; + sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2; + + sum.r2c1 = matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2; + sum.r2c2 = matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2; + } + + public static void GetWeightedSum3( + float weight1, in F32Matrix2x2 matrix1, + float weight2, in F32Matrix2x2 matrix2, + float weight3, in F32Matrix2x2 matrix3, + out F64Matrix2x2 sum) + { + sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2 + matrix3.r1c1 * weight3; + sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2 + matrix3.r1c2 * weight3; + + sum.r2c1 = matrix1.r2c1 * weight1 + matrix2.r2c1 * weight2 + matrix3.r2c1 * weight3; + sum.r2c2 = matrix1.r2c2 * weight1 + matrix2.r2c2 * weight2 + matrix3.r2c2 * weight3; + } + + public static void GetWeightedSum4( + float weight1, in F32Matrix2x2 matrix1, + float weight2, in F32Matrix2x2 matrix2, + float weight3, in F32Matrix2x2 matrix3, + float weight4, in F32Matrix2x2 matrix4, + out F64Matrix2x2 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.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); + } + + public static void GetWeightedSum5( + double weight1, in F64Matrix2x2 matrix1, + double weight2, in F64Matrix2x2 matrix2, + double weight3, in F64Matrix2x2 matrix3, + double weight4, in F64Matrix2x2 matrix4, + double weight5, in F64Matrix2x2 matrix5, + out F64Matrix2x2 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.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; + } + + public static void GetRightProduct(in F64Matrix2x2 matrix, in F64Vector2 vector, out F64Vector2 result) + { + double x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2; + double x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2; + + result.x1 = x1; + result.x2 = x2; + } + + public static void GetLeftProduct(in F64Vector2 vector, in F64Matrix2x2 matrix, out F64Vector2 result) + { + double x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1; + double x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2; + + result.x1 = x1; + result.x2 = x2; + } + + public static void LoadZero(out F64Matrix2x2 matrix) + { + matrix.r1c1 = 0.0; + matrix.r1c2 = 0.0; + + matrix.r2c1 = 0.0; + matrix.r2c2 = 0.0; + } + + public static void LoadIdentity(out F64Matrix2x2 matrix) + { + matrix.r1c1 = 1.0; + matrix.r1c2 = 0.0; + + matrix.r2c1 = 0.0; + matrix.r2c2 = 1.0; + } + + public static void LoadDiagonal(double d1, double d2, out F64Matrix2x2 matrix) + { + matrix.r1c1 = d1; + matrix.r1c2 = 0.0; + + matrix.r2c1 = 0.0; + matrix.r2c2 = d2; + } + } +} diff --git a/Geometry/DPMatrix2x3.cs b/BGC/F64Matrix2x3.cs similarity index 81% rename from Geometry/DPMatrix2x3.cs rename to BGC/F64Matrix2x3.cs index a6ba25e..0e8315a 100644 --- a/Geometry/DPMatrix2x3.cs +++ b/BGC/F64Matrix2x3.cs @@ -20,15 +20,15 @@ using System; * Author: Andrey Pokidov * Date: 11 Nov 2024 */ -namespace Geometry +namespace BGC { - public struct DPMatrix2x3 + public struct F64Matrix2x3 { public double r1c1, r1c2; public double r2c1, r2c2; public double r3c1, r3c2; - public DPMatrix2x3() + public F64Matrix2x3() { this.r1c1 = 0.0; this.r1c2 = 0.0; @@ -40,7 +40,7 @@ namespace Geometry this.r3c2 = 0.0; } - public DPMatrix2x3(in DPMatrix2x3 matrix) + public F64Matrix2x3(in F64Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -52,7 +52,7 @@ namespace Geometry this.r3c2 = matrix.r3c2; } - public DPMatrix2x3(in SPMatrix2x3 matrix) + public F64Matrix2x3(in F32Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -64,7 +64,7 @@ namespace Geometry this.r3c2 = matrix.r3c2; } - public DPMatrix2x3(in DPMatrix3x2 matrix) + public F64Matrix2x3(in F64Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -76,7 +76,7 @@ namespace Geometry this.r3c2 = matrix.r2c3; } - public DPMatrix2x3(in SPMatrix3x2 matrix) + public F64Matrix2x3(in F32Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -100,7 +100,7 @@ namespace Geometry this.r3c2 = 0.0; } - public void SetValues(in DPMatrix2x3 matrix) + public void SetValues(in F64Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -112,7 +112,7 @@ namespace Geometry this.r3c2 = matrix.r3c2; } - public void SetValues(in SPMatrix2x3 matrix) + public void SetValues(in F32Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -124,7 +124,7 @@ namespace Geometry this.r3c2 = matrix.r3c2; } - public void SetTransposed(in DPMatrix3x2 matrix) + public void SetTransposed(in F64Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -136,7 +136,7 @@ namespace Geometry this.r3c2 = matrix.r2c3; } - public void SetTransposed(in SPMatrix3x2 matrix) + public void SetTransposed(in F32Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -180,7 +180,7 @@ namespace Geometry this.r3c2 = r3; } - public static void Add(in DPMatrix2x3 matrix1, in DPMatrix2x3 matrix2, out DPMatrix2x3 sum) + public static void Add(in F64Matrix2x3 matrix1, in F64Matrix2x3 matrix2, out F64Matrix2x3 sum) { sum.r1c1 = matrix1.r1c1 + matrix2.r1c1; sum.r1c2 = matrix1.r1c2 + matrix2.r1c2; @@ -192,7 +192,7 @@ namespace Geometry sum.r3c2 = matrix1.r3c2 + matrix2.r3c2; } - public static void Subtract(in DPMatrix2x3 minuend, in DPMatrix2x3 subtrahend, out DPMatrix2x3 difference) + public static void Subtract(in F64Matrix2x3 minuend, in F64Matrix2x3 subtrahend, out F64Matrix2x3 difference) { difference.r1c1 = minuend.r1c1 - subtrahend.r1c1; difference.r1c2 = minuend.r1c2 - subtrahend.r1c2; @@ -204,7 +204,7 @@ namespace Geometry difference.r3c2 = minuend.r3c2 - subtrahend.r3c2; } - public static void Multiply(in DPMatrix2x3 multiplicand, double multiplier, out DPMatrix2x3 product) + public static void Multiply(in F64Matrix2x3 multiplicand, double multiplier, out F64Matrix2x3 product) { product.r1c1 = multiplicand.r1c1 * multiplier; product.r1c2 = multiplicand.r1c2 * multiplier; @@ -216,7 +216,7 @@ namespace Geometry product.r3c2 = multiplicand.r3c2 * multiplier; } - public static void Divide(in DPMatrix2x3 dividend, double divisor, out DPMatrix2x3 quotient) + public static void Divide(in F64Matrix2x3 dividend, double divisor, out F64Matrix2x3 quotient) { quotient.r1c1 = dividend.r1c1 / divisor; quotient.r1c2 = dividend.r1c2 / divisor; @@ -229,9 +229,9 @@ namespace Geometry } public static void GetWeightedSum2( - double weight1, in DPMatrix2x3 matrix1, - double weight2, in DPMatrix2x3 matrix2, - out DPMatrix2x3 sum) + double weight1, in F64Matrix2x3 matrix1, + double weight2, in F64Matrix2x3 matrix2, + out F64Matrix2x3 sum) { sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2; sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2; @@ -244,10 +244,10 @@ namespace Geometry } public static void GetWeightedSum3( - double weight1, in DPMatrix2x3 matrix1, - double weight2, in DPMatrix2x3 matrix2, - double weight3, in DPMatrix2x3 matrix3, - out DPMatrix2x3 sum) + double weight1, in F64Matrix2x3 matrix1, + double weight2, in F64Matrix2x3 matrix2, + double weight3, in F64Matrix2x3 matrix3, + out F64Matrix2x3 sum) { sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2 + matrix3.r1c1 * weight3; sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2 + matrix3.r1c2 * weight3; @@ -260,11 +260,11 @@ namespace Geometry } public static void GetWeightedSum4( - double weight1, in DPMatrix2x3 matrix1, - double weight2, in DPMatrix2x3 matrix2, - double weight3, in DPMatrix2x3 matrix3, - double weight4, in DPMatrix2x3 matrix4, - out DPMatrix2x3 sum) + double weight1, in F64Matrix2x3 matrix1, + double weight2, in F64Matrix2x3 matrix2, + double weight3, in F64Matrix2x3 matrix3, + double weight4, in F64Matrix2x3 matrix4, + out F64Matrix2x3 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); @@ -277,12 +277,12 @@ namespace Geometry } public static void GetWeightedSum5( - double weight1, in DPMatrix2x3 matrix1, - double weight2, in DPMatrix2x3 matrix2, - double weight3, in DPMatrix2x3 matrix3, - double weight4, in DPMatrix2x3 matrix4, - double weight5, in DPMatrix2x3 matrix5, - out DPMatrix2x3 sum) + double weight1, in F64Matrix2x3 matrix1, + double weight2, in F64Matrix2x3 matrix2, + double weight3, in F64Matrix2x3 matrix3, + double weight4, in F64Matrix2x3 matrix4, + double weight5, in F64Matrix2x3 matrix5, + out F64Matrix2x3 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; @@ -294,14 +294,14 @@ namespace Geometry sum.r3c2 = (matrix1.r3c2 * weight1 + matrix2.r3c2 * weight2) + (matrix3.r3c2 * weight3 + matrix4.r3c2 * weight4) + matrix5.r3c2 * weight5; } - public static void GetRightProduct(in DPMatrix2x3 matrix, in DPVector2 vector, out DPVector3 result) + public static void GetRightProduct(in F64Matrix2x3 matrix, in F64Vector2 vector, out F64Vector3 result) { result.x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2; result.x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2; result.x3 = matrix.r3c1 * vector.x1 + matrix.r3c2 * vector.x2; } - public static void GetLeftProduct(in DPVector3 vector, in DPMatrix2x3 matrix, out DPVector2 result) + public static void GetLeftProduct(in F64Vector3 vector, in F64Matrix2x3 matrix, out F64Vector2 result) { result.x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1 + vector.x3 * matrix.r3c1; result.x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2 + vector.x3 * matrix.r3c2; diff --git a/Geometry/DPMatrix3x2.cs b/BGC/F64Matrix3x2.cs similarity index 81% rename from Geometry/DPMatrix3x2.cs rename to BGC/F64Matrix3x2.cs index 0b2ca3a..dccf764 100644 --- a/Geometry/DPMatrix3x2.cs +++ b/BGC/F64Matrix3x2.cs @@ -20,14 +20,14 @@ using System; * Author: Andrey Pokidov * Date: 11 Nov 2024 */ -namespace Geometry +namespace BGC { - public struct DPMatrix3x2 + public struct F64Matrix3x2 { public double r1c1, r1c2, r1c3; public double r2c1, r2c2, r2c3; - public DPMatrix3x2() + public F64Matrix3x2() { this.r1c1 = 0.0; this.r1c2 = 0.0; @@ -38,7 +38,7 @@ namespace Geometry this.r2c3 = 0.0; } - public DPMatrix3x2(in DPMatrix3x2 matrix) + public F64Matrix3x2(in F64Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -49,7 +49,7 @@ namespace Geometry this.r2c3 = matrix.r2c3; } - public DPMatrix3x2(in SPMatrix3x2 matrix) + public F64Matrix3x2(in F32Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -60,7 +60,7 @@ namespace Geometry this.r2c3 = matrix.r2c3; } - public DPMatrix3x2(in DPMatrix2x3 matrix) + public F64Matrix3x2(in F64Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -71,7 +71,7 @@ namespace Geometry this.r2c3 = matrix.r2c2; } - public DPMatrix3x2(in SPMatrix2x3 matrix) + public F64Matrix3x2(in F32Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -94,7 +94,7 @@ namespace Geometry } - public void SetValues(in DPMatrix3x2 matrix) + public void SetValues(in F64Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -105,7 +105,7 @@ namespace Geometry this.r2c3 = matrix.r2c3; } - public void SetValues(in SPMatrix3x2 matrix) + public void SetValues(in F32Matrix3x2 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -116,7 +116,7 @@ namespace Geometry this.r2c3 = matrix.r2c3; } - public void SetTransposed(in DPMatrix2x3 matrix) + public void SetTransposed(in F64Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -127,7 +127,7 @@ namespace Geometry this.r2c3 = matrix.r2c2; } - public void SetTransposed(in SPMatrix2x3 matrix) + public void SetTransposed(in F32Matrix2x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r2c1; @@ -170,7 +170,7 @@ namespace Geometry this.r2c3 = r2; } - public static void Add(in DPMatrix3x2 matrix1, in DPMatrix3x2 matrix2, out DPMatrix3x2 sum) + public static void Add(in F64Matrix3x2 matrix1, in F64Matrix3x2 matrix2, out F64Matrix3x2 sum) { sum.r1c1 = matrix1.r1c1 + matrix2.r1c1; sum.r1c2 = matrix1.r1c2 + matrix2.r1c2; @@ -181,7 +181,7 @@ namespace Geometry sum.r2c3 = matrix1.r2c3 + matrix2.r2c3; } - public static void Subtract(in DPMatrix3x2 minuend, in DPMatrix3x2 subtrahend, out DPMatrix3x2 difference) + public static void Subtract(in F64Matrix3x2 minuend, in F64Matrix3x2 subtrahend, out F64Matrix3x2 difference) { difference.r1c1 = minuend.r1c1 - subtrahend.r1c1; difference.r1c2 = minuend.r1c2 - subtrahend.r1c2; @@ -192,7 +192,7 @@ namespace Geometry difference.r2c3 = minuend.r2c3 - subtrahend.r2c3; } - public static void Multiply(in DPMatrix3x2 multiplicand, double multiplier, out DPMatrix3x2 product) + public static void Multiply(in F64Matrix3x2 multiplicand, double multiplier, out F64Matrix3x2 product) { product.r1c1 = multiplicand.r1c1 * multiplier; product.r1c2 = multiplicand.r1c2 * multiplier; @@ -203,7 +203,7 @@ namespace Geometry product.r2c3 = multiplicand.r2c3 * multiplier; } - public static void Divide(in DPMatrix3x2 dividend, double divisor, out DPMatrix3x2 quotient) + public static void Divide(in F64Matrix3x2 dividend, double divisor, out F64Matrix3x2 quotient) { quotient.r1c1 = dividend.r1c1 / divisor; quotient.r1c2 = dividend.r1c2 / divisor; @@ -215,9 +215,9 @@ namespace Geometry } public static void GetWeightedSum2( - double weight1, in DPMatrix3x2 matrix1, - double weight2, in DPMatrix3x2 matrix2, - out DPMatrix3x2 sum) + double weight1, in F64Matrix3x2 matrix1, + double weight2, in F64Matrix3x2 matrix2, + out F64Matrix3x2 sum) { sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2; sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2; @@ -229,10 +229,10 @@ namespace Geometry } public static void GetWeightedSum3( - double weight1, in DPMatrix3x2 matrix1, - double weight2, in DPMatrix3x2 matrix2, - double weight3, in DPMatrix3x2 matrix3, - out DPMatrix3x2 sum) + double weight1, in F64Matrix3x2 matrix1, + double weight2, in F64Matrix3x2 matrix2, + double weight3, in F64Matrix3x2 matrix3, + out F64Matrix3x2 sum) { sum.r1c1 = matrix1.r1c1 * weight1 + matrix2.r1c1 * weight2 + matrix3.r1c1 * weight3; sum.r1c2 = matrix1.r1c2 * weight1 + matrix2.r1c2 * weight2 + matrix3.r1c2 * weight3; @@ -244,11 +244,11 @@ namespace Geometry } public static void GetWeightedSum4( - double weight1, in DPMatrix3x2 matrix1, - double weight2, in DPMatrix3x2 matrix2, - double weight3, in DPMatrix3x2 matrix3, - double weight4, in DPMatrix3x2 matrix4, - out DPMatrix3x2 sum) + double weight1, in F64Matrix3x2 matrix1, + double weight2, in F64Matrix3x2 matrix2, + double weight3, in F64Matrix3x2 matrix3, + double weight4, in F64Matrix3x2 matrix4, + out F64Matrix3x2 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); @@ -260,12 +260,12 @@ namespace Geometry } public static void GetWeightedSum5( - double weight1, in DPMatrix3x2 matrix1, - double weight2, in DPMatrix3x2 matrix2, - double weight3, in DPMatrix3x2 matrix3, - double weight4, in DPMatrix3x2 matrix4, - double weight5, in DPMatrix3x2 matrix5, - out DPMatrix3x2 sum) + double weight1, in F64Matrix3x2 matrix1, + double weight2, in F64Matrix3x2 matrix2, + double weight3, in F64Matrix3x2 matrix3, + double weight4, in F64Matrix3x2 matrix4, + double weight5, in F64Matrix3x2 matrix5, + out F64Matrix3x2 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; @@ -276,13 +276,13 @@ namespace Geometry sum.r2c3 = (matrix1.r2c3 * weight1 + matrix2.r2c3 * weight2) + (matrix3.r2c3 * weight3 + matrix4.r2c3 * weight4) + matrix5.r2c3 * weight5; } - public static void GetRightProduct(in DPMatrix3x2 matrix, in DPVector3 vector, out DPVector2 result) + public static void GetRightProduct(in F64Matrix3x2 matrix, in F64Vector3 vector, out F64Vector2 result) { result.x1 = matrix.r1c1 * vector.x1 + matrix.r1c2 * vector.x2 + matrix.r1c3 * vector.x3; result.x2 = matrix.r2c1 * vector.x1 + matrix.r2c2 * vector.x2 + matrix.r2c3 * vector.x3; } - public static void GetLeftProduct(in DPVector2 vector, in DPMatrix3x2 matrix, out DPVector3 result) + public static void GetLeftProduct(in F64Vector2 vector, in F64Matrix3x2 matrix, out F64Vector3 result) { result.x1 = vector.x1 * matrix.r1c1 + vector.x2 * matrix.r2c1; result.x2 = vector.x1 * matrix.r1c2 + vector.x2 * matrix.r2c2; diff --git a/Geometry/DPMatrix3x3.cs b/BGC/F64Matrix3x3.cs similarity index 87% rename from Geometry/DPMatrix3x3.cs rename to BGC/F64Matrix3x3.cs index 17934ca..ad06f7e 100644 --- a/Geometry/DPMatrix3x3.cs +++ b/BGC/F64Matrix3x3.cs @@ -21,9 +21,9 @@ using System; * Date: 10 Feb 2019 */ -namespace Geometry +namespace BGC { - public struct DPMatrix3x3 + public struct F64Matrix3x3 { public double r1c1, r1c2, r1c3; @@ -31,7 +31,7 @@ namespace Geometry public double r3c1, r3c2, r3c3; - public DPMatrix3x3() + public F64Matrix3x3() { this.r1c1 = 0.0; this.r1c2 = 0.0; @@ -46,7 +46,7 @@ namespace Geometry this.r3c3 = 0.0; } - public DPMatrix3x3(double d1, double d2, double d3) + public F64Matrix3x3(double d1, double d2, double d3) { this.r1c1 = d1; this.r1c2 = 0.0; @@ -61,7 +61,7 @@ namespace Geometry this.r3c3 = d3; } - public DPMatrix3x3(in DPMatrix3x3 matrix) + public F64Matrix3x3(in F64Matrix3x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -76,7 +76,7 @@ namespace Geometry this.r3c3 = matrix.r3c3; } - public DPMatrix3x3(in SPMatrix3x3 matrix) + public F64Matrix3x3(in F32Matrix3x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -101,7 +101,7 @@ namespace Geometry public readonly bool IsSingular() { double determinant = this.GetDeterminant(); - return -DPUtility.EPSYLON <= determinant && determinant <= DPUtility.EPSYLON; + return -F64Utility.EPSYLON <= determinant && determinant <= F64Utility.EPSYLON; } public void Transpose() @@ -115,7 +115,7 @@ namespace Geometry { double determinant = this.GetDeterminant(); - if (-DPUtility.EPSYLON <= determinant && determinant <= DPUtility.EPSYLON) { + if (-F64Utility.EPSYLON <= determinant && determinant <= F64Utility.EPSYLON) { return false; } @@ -191,7 +191,7 @@ namespace Geometry this.r2c3 = d3; } - public void SetValues(DPMatrix3x3 matrix) + public void SetValues(F64Matrix3x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -206,7 +206,7 @@ namespace Geometry this.r3c3 = matrix.r3c3; } - public void SetValues(SPMatrix3x3 matrix) + public void SetValues(F32Matrix3x3 matrix) { this.r1c1 = matrix.r1c1; this.r1c2 = matrix.r1c2; @@ -221,7 +221,7 @@ namespace Geometry this.r3c3 = matrix.r3c3; } - public void SetTransposedOf(in DPMatrix3x3 matrix) + public void SetTransposedOf(in F64Matrix3x3 matrix) { this.r1c1 = matrix.r1c1; this.r2c2 = matrix.r2c2; @@ -232,7 +232,7 @@ namespace Geometry (this.r2c3, this.r3c2) = (matrix.r3c2, matrix.r2c3); } - public void SetTransposedOf(in SPMatrix3x3 matrix) + public void SetTransposedOf(in F32Matrix3x3 matrix) { this.r1c1 = matrix.r1c1; this.r2c2 = matrix.r2c2; @@ -243,11 +243,11 @@ namespace Geometry (this.r2c3, this.r3c2) = (matrix.r3c2, matrix.r2c3); } - public bool SetInvertedOf(in DPMatrix3x3 matrix) + public bool SetInvertedOf(in F64Matrix3x3 matrix) { double determinant = matrix.GetDeterminant(); - if (-DPUtility.EPSYLON <= determinant && determinant <= DPUtility.EPSYLON) { + if (-F64Utility.EPSYLON <= determinant && determinant <= F64Utility.EPSYLON) { return false; } @@ -320,7 +320,7 @@ namespace Geometry this.r3c3 = r3; } - public static void Add(in DPMatrix3x3 matrix1, in DPMatrix3x3 matrix2, out DPMatrix3x3 sum) + 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; @@ -335,7 +335,7 @@ namespace Geometry sum.r3c3 = matrix1.r3c3 + matrix2.r3c3; } - public static void Subtract(in DPMatrix3x3 minuend, in DPMatrix3x3 subtrahend, out DPMatrix3x3 difference) + 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; @@ -350,7 +350,7 @@ namespace Geometry difference.r3c3 = minuend.r3c3 - subtrahend.r3c3; } - public static void Multiply(in DPMatrix3x3 multiplicand, double multiplier, out DPMatrix3x3 product) + public static void Multiply(in F64Matrix3x3 multiplicand, double multiplier, out F64Matrix3x3 product) { product.r1c1 = multiplicand.r1c1 * multiplier; product.r1c2 = multiplicand.r1c2 * multiplier; @@ -365,7 +365,7 @@ namespace Geometry product.r3c3 = multiplicand.r3c3 * multiplier; } - public static void Divide(in DPMatrix3x3 dividend, double divisor, out DPMatrix3x3 quotient) + public static void Divide(in F64Matrix3x3 dividend, double divisor, out F64Matrix3x3 quotient) { quotient.r1c1 = dividend.r1c1 / divisor; quotient.r1c2 = dividend.r1c2 / divisor; @@ -381,9 +381,9 @@ namespace Geometry } public static void GetWeightedSum2( - double weight1, in DPMatrix3x3 matrix1, - double weight2, in DPMatrix3x3 matrix2, - out DPMatrix3x3 sum) + 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; @@ -399,10 +399,10 @@ namespace Geometry } public static void GetWeightedSum3( - double weight1, in DPMatrix3x3 matrix1, - double weight2, in DPMatrix3x3 matrix2, - double weight3, in DPMatrix3x3 matrix3, - out DPMatrix3x3 sum) + 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; @@ -418,11 +418,11 @@ namespace Geometry } public static void GetWeightedSum4( - double weight1, in DPMatrix3x3 matrix1, - double weight2, in DPMatrix3x3 matrix2, - double weight3, in DPMatrix3x3 matrix3, - double weight4, in DPMatrix3x3 matrix4, - out DPMatrix3x3 sum) + 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); @@ -438,12 +438,12 @@ namespace Geometry } public static void GetWeightedSum5( - double weight1, in DPMatrix3x3 matrix1, - double weight2, in DPMatrix3x3 matrix2, - double weight3, in DPMatrix3x3 matrix3, - double weight4, in DPMatrix3x3 matrix4, - double weight5, in DPMatrix3x3 matrix5, - out DPMatrix3x3 sum) + 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; @@ -458,7 +458,7 @@ namespace Geometry sum.r3c3 = (matrix1.r3c3 * weight1 + matrix2.r3c3 * weight2) + (matrix3.r3c3 * weight3 + matrix4.r3c3 * weight4) + matrix5.r3c3 * weight5; } - public static void GetRightProduct(in DPMatrix3x3 matrix, in DPVector3 vector, out DPVector3 result) + 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; @@ -469,7 +469,7 @@ namespace Geometry result.x3 = x3; } - public static void GetLeftProduct(in DPVector3 vector, in DPMatrix3x3 matrix, out DPVector3 result) + 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; @@ -480,7 +480,7 @@ namespace Geometry result.x3 = x3; } - public static void LoadZero(out DPMatrix3x3 matrix) + public static void LoadZero(out F64Matrix3x3 matrix) { matrix.r1c1 = 0.0; matrix.r1c2 = 0.0; @@ -495,7 +495,7 @@ namespace Geometry matrix.r3c3 = 0.0; } - public static void LoadIdentity(out DPMatrix3x3 matrix) + public static void LoadIdentity(out F64Matrix3x3 matrix) { matrix.r1c1 = 1.0; matrix.r1c2 = 0.0; @@ -510,7 +510,7 @@ namespace Geometry matrix.r3c3 = 1.0; } - public static void LoadDiagonal(double d1, double d2, double d3, out DPMatrix3x3 matrix) + public static void LoadDiagonal(double d1, double d2, double d3, out F64Matrix3x3 matrix) { matrix.r1c1 = d1; matrix.r1c2 = 0.0; diff --git a/Geometry/DPMatrixProduct.cs b/BGC/F64MatrixProduct.cs similarity index 87% rename from Geometry/DPMatrixProduct.cs rename to BGC/F64MatrixProduct.cs index abc8fa9..75150c4 100644 --- a/Geometry/DPMatrixProduct.cs +++ b/BGC/F64MatrixProduct.cs @@ -20,11 +20,11 @@ using System; * Author: Andrey Pokidov * Date: 11 Nov 2024 */ -namespace Geometry +namespace BGC { - public class DPMatrixProduct + public class F64MatrixProduct { - public static void Get2x2At2x2(in DPMatrix2x2 left, in DPMatrix2x2 right, out DPMatrix2x2 product) + public static void Get2x2At2x2(in F64Matrix2x2 left, in F64Matrix2x2 right, out F64Matrix2x2 product) { double r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1; double r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2; @@ -39,7 +39,7 @@ namespace Geometry product.r2c2 = r2c2; } - public static void Get2x2At3x2(in DPMatrix2x2 left, in DPMatrix3x2 right, out DPMatrix3x2 product) + public static void Get2x2At3x2(in F64Matrix2x2 left, in F64Matrix3x2 right, out F64Matrix3x2 product) { double r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1; double r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2; @@ -58,7 +58,7 @@ namespace Geometry product.r2c3 = r2c3; } - public static void Get2x3At2x2(in DPMatrix2x3 left, in DPMatrix2x2 right, out DPMatrix2x3 product) + public static void Get2x3At2x2(in F64Matrix2x3 left, in F64Matrix2x2 right, out F64Matrix2x3 product) { double r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1; double r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2; @@ -79,7 +79,7 @@ namespace Geometry product.r3c2 = r3c2; } - public static void Get2x3At3x2(in DPMatrix2x3 left, in DPMatrix3x2 right, out DPMatrix3x3 product) + public static void Get2x3At3x2(in F64Matrix2x3 left, in F64Matrix3x2 right, out F64Matrix3x3 product) { product.r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1; product.r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2; @@ -94,7 +94,7 @@ namespace Geometry product.r3c3 = left.r3c1 * right.r1c2 + left.r3c2 * right.r2c3; } - public static void Get3x2At3x3(in DPMatrix3x2 left, in DPMatrix3x3 right, out DPMatrix3x2 product) + public static void Get3x2At3x3(in F64Matrix3x2 left, in F64Matrix3x3 right, out F64Matrix3x2 product) { double r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1 + left.r1c3 * right.r3c1; double r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2 + left.r1c3 * right.r3c2; @@ -113,7 +113,7 @@ namespace Geometry product.r2c3 = r2c3; } - public static void Get3x2At2x3(in DPMatrix3x2 left, in DPMatrix2x3 right, out DPMatrix2x2 product) + public static void Get3x2At2x3(in F64Matrix3x2 left, in F64Matrix2x3 right, out F64Matrix2x2 product) { product.r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1 + left.r1c3 * right.r3c1; product.r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2 + left.r1c3 * right.r3c2; @@ -122,7 +122,7 @@ namespace Geometry product.r2c2 = left.r2c1 * right.r1c2 + left.r2c2 * right.r2c2 + left.r2c3 * right.r3c2; } - public static void Get3x3At2x3(in DPMatrix3x3 left, in DPMatrix2x3 right, out DPMatrix2x3 product) + public static void Get3x3At2x3(in F64Matrix3x3 left, in F64Matrix2x3 right, out F64Matrix2x3 product) { double r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1 + left.r1c3 * right.r3c1; double r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2 + left.r1c3 * right.r3c2; @@ -143,7 +143,7 @@ namespace Geometry product.r3c2 = r3c2; } - public static void Get3x3At3x3(in DPMatrix3x3 left, in DPMatrix3x3 right, out DPMatrix3x3 product) + public static void Get3x3At3x3(in F64Matrix3x3 left, in F64Matrix3x3 right, out F64Matrix3x3 product) { double r1c1 = left.r1c1 * right.r1c1 + left.r1c2 * right.r2c1 + left.r1c3 * right.r3c1; double r1c2 = left.r1c1 * right.r1c2 + left.r1c2 * right.r2c2 + left.r1c3 * right.r3c2; diff --git a/Geometry/DPQuaternion.cs b/BGC/F64Quaternion.cs similarity index 77% rename from Geometry/DPQuaternion.cs rename to BGC/F64Quaternion.cs index 5051d3c..6de55e9 100644 --- a/Geometry/DPQuaternion.cs +++ b/BGC/F64Quaternion.cs @@ -1,204 +1,204 @@ -using System; -using System.Numerics; - -namespace Geometry -{ - public struct DPQuaternion - { - public double s0, x1, x2, x3; - - public DPQuaternion(double s0, double x1, double x2, double x3) - { - this.s0 = s0; - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - } - - public DPQuaternion(in SPQuaternion quaternion) - { - this.s0 = quaternion.s0; - this.x1 = quaternion.x1; - this.x2 = quaternion.x2; - this.x3 = quaternion.x3; - } - - public DPQuaternion(in DPQuaternion quaternion) - { - this.s0 = quaternion.s0; - this.x1 = quaternion.x1; - this.x2 = quaternion.x2; - this.x3 = quaternion.x3; - } - - public void Reset() - { - this.s0 = 0.0; - this.x1 = 0.0; - this.x2 = 0.0; - this.x3 = 0.0; - } - - public void Conjugate() - { - this.x1 = -this.x1; - this.x2 = -this.x2; - this.x3 = -this.x3; - } - - public void SetValues(double s0, double x1, double x2, double x3) - { - this.s0 = s0; - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - } - - public void SetValues(in SPQuaternion quaternion) - { - this.s0 = quaternion.s0; - this.x1 = quaternion.x1; - this.x2 = quaternion.x2; - this.x3 = quaternion.x3; - } - - public void SetValues(in DPQuaternion quaternion) - { - this.s0 = quaternion.s0; - this.x1 = quaternion.x1; - this.x2 = quaternion.x2; - this.x3 = quaternion.x3; - } - - public void SetConjugateOf(in DPQuaternion quaternion) - { - this.s0 = quaternion.s0; - this.x1 = -quaternion.x1; - this.x2 = -quaternion.x2; - this.x3 = -quaternion.x3; - } - - public readonly void MakeRotationMatrix(out DPMatrix3x3 matrix) - { - double s0s0 = this.s0 * this.s0; - double x1x1 = this.x1 * this.x1; - double x2x2 = this.x2 * this.x2; - double x3x3 = this.x3 * this.x3; - - double squareModule = (s0s0 + x1x1) + (x2x2 + x3x3); - - if (-DPUtility.EPSYLON <= squareModule && squareModule <= DPUtility.EPSYLON) - { - DPMatrix3x3.LoadIdentity(out matrix); - return; - } - - double corrector1; - double corrector2; - - if (1.0 - DPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + DPUtility.TWO_EPSYLON) { - corrector1 = 2.0 - squareModule; - corrector2 = 2.0 * corrector1; - } - else { - corrector1 = 1.0 / squareModule; - corrector2 = 2.0 / squareModule; - } - - double s0x1 = this.s0 * this.x1; - double s0x2 = this.s0 * this.x2; - double s0x3 = this.s0 * this.x3; - double x1x2 = this.x1 * this.x2; - double x1x3 = this.x1 * this.x3; - double x2x3 = this.x2 * this.x3; - - matrix.r1c1 = corrector1 * ((s0s0 + x1x1) - (x2x2 + x3x3)); - matrix.r2c2 = corrector1 * ((s0s0 + x2x2) - (x1x1 + x3x3)); - matrix.r3c3 = corrector1 * ((s0s0 + x3x3) - (x1x1 + x2x2)); - - matrix.r1c2 = corrector2 * (x1x2 - s0x3); - matrix.r2c3 = corrector2 * (x2x3 - s0x1); - matrix.r3c1 = corrector2 * (x1x3 - s0x2); - - matrix.r2c1 = corrector2 * (x1x2 + s0x3); - matrix.r3c2 = corrector2 * (x2x3 + s0x1); - matrix.r1c3 = corrector2 * (x1x3 + s0x2); - } - - public readonly void MakeReverseMatrix(out DPMatrix3x3 matrix) - { - double s0s0 = this.s0 * this.s0; - double x1x1 = this.x1 * this.x1; - double x2x2 = this.x2 * this.x2; - double x3x3 = this.x3 * this.x3; - - double squareModule = (s0s0 + x1x1) + (x2x2 + x3x3); - - if (-DPUtility.EPSYLON <= squareModule && squareModule <= DPUtility.EPSYLON) - { - DPMatrix3x3.LoadIdentity(out matrix); - return; - } - - double corrector1; - double corrector2; - - if (1.0 - DPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + DPUtility.TWO_EPSYLON) { - corrector1 = 2.0 - squareModule; - corrector2 = 2.0 * corrector1; - } - else { - corrector1 = 1.0 / squareModule; - corrector2 = 2.0 / squareModule; - } - - double s0x1 = this.s0 * this.x1; - double s0x2 = this.s0 * this.x2; - double s0x3 = this.s0 * this.x3; - double x1x2 = this.x1 * this.x2; - double x1x3 = this.x1 * this.x3; - double x2x3 = this.x2 * this.x3; - - matrix.r1c1 = corrector1 * ((s0s0 + x1x1) - (x2x2 + x3x3)); - matrix.r2c2 = corrector1 * ((s0s0 + x2x2) - (x1x1 + x3x3)); - matrix.r3c3 = corrector1 * ((s0s0 + x3x3) - (x1x1 + x2x2)); - - matrix.r1c2 = corrector2 * (x1x2 + s0x3); - matrix.r2c3 = corrector2 * (x2x3 + s0x1); - matrix.r3c1 = corrector2 * (x1x3 + s0x2); - - matrix.r2c1 = corrector2 * (x1x2 - s0x3); - matrix.r3c2 = corrector2 * (x2x3 - s0x1); - matrix.r1c3 = corrector2 * (x1x3 - s0x2); - } - - public static void Add(in DPQuaternion quaternion1, in DPQuaternion quaternion2, out DPQuaternion sum) - { - sum.s0 = quaternion1.s0 + quaternion2.s0; - sum.x1 = quaternion1.x1 + quaternion2.x1; - sum.x2 = quaternion1.x2 + quaternion2.x2; - sum.x3 = quaternion1.x3 + quaternion2.x3; - } - - public static void Subtract(in DPQuaternion minuend, in DPQuaternion subtrahend, out DPQuaternion difference) - { - difference.s0 = minuend.s0 - subtrahend.s0; - difference.x1 = minuend.x1 - subtrahend.x1; - difference.x2 = minuend.x2 - subtrahend.x2; - difference.x3 = minuend.x3 - subtrahend.x3; - } - - public static void Multiply(in DPQuaternion left, in DPQuaternion right, out DPQuaternion product) - { - double s0 = (left.s0 * right.s0 - left.x1 * right.x1) - (left.x2 * right.x2 + left.x3 * right.x3); - double x1 = (left.x1 * right.s0 + left.s0 * right.x1) - (left.x3 * right.x2 - left.x2 * right.x3); - double x2 = (left.x2 * right.s0 + left.s0 * right.x2) - (left.x1 * right.x3 - left.x3 * right.x1); - double x3 = (left.x3 * right.s0 + left.s0 * right.x3) - (left.x2 * right.x1 - left.x1 * right.x2); - - product.s0 = s0; - product.x1 = x1; - product.x2 = x2; - product.x3 = x3; - } - } -} +using System; +using System.Numerics; + +namespace BGC +{ + public struct F64Quaternion + { + public double s0, x1, x2, x3; + + public F64Quaternion(double s0, double x1, double x2, double x3) + { + this.s0 = s0; + this.x1 = x1; + this.x2 = x2; + this.x3 = x3; + } + + public F64Quaternion(in F32Quaternion quaternion) + { + this.s0 = quaternion.s0; + this.x1 = quaternion.x1; + this.x2 = quaternion.x2; + this.x3 = quaternion.x3; + } + + public F64Quaternion(in F64Quaternion quaternion) + { + this.s0 = quaternion.s0; + this.x1 = quaternion.x1; + this.x2 = quaternion.x2; + this.x3 = quaternion.x3; + } + + public void Reset() + { + this.s0 = 0.0; + this.x1 = 0.0; + this.x2 = 0.0; + this.x3 = 0.0; + } + + public void Conjugate() + { + this.x1 = -this.x1; + this.x2 = -this.x2; + this.x3 = -this.x3; + } + + public void SetValues(double s0, double x1, double x2, double x3) + { + this.s0 = s0; + this.x1 = x1; + this.x2 = x2; + this.x3 = x3; + } + + public void SetValues(in F32Quaternion quaternion) + { + this.s0 = quaternion.s0; + this.x1 = quaternion.x1; + this.x2 = quaternion.x2; + this.x3 = quaternion.x3; + } + + public void SetValues(in F64Quaternion quaternion) + { + this.s0 = quaternion.s0; + this.x1 = quaternion.x1; + this.x2 = quaternion.x2; + this.x3 = quaternion.x3; + } + + public void SetConjugateOf(in F64Quaternion quaternion) + { + this.s0 = quaternion.s0; + this.x1 = -quaternion.x1; + this.x2 = -quaternion.x2; + this.x3 = -quaternion.x3; + } + + public readonly void MakeRotationMatrix(out F64Matrix3x3 matrix) + { + double s0s0 = this.s0 * this.s0; + double x1x1 = this.x1 * this.x1; + double x2x2 = this.x2 * this.x2; + double x3x3 = this.x3 * this.x3; + + double squareModule = (s0s0 + x1x1) + (x2x2 + x3x3); + + if (-F64Utility.EPSYLON <= squareModule && squareModule <= F64Utility.EPSYLON) + { + F64Matrix3x3.LoadIdentity(out matrix); + return; + } + + double corrector1; + double corrector2; + + if (1.0 - F64Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + F64Utility.TWO_EPSYLON) { + corrector1 = 2.0 - squareModule; + corrector2 = 2.0 * corrector1; + } + else { + corrector1 = 1.0 / squareModule; + corrector2 = 2.0 / squareModule; + } + + double s0x1 = this.s0 * this.x1; + double s0x2 = this.s0 * this.x2; + double s0x3 = this.s0 * this.x3; + double x1x2 = this.x1 * this.x2; + double x1x3 = this.x1 * this.x3; + double x2x3 = this.x2 * this.x3; + + matrix.r1c1 = corrector1 * ((s0s0 + x1x1) - (x2x2 + x3x3)); + matrix.r2c2 = corrector1 * ((s0s0 + x2x2) - (x1x1 + x3x3)); + matrix.r3c3 = corrector1 * ((s0s0 + x3x3) - (x1x1 + x2x2)); + + matrix.r1c2 = corrector2 * (x1x2 - s0x3); + matrix.r2c3 = corrector2 * (x2x3 - s0x1); + matrix.r3c1 = corrector2 * (x1x3 - s0x2); + + matrix.r2c1 = corrector2 * (x1x2 + s0x3); + matrix.r3c2 = corrector2 * (x2x3 + s0x1); + matrix.r1c3 = corrector2 * (x1x3 + s0x2); + } + + public readonly void MakeReverseMatrix(out F64Matrix3x3 matrix) + { + double s0s0 = this.s0 * this.s0; + double x1x1 = this.x1 * this.x1; + double x2x2 = this.x2 * this.x2; + double x3x3 = this.x3 * this.x3; + + double squareModule = (s0s0 + x1x1) + (x2x2 + x3x3); + + if (-F64Utility.EPSYLON <= squareModule && squareModule <= F64Utility.EPSYLON) + { + F64Matrix3x3.LoadIdentity(out matrix); + return; + } + + double corrector1; + double corrector2; + + if (1.0 - F64Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + F64Utility.TWO_EPSYLON) { + corrector1 = 2.0 - squareModule; + corrector2 = 2.0 * corrector1; + } + else { + corrector1 = 1.0 / squareModule; + corrector2 = 2.0 / squareModule; + } + + double s0x1 = this.s0 * this.x1; + double s0x2 = this.s0 * this.x2; + double s0x3 = this.s0 * this.x3; + double x1x2 = this.x1 * this.x2; + double x1x3 = this.x1 * this.x3; + double x2x3 = this.x2 * this.x3; + + matrix.r1c1 = corrector1 * ((s0s0 + x1x1) - (x2x2 + x3x3)); + matrix.r2c2 = corrector1 * ((s0s0 + x2x2) - (x1x1 + x3x3)); + matrix.r3c3 = corrector1 * ((s0s0 + x3x3) - (x1x1 + x2x2)); + + matrix.r1c2 = corrector2 * (x1x2 + s0x3); + matrix.r2c3 = corrector2 * (x2x3 + s0x1); + matrix.r3c1 = corrector2 * (x1x3 + s0x2); + + matrix.r2c1 = corrector2 * (x1x2 - s0x3); + matrix.r3c2 = corrector2 * (x2x3 - s0x1); + matrix.r1c3 = corrector2 * (x1x3 - s0x2); + } + + public static void Add(in F64Quaternion quaternion1, in F64Quaternion quaternion2, out F64Quaternion sum) + { + sum.s0 = quaternion1.s0 + quaternion2.s0; + sum.x1 = quaternion1.x1 + quaternion2.x1; + sum.x2 = quaternion1.x2 + quaternion2.x2; + sum.x3 = quaternion1.x3 + quaternion2.x3; + } + + public static void Subtract(in F64Quaternion minuend, in F64Quaternion subtrahend, out F64Quaternion difference) + { + difference.s0 = minuend.s0 - subtrahend.s0; + difference.x1 = minuend.x1 - subtrahend.x1; + difference.x2 = minuend.x2 - subtrahend.x2; + difference.x3 = minuend.x3 - subtrahend.x3; + } + + public static void Multiply(in F64Quaternion left, in F64Quaternion right, out F64Quaternion product) + { + double s0 = (left.s0 * right.s0 - left.x1 * right.x1) - (left.x2 * right.x2 + left.x3 * right.x3); + double x1 = (left.x1 * right.s0 + left.s0 * right.x1) - (left.x3 * right.x2 - left.x2 * right.x3); + double x2 = (left.x2 * right.s0 + left.s0 * right.x2) - (left.x1 * right.x3 - left.x3 * right.x1); + double x3 = (left.x3 * right.s0 + left.s0 * right.x3) - (left.x2 * right.x1 - left.x1 * right.x2); + + product.s0 = s0; + product.x1 = x1; + product.x2 = x2; + product.x3 = x3; + } + } +} diff --git a/BGC/F64Radians.cs b/BGC/F64Radians.cs new file mode 100644 index 0000000..c46bb8b --- /dev/null +++ b/BGC/F64Radians.cs @@ -0,0 +1,75 @@ + +/* + * Author: Andrey Pokidov + * Date: 18 Nov 2024 + */ + +namespace BGC +{ + public class F64Radians + { + public const double PI = 3.14159265358979324; + public const double TWO_PI = 6.28318530717958648; + public const double HALF_OF_PI = 1.57079632679489662; + public const double THIRD_OF_PI = 1.04719755119659775; + public const double FOURTH_OF_PI = 0.78539816339744831; + public const double SIXTH_OF_PI = 0.523598775598298873; + + public const double DEGREES_IN_RADIAN = 57.2957795130823209; + public const double TURNS_IN_RADIAN = 0.159154943091895336; + + public static double ToDegrees(double radians) + { + return radians * DEGREES_IN_RADIAN; + } + + public static double ToTurns(double radians) + { + return radians * TURNS_IN_RADIAN; + } + + public static double ToUnits(double radians, AngleUnit toUnit) + { + if (toUnit == AngleUnit.DEGREES) + { + return radians * DEGREES_IN_RADIAN; + } + + if (toUnit == AngleUnit.TURNS) + { + return radians * TURNS_IN_RADIAN; + } + + return radians; + } + + public static double Normalize(double radians, AngleRange range) + { + if (range == AngleRange.UNSIGNED_RANGE) + { + if (0.0 <= radians && radians < TWO_PI) + { + return radians; + } + } + else + { + if (-PI < radians && radians <= PI) + { + return radians; + } + } + + double turns = radians * TURNS_IN_RADIAN; + + turns -= Math.Floor(turns); + + if (range == AngleRange.SIGNED_RANGE && turns > 0.5) + { + turns -= 1.0; + } + + return turns * TWO_PI; + } + } +} diff --git a/BGC/F64Turns.cs b/BGC/F64Turns.cs new file mode 100644 index 0000000..2d6f365 --- /dev/null +++ b/BGC/F64Turns.cs @@ -0,0 +1,63 @@ + +/* + * Author: Andrey Pokidov + * Date: 18 Nov 2024 + */ + +namespace BGC +{ + public class F64Turns + { + public static double TurnsToRadians(double turns) + { + return turns * F64Radians.TWO_PI; + } + + public static double TurnsToDegrees(double turns) + { + return turns * 360.0; + } + + public static double ToUnits(double turns, AngleUnit toUnit) + { + if (toUnit == AngleUnit.RADIANS) + { + return turns * F64Radians.TWO_PI; + } + + if (toUnit == AngleUnit.DEGREES) + { + return turns * 360.0; + } + + return turns; + } + + public static double Normalize(double turns, AngleRange range) + { + if (range == AngleRange.UNSIGNED_RANGE) + { + if (0.0 <= turns && turns < 1.0) + { + return turns; + } + } + else + { + if (-0.5 < turns && turns <= 0.5) + { + return turns; + } + } + + double rest = turns - Math.Floor(turns); + + if (range == AngleRange.SIGNED_RANGE && rest > 0.5) + { + rest -= 1.0; + } + + return rest; + } + } +} diff --git a/Geometry/DPUtility.cs b/BGC/F64Utility.cs similarity index 89% rename from Geometry/DPUtility.cs rename to BGC/F64Utility.cs index 81fc9a0..c7215fa 100644 --- a/Geometry/DPUtility.cs +++ b/BGC/F64Utility.cs @@ -1,20 +1,20 @@ -using System; - -namespace Geometry -{ - public class DPUtility - { - public const double EPSYLON = 5E-14; - public const double TWO_EPSYLON = 1E-13; - public const double SQUARE_EPSYLON = 2.5E-27; - - public const double EPSYLON_EFFECTIVENESS_LIMIT = 1.0; - - public const double ONE_THIRD = 0.333333333333333333; - public const double ONE_SIXTH = 0.166666666666666667; - public const double ONE_NINETH = 0.111111111111111111; - - public const double GOLDEN_RATIO_HIGH = 1.61803398874989485; - public const double GOLDEN_RATIO_LOW = 0.61803398874989485; - } -} +using System; + +namespace BGC +{ + public class F64Utility + { + public const double EPSYLON = 5E-14; + public const double TWO_EPSYLON = 1E-13; + public const double SQUARE_EPSYLON = 2.5E-27; + + public const double EPSYLON_EFFECTIVENESS_LIMIT = 1.0; + + public const double ONE_THIRD = 0.333333333333333333; + public const double ONE_SIXTH = 0.166666666666666667; + public const double ONE_NINETH = 0.111111111111111111; + + public const double GOLDEN_RATIO_HIGH = 1.61803398874989485; + public const double GOLDEN_RATIO_LOW = 0.61803398874989485; + } +} diff --git a/Geometry/DPVector2.cs b/BGC/F64Vector2.cs similarity index 60% rename from Geometry/DPVector2.cs rename to BGC/F64Vector2.cs index 0c711d1..f8a750d 100644 --- a/Geometry/DPVector2.cs +++ b/BGC/F64Vector2.cs @@ -21,28 +21,28 @@ using System; * Date: 1 Feb 2019 */ -namespace Geometry +namespace BGC { - public struct DPVector2 + public struct F64Vector2 { - public static readonly DPVector2 ZERO = new DPVector2(0.0, 0.0); + public static readonly F64Vector2 ZERO = new F64Vector2(0.0, 0.0); public double x1; public double x2; - public DPVector2(double x1, double x2) + public F64Vector2(double x1, double x2) { this.x1 = x1; this.x2 = x2; } - public DPVector2(in DPVector2 vector) + public F64Vector2(in F64Vector2 vector) { this.x1 = vector.x1; this.x2 = vector.x2; } - public DPVector2(in SPVector2 vector) + public F64Vector2(in F32Vector2 vector) { this.x1 = vector.x1; this.x2 = vector.x2; @@ -62,12 +62,12 @@ namespace Geometry { double squareModule = this.GetSquareModule(); - if (1.0 - DPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + DPUtility.TWO_EPSYLON) + if (1.0 - F64Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + F64Utility.TWO_EPSYLON) { return 1; } - if (squareModule <= DPUtility.SQUARE_EPSYLON) + if (squareModule <= F64Utility.SQUARE_EPSYLON) { this.Reset(); return 0; @@ -81,23 +81,23 @@ namespace Geometry return 1; } - public readonly DPVector2 GetNormalized() + public readonly F64Vector2 GetNormalized() { double squareModule = this.GetSquareModule(); - if (1.0 - DPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + DPUtility.TWO_EPSYLON) + if (1.0 - F64Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + F64Utility.TWO_EPSYLON) { return this; } - if (squareModule <= DPUtility.SQUARE_EPSYLON) + if (squareModule <= F64Utility.SQUARE_EPSYLON) { return ZERO; } double module = Math.Sqrt(squareModule); - return new DPVector2( + return new F64Vector2( this.x1 / module, this.x2 / module ); @@ -111,13 +111,13 @@ namespace Geometry public readonly bool IsZero() { - return this.GetSquareModule() <= DPUtility.SQUARE_EPSYLON; + return this.GetSquareModule() <= F64Utility.SQUARE_EPSYLON; } public readonly bool IsUnit() { double squareModule = this.GetSquareModule(); - return 1.0 - DPUtility.TWO_EPSYLON <= squareModule && squareModule <= DPUtility.EPSYLON; + return 1.0 - F64Utility.TWO_EPSYLON <= squareModule && squareModule <= F64Utility.EPSYLON; } public void Reset() @@ -132,25 +132,25 @@ namespace Geometry this.x2 = x2; } - public void SetValues(in DPVector2 vector) + public void SetValues(in F64Vector2 vector) { this.x1 = vector.x1; this.x2 = vector.x2; } - public void SetValues(in SPVector2 vector) + public void SetValues(in F32Vector2 vector) { this.x1 = vector.x1; this.x2 = vector.x2; } - public void SetReverseOf(in DPVector2 vector) + public void SetReverseOf(in F64Vector2 vector) { this.x1 = -vector.x1; this.x2 = -vector.x2; } - public void SetReverseOf(in SPVector2 vector) + public void SetReverseOf(in F32Vector2 vector) { this.x1 = -vector.x1; this.x2 = -vector.x2; @@ -161,34 +161,34 @@ namespace Geometry return String.Format("DPVector2({0}, {1})", this.x1, this.x2); } - public static void Add(in DPVector2 vector1, in DPVector2 vector2, out DPVector2 sum) + public static void Add(in F64Vector2 vector1, in F64Vector2 vector2, out F64Vector2 sum) { sum.x1 = vector1.x1 + vector2.x1; sum.x2 = vector1.x2 + vector2.x2; } - public static void Subtract(in DPVector2 minuend, in DPVector2 subtrahend, out DPVector2 difference) + public static void Subtract(in F64Vector2 minuend, in F64Vector2 subtrahend, out F64Vector2 difference) { difference.x1 = minuend.x1 - subtrahend.x1; difference.x2 = minuend.x2 - subtrahend.x2; } - public static void Muliply(in DPVector2 multiplicand, double multiplier, out DPVector2 product) + public static void Muliply(in F64Vector2 multiplicand, double multiplier, out F64Vector2 product) { product.x1 = multiplicand.x1 * multiplier; product.x2 = multiplicand.x2 * multiplier; } - public static void Divide(in DPVector2 dividend, double divisor, out DPVector2 quotient) + public static void Divide(in F64Vector2 dividend, double divisor, out F64Vector2 quotient) { quotient.x1 = dividend.x1 / divisor; quotient.x2 = dividend.x2 / divisor; } public static void GetWeightedSum2( - double weight1, in DPVector2 vector1, - double weight2, in DPVector2 vector2, - out DPVector2 sum + double weight1, in F64Vector2 vector1, + double weight2, in F64Vector2 vector2, + out F64Vector2 sum ) { sum.x1 = vector1.x1 * weight1 + vector2.x1 * weight2; @@ -196,10 +196,10 @@ namespace Geometry } public static void GetWeightedSum3( - double weight1, in DPVector2 vector1, - double weight2, in DPVector2 vector2, - double weight3, in DPVector2 vector3, - out DPVector2 sum + double weight1, in F64Vector2 vector1, + double weight2, in F64Vector2 vector2, + double weight3, in F64Vector2 vector3, + out F64Vector2 sum ) { sum.x1 = vector1.x1 * weight1 + vector2.x1 * weight2 + vector3.x1 * weight3; @@ -207,112 +207,112 @@ namespace Geometry } public static void GetWeightedSum4( - double weight1, in DPVector2 vector1, - double weight2, in DPVector2 vector2, - double weight3, in DPVector2 vector3, - double weight4, in DPVector2 vector4, - out DPVector2 sum) + double weight1, in F64Vector2 vector1, + double weight2, in F64Vector2 vector2, + double weight3, in F64Vector2 vector3, + double weight4, in F64Vector2 vector4, + out F64Vector2 sum) { sum.x1 = (vector1.x1 * weight1 + vector2.x1 * weight2) + (vector3.x1 * weight3 + vector4.x1 * weight4); sum.x2 = (vector1.x2 * weight1 + vector2.x2 * weight2) + (vector3.x2 * weight3 + vector4.x2 * weight4); } public static void GetWeightedSum5( - double weight1, in DPVector2 vector1, - double weight2, in DPVector2 vector2, - double weight3, in DPVector2 vector3, - double weight4, in DPVector2 vector4, - double weight5, in DPVector2 vector5, - out DPVector2 sum) + double weight1, in F64Vector2 vector1, + double weight2, in F64Vector2 vector2, + double weight3, in F64Vector2 vector3, + double weight4, in F64Vector2 vector4, + double weight5, in F64Vector2 vector5, + out F64Vector2 sum) { sum.x1 = (vector1.x1 * weight1 + vector2.x1 * weight2) + (vector3.x1 * weight3 + vector4.x1 * weight4) + vector5.x1 * weight5; sum.x2 = (vector1.x2 * weight1 + vector2.x2 * weight2) + (vector3.x2 * weight3 + vector4.x2 * weight4) + vector5.x2 * weight5; } public static void GetMean2( - in DPVector2 vector1, - in DPVector2 vector2, - out DPVector2 result) + in F64Vector2 vector1, + in F64Vector2 vector2, + out F64Vector2 result) { result.x1 = (vector1.x1 + vector2.x1) * 0.5; result.x2 = (vector1.x2 + vector2.x2) * 0.5; } public static void GetMean3( - in DPVector2 vector1, - in DPVector2 vector2, - in DPVector2 vector3, - out DPVector2 result) + in F64Vector2 vector1, + in F64Vector2 vector2, + in F64Vector2 vector3, + out F64Vector2 result) { - result.x1 = (vector1.x1 + vector2.x1 + vector3.x1) * DPUtility.ONE_THIRD; - result.x2 = (vector1.x2 + vector2.x2 + vector3.x2) * DPUtility.ONE_THIRD; + result.x1 = (vector1.x1 + vector2.x1 + vector3.x1) * F64Utility.ONE_THIRD; + result.x2 = (vector1.x2 + vector2.x2 + vector3.x2) * F64Utility.ONE_THIRD; } public static void GetMean4( - in DPVector2 vector1, - in DPVector2 vector2, - in DPVector2 vector3, - in DPVector2 vector4, - out DPVector2 result) + in F64Vector2 vector1, + in F64Vector2 vector2, + in F64Vector2 vector3, + in F64Vector2 vector4, + out F64Vector2 result) { result.x1 = ((vector1.x1 + vector2.x1) + (vector3.x1 + vector4.x1)) * 0.25; result.x2 = ((vector1.x2 + vector2.x2) + (vector3.x2 + vector4.x2)) * 0.25; } public static void GetMean5( - in DPVector2 vector1, - in DPVector2 vector2, - in DPVector2 vector3, - in DPVector2 vector4, - in DPVector2 vector5, - out DPVector2 result) + in F64Vector2 vector1, + in F64Vector2 vector2, + in F64Vector2 vector3, + in F64Vector2 vector4, + in F64Vector2 vector5, + out F64Vector2 result) { result.x1 = ((vector1.x1 + vector2.x1) + (vector3.x1 + vector4.x1) + vector5.x1) * 0.2; result.x2 = ((vector1.x2 + vector2.x2) + (vector3.x2 + vector4.x2) + vector5.x2) * 0.2; } - public static double GetScalarProduct(in DPVector2 vector1, in DPVector2 vector2) + public static double GetScalarProduct(in F64Vector2 vector1, in F64Vector2 vector2) { return vector1.x1 * vector2.x1 + vector1.x2 * vector2.x2; } - public static double GetCrossProduct(in DPVector2 vector1, in DPVector2 vector2) + public static double GetCrossProduct(in F64Vector2 vector1, in F64Vector2 vector2) { return vector1.x1 * vector2.x2 - vector1.x2 * vector2.x1; } - public static double GetAngle(in DPVector2 vector1, in DPVector2 vector2, AngleUnit unit) + public static double GetAngle(in F64Vector2 vector1, in F64Vector2 vector2, AngleUnit unit) { double squareModule1 = vector1.GetSquareModule(); - if (squareModule1 <= DPUtility.SQUARE_EPSYLON) + if (squareModule1 <= F64Utility.SQUARE_EPSYLON) { return 0.0; } double squareModule2 = vector2.GetSquareModule(); - if (squareModule2 <= DPUtility.SQUARE_EPSYLON) + if (squareModule2 <= F64Utility.SQUARE_EPSYLON) { return 0.0; } - double cosine = DPVector2.GetScalarProduct(vector1, vector2) / Math.Sqrt(squareModule1 * squareModule2); + double cosine = F64Vector2.GetScalarProduct(vector1, vector2) / Math.Sqrt(squareModule1 * squareModule2); - if (1.0 - DPUtility.EPSYLON <= cosine) + if (1.0 - F64Utility.EPSYLON <= cosine) { return 0.0; } - if (cosine <= -(1.0 - DPUtility.EPSYLON)) + if (cosine <= -(1.0 - F64Utility.EPSYLON)) { - return DPAngle.GetHalfCircle(unit); + return F64Angle.GetHalfCircle(unit); } - return DPAngle.ConvertFromRadians(Math.Acos(cosine), unit); + return F64Radians.ToUnits(Math.Acos(cosine), unit); } - public static double GetSquareDistance(in DPVector2 vector1, in DPVector2 vector2) + public static double GetSquareDistance(in F64Vector2 vector1, in F64Vector2 vector2) { double dx1 = vector1.x1 - vector2.x1; double dx2 = vector1.x2 - vector2.x2; @@ -320,29 +320,29 @@ namespace Geometry return dx1 * dx1 + dx2 * dx2; } - public static double GetDistance(in DPVector2 vector1, in DPVector2 vector2) + public static double GetDistance(in F64Vector2 vector1, in F64Vector2 vector2) { return Math.Sqrt(GetSquareDistance(vector1, vector2)); } - public static bool AreEqual(in DPVector2 vector1, in DPVector2 vector2) + public static bool AreEqual(in F64Vector2 vector1, in F64Vector2 vector2) { double squareModule1 = vector1.GetSquareModule(); double squareModule2 = vector2.GetSquareModule(); double squareModule3 = GetSquareDistance(vector1, vector2); // 2.0 means dimension amount - if (squareModule1 < DPUtility.EPSYLON_EFFECTIVENESS_LIMIT || squareModule2 < DPUtility.EPSYLON_EFFECTIVENESS_LIMIT) + if (squareModule1 < F64Utility.EPSYLON_EFFECTIVENESS_LIMIT || squareModule2 < F64Utility.EPSYLON_EFFECTIVENESS_LIMIT) { - return squareModule3 < (2.0 * DPUtility.SQUARE_EPSYLON); + return squareModule3 < (2.0 * F64Utility.SQUARE_EPSYLON); } if (squareModule1 <= squareModule2) { - return squareModule3 <= (2.0 * DPUtility.SQUARE_EPSYLON) * squareModule2; + return squareModule3 <= (2.0 * F64Utility.SQUARE_EPSYLON) * squareModule2; } - return squareModule3 <= (2.0 * DPUtility.SQUARE_EPSYLON) * squareModule1; + return squareModule3 <= (2.0 * F64Utility.SQUARE_EPSYLON) * squareModule1; } } } diff --git a/Geometry/DPVector3.cs b/BGC/F64Vector3.cs similarity index 64% rename from Geometry/DPVector3.cs rename to BGC/F64Vector3.cs index ed21551..9ade2d4 100644 --- a/Geometry/DPVector3.cs +++ b/BGC/F64Vector3.cs @@ -1,397 +1,397 @@ -/* - * Copyright 2019-2025 Andrey Pokidov - * - * 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: 1 Feb 2019 - */ - -namespace Geometry -{ - public struct DPVector3 - { - public static readonly DPVector3 ZERO = new DPVector3(0.0, 0.0, 0.0); - - public double x1; - public double x2; - public double x3; - - public DPVector3(double x1, double x2, double x3) - { - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - } - - public DPVector3(in DPVector3 vector) - { - this.x1 = vector.x1; - this.x2 = vector.x2; - this.x3 = vector.x3; - } - - public DPVector3(in SPVector3 vector) - { - this.x1 = vector.x1; - this.x2 = vector.x2; - this.x3 = vector.x3; - } - - public readonly double GetSquareModule() - { - return this.x1 * this.x1 + this.x2 * this.x2 + this.x3 * this.x3; - } - - public readonly double GetModule() - { - return Math.Sqrt(this.GetSquareModule()); - } - - public int Normalize() - { - double squareModule = this.GetSquareModule(); - - if (1.0 - DPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + DPUtility.TWO_EPSYLON) - { - return 1; - } - - if (squareModule <= DPUtility.SQUARE_EPSYLON) - { - this.Reset(); - return 0; - } - - double module = Math.Sqrt(squareModule); - - this.x1 /= module; - this.x2 /= module; - this.x3 /= module; - - return 1; - } - - public readonly DPVector3 GetNormalized() - { - double squareModule = this.GetSquareModule(); - - if (1.0 - DPUtility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + DPUtility.TWO_EPSYLON) - { - return this; - } - - if (squareModule <= DPUtility.SQUARE_EPSYLON) - { - return ZERO; - } - - double module = Math.Sqrt(squareModule); - - return new DPVector3( - this.x1 / module, - this.x2 / module, - this.x3 / module - ); - } - - public void Reverse() - { - this.x1 = -this.x1; - this.x2 = -this.x2; - this.x3 = -this.x3; - } - - public readonly bool IsZero() - { - return this.GetSquareModule() <= DPUtility.SQUARE_EPSYLON; - } - - public readonly bool IsUnit() - { - double squareModule = this.GetSquareModule(); - return 1.0 - DPUtility.TWO_EPSYLON <= squareModule && squareModule <= DPUtility.EPSYLON; - } - - public void Reset() - { - this.x1 = 0.0; - this.x2 = 0.0; - this.x3 = 0.0; - } - - public void SetValues(double x1, double x2, double x3) - { - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - } - - public void SetValues(in DPVector3 vector) - { - this.x1 = vector.x1; - this.x2 = vector.x2; - this.x3 = vector.x3; - } - - public void SetValues(in SPVector3 vector) - { - this.x1 = vector.x1; - this.x2 = vector.x2; - this.x3 = vector.x3; - } - - public void SetReverseOf(in DPVector3 vector) - { - this.x1 = -vector.x1; - this.x2 = -vector.x2; - this.x3 = -vector.x3; - } - - public void SetReverseOf(in SPVector3 vector) - { - this.x1 = -vector.x1; - this.x2 = -vector.x2; - this.x3 = -vector.x3; - } - - public readonly override string ToString() - { - return String.Format("DPVector3({0}, {1}, {2})", this.x1, this.x2, this.x3); - } - - public static void Add(in DPVector3 vector1, in DPVector3 vector2, out DPVector3 sum) - { - sum.x1 = vector1.x1 + vector2.x1; - sum.x2 = vector1.x2 + vector2.x2; - sum.x3 = vector1.x3 + vector2.x3; - } - - public static void Subtract(in DPVector3 minuend, in DPVector3 subtrahend, out DPVector3 difference) - { - difference.x1 = minuend.x1 - subtrahend.x1; - difference.x2 = minuend.x2 - subtrahend.x2; - difference.x3 = minuend.x3 - subtrahend.x3; - } - - public static void Muliply(in DPVector3 multiplicand, double multiplier, out DPVector3 product) - { - product.x1 = multiplicand.x1 * multiplier; - product.x2 = multiplicand.x2 * multiplier; - product.x3 = multiplicand.x3 * multiplier; - } - - public static void Divide(in DPVector3 dividend, double divisor, out DPVector3 quotient) - { - quotient.x1 = dividend.x1 / divisor; - quotient.x2 = dividend.x2 / divisor; - quotient.x3 = dividend.x3 / divisor; - } - - public static void GetWeightedSum2( - double weight1, in DPVector3 vector1, - double weight2, in DPVector3 vector2, - out DPVector3 sum) - { - sum.x1 = vector1.x1 * weight1 + vector2.x1 * weight2; - sum.x2 = vector1.x2 * weight1 + vector2.x2 * weight2; - sum.x3 = vector1.x3 * weight1 + vector2.x3 * weight2; - } - - public static void GetWeightedSum3( - double weight1, in DPVector3 vector1, - double weight2, in DPVector3 vector2, - double weight3, in DPVector3 vector3, - out DPVector3 sum) - { - sum.x1 = vector1.x1 * weight1 + vector2.x1 * weight2 + vector3.x1 * weight3; - sum.x2 = vector1.x2 * weight1 + vector2.x2 * weight2 + vector3.x2 * weight3; - sum.x3 = vector1.x3 * weight1 + vector2.x3 * weight2 + vector3.x3 * weight3; - } - - public static void GetWeightedSum4( - double weight1, in DPVector3 vector1, - double weight2, in DPVector3 vector2, - double weight3, in DPVector3 vector3, - double weight4, in DPVector3 vector4, - out DPVector3 sum) - { - sum.x1 = (vector1.x1 * weight1 + vector2.x1 * weight2) + (vector3.x1 * weight3 + vector4.x1 * weight4); - sum.x2 = (vector1.x2 * weight1 + vector2.x2 * weight2) + (vector3.x2 * weight3 + vector4.x2 * weight4); - sum.x3 = (vector1.x3 * weight1 + vector2.x3 * weight2) + (vector3.x3 * weight3 + vector4.x3 * weight4); - } - - public static void GetWeightedSum5( - double weight1, in DPVector3 vector1, - double weight2, in DPVector3 vector2, - double weight3, in DPVector3 vector3, - double weight4, in DPVector3 vector4, - double weight5, in DPVector3 vector5, - out DPVector3 sum) - { - sum.x1 = (vector1.x1 * weight1 + vector2.x1 * weight2) + (vector3.x1 * weight3 + vector4.x1 * weight4) + vector5.x1 * weight5; - sum.x2 = (vector1.x2 * weight1 + vector2.x2 * weight2) + (vector3.x2 * weight3 + vector4.x2 * weight4) + vector5.x2 * weight5; - sum.x3 = (vector1.x3 * weight1 + vector2.x3 * weight2) + (vector3.x3 * weight3 + vector4.x3 * weight4) + vector5.x3 * weight5; - } - - public static void GetMean2( - in DPVector3 vector1, - in DPVector3 vector2, - out DPVector3 result) - { - result.x1 = (vector1.x1 + vector2.x1) * 0.5; - result.x2 = (vector1.x2 + vector2.x2) * 0.5; - result.x3 = (vector1.x3 + vector2.x3) * 0.5; - } - - public static void GetMean3( - in DPVector3 vector1, - in DPVector3 vector2, - in DPVector3 vector3, - out DPVector3 result) - { - result.x1 = (vector1.x1 + vector2.x1 + vector3.x1) * DPUtility.ONE_THIRD; - result.x2 = (vector1.x2 + vector2.x2 + vector3.x2) * DPUtility.ONE_THIRD; - result.x3 = (vector1.x3 + vector2.x3 + vector3.x3) * DPUtility.ONE_THIRD; - } - - public static void GetMean4( - in DPVector3 vector1, - in DPVector3 vector2, - in DPVector3 vector3, - in DPVector3 vector4, - out DPVector3 result) - { - result.x1 = ((vector1.x1 + vector2.x1) + (vector3.x1 + vector4.x1)) * 0.25; - result.x2 = ((vector1.x2 + vector2.x2) + (vector3.x2 + vector4.x2)) * 0.25; - result.x3 = ((vector1.x3 + vector2.x3) + (vector3.x3 + vector4.x3)) * 0.25; - } - - public static void GetMean5( - in DPVector3 vector1, - in DPVector3 vector2, - in DPVector3 vector3, - in DPVector3 vector4, - in DPVector3 vector5, - out DPVector3 result) - { - result.x1 = ((vector1.x1 + vector2.x1) + (vector3.x1 + vector4.x1) + vector5.x1) * 0.2; - result.x2 = ((vector1.x2 + vector2.x2) + (vector3.x2 + vector4.x2) + vector5.x2) * 0.2; - result.x3 = ((vector1.x3 + vector2.x3) + (vector3.x3 + vector4.x3) + vector5.x3) * 0.2; - } - - public static double GetScalarProduct(in DPVector3 vector1, in DPVector3 vector2) - { - return vector1.x1 * vector2.x1 + vector1.x2 * vector2.x2 + vector1.x3 * vector2.x3; - } - - public static void GetCrossProduct(in DPVector3 vector1, in DPVector3 vector2, out DPVector3 result) - { - double x1 = vector1.x2 * vector2.x3 - vector1.x3 * vector2.x2; - double x2 = vector1.x3 * vector2.x1 - vector1.x1 * vector2.x3; - double x3 = vector1.x1 * vector2.x2 - vector1.x2 * vector2.x1; - - result.x1 = x1; - result.x2 = x2; - result.x3 = x3; - } - - public static double GetTripleProduct(in DPVector3 vector1, in DPVector3 vector2, in DPVector3 vector3) - { - return vector1.x1 * (vector2.x2 * vector3.x3 - vector2.x3 * vector3.x2) - + vector1.x2 * (vector2.x3 * vector3.x1 - vector2.x1 * vector3.x3) - + vector1.x3 * (vector2.x1 * vector3.x2 - vector2.x2 * vector3.x1); - } - - public static void GetDoubleCrossProduct(in DPVector3 vector1, in DPVector3 vector2, in DPVector3 vector3, out DPVector3 result) - { - // [a x [b x c]] = b * (a, c) - c * (a, b) - double ac = GetScalarProduct(vector1, vector3); - double ab = GetScalarProduct(vector1, vector2); - - result.x1 = ac * vector2.x1 - ab * vector3.x1; - result.x2 = ac * vector2.x2 - ab * vector3.x2; - result.x3 = ac * vector2.x3 - ab * vector3.x3; - } - - public static double GetAngle(in DPVector3 vector1, in DPVector3 vector2, AngleUnit unit) - { - double squareModule1 = vector1.GetSquareModule(); - - if (squareModule1 <= DPUtility.SQUARE_EPSYLON) - { - return 0.0; - } - - double squareModule2 = vector2.GetSquareModule(); - - if (squareModule2 <= DPUtility.SQUARE_EPSYLON) - { - return 0.0; - } - - double cosine = DPVector3.GetScalarProduct(vector1, vector2) / Math.Sqrt(squareModule1 * squareModule2); - - if (1.0 - DPUtility.EPSYLON <= cosine) - { - return 0.0; - } - - if (cosine <= -(1.0 - DPUtility.EPSYLON)) - { - return DPAngle.GetHalfCircle(unit); - } - - return DPAngle.ConvertFromRadians(Math.Acos(cosine), unit); - } - - public static double GetSquareDistance(in DPVector3 vector1, in DPVector3 vector2) - { - double dx1 = vector1.x1 - vector2.x1; - double dx2 = vector1.x2 - vector2.x2; - double dx3 = vector1.x3 - vector2.x3; - - return dx1 * dx1 + dx2 * dx2 + dx3 * dx3; - } - - public static double GetDistance(in DPVector3 vector1, in DPVector3 vector2) - { - return Math.Sqrt(GetSquareDistance(vector1, vector2)); - } - - public static bool AreEqual(in DPVector3 vector1, in DPVector3 vector2) - { - double squareModule1 = vector1.GetSquareModule(); - double squareModule2 = vector2.GetSquareModule(); - double squareModule3 = GetSquareDistance(vector1, vector2); - - // 3.0 means dimension amount - if (squareModule1 < DPUtility.EPSYLON_EFFECTIVENESS_LIMIT || squareModule2 < DPUtility.EPSYLON_EFFECTIVENESS_LIMIT) - { - return squareModule3 < (3.0 * DPUtility.SQUARE_EPSYLON); - } - - if (squareModule1 <= squareModule2) - { - return squareModule3 <= (3.0 * DPUtility.SQUARE_EPSYLON) * squareModule2; - } - - return squareModule3 <= (3.0 * DPUtility.SQUARE_EPSYLON) * squareModule1; - } - } -} - +/* + * Copyright 2019-2025 Andrey Pokidov + * + * 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: 1 Feb 2019 + */ + +namespace BGC +{ + public struct F64Vector3 + { + public static readonly F64Vector3 ZERO = new F64Vector3(0.0, 0.0, 0.0); + + public double x1; + public double x2; + public double x3; + + public F64Vector3(double x1, double x2, double x3) + { + this.x1 = x1; + this.x2 = x2; + this.x3 = x3; + } + + public F64Vector3(in F64Vector3 vector) + { + this.x1 = vector.x1; + this.x2 = vector.x2; + this.x3 = vector.x3; + } + + public F64Vector3(in F32Vector3 vector) + { + this.x1 = vector.x1; + this.x2 = vector.x2; + this.x3 = vector.x3; + } + + public readonly double GetSquareModule() + { + return this.x1 * this.x1 + this.x2 * this.x2 + this.x3 * this.x3; + } + + public readonly double GetModule() + { + return Math.Sqrt(this.GetSquareModule()); + } + + public int Normalize() + { + double squareModule = this.GetSquareModule(); + + if (1.0 - F64Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + F64Utility.TWO_EPSYLON) + { + return 1; + } + + if (squareModule <= F64Utility.SQUARE_EPSYLON) + { + this.Reset(); + return 0; + } + + double module = Math.Sqrt(squareModule); + + this.x1 /= module; + this.x2 /= module; + this.x3 /= module; + + return 1; + } + + public readonly F64Vector3 GetNormalized() + { + double squareModule = this.GetSquareModule(); + + if (1.0 - F64Utility.TWO_EPSYLON <= squareModule && squareModule <= 1.0 + F64Utility.TWO_EPSYLON) + { + return this; + } + + if (squareModule <= F64Utility.SQUARE_EPSYLON) + { + return ZERO; + } + + double module = Math.Sqrt(squareModule); + + return new F64Vector3( + this.x1 / module, + this.x2 / module, + this.x3 / module + ); + } + + public void Reverse() + { + this.x1 = -this.x1; + this.x2 = -this.x2; + this.x3 = -this.x3; + } + + public readonly bool IsZero() + { + return this.GetSquareModule() <= F64Utility.SQUARE_EPSYLON; + } + + public readonly bool IsUnit() + { + double squareModule = this.GetSquareModule(); + return 1.0 - F64Utility.TWO_EPSYLON <= squareModule && squareModule <= F64Utility.EPSYLON; + } + + public void Reset() + { + this.x1 = 0.0; + this.x2 = 0.0; + this.x3 = 0.0; + } + + public void SetValues(double x1, double x2, double x3) + { + this.x1 = x1; + this.x2 = x2; + this.x3 = x3; + } + + public void SetValues(in F64Vector3 vector) + { + this.x1 = vector.x1; + this.x2 = vector.x2; + this.x3 = vector.x3; + } + + public void SetValues(in F32Vector3 vector) + { + this.x1 = vector.x1; + this.x2 = vector.x2; + this.x3 = vector.x3; + } + + public void SetReverseOf(in F64Vector3 vector) + { + this.x1 = -vector.x1; + this.x2 = -vector.x2; + this.x3 = -vector.x3; + } + + public void SetReverseOf(in F32Vector3 vector) + { + this.x1 = -vector.x1; + this.x2 = -vector.x2; + this.x3 = -vector.x3; + } + + public readonly override string ToString() + { + return String.Format("DPVector3({0}, {1}, {2})", this.x1, this.x2, this.x3); + } + + public static void Add(in F64Vector3 vector1, in F64Vector3 vector2, out F64Vector3 sum) + { + sum.x1 = vector1.x1 + vector2.x1; + sum.x2 = vector1.x2 + vector2.x2; + sum.x3 = vector1.x3 + vector2.x3; + } + + public static void Subtract(in F64Vector3 minuend, in F64Vector3 subtrahend, out F64Vector3 difference) + { + difference.x1 = minuend.x1 - subtrahend.x1; + difference.x2 = minuend.x2 - subtrahend.x2; + difference.x3 = minuend.x3 - subtrahend.x3; + } + + public static void Muliply(in F64Vector3 multiplicand, double multiplier, out F64Vector3 product) + { + product.x1 = multiplicand.x1 * multiplier; + product.x2 = multiplicand.x2 * multiplier; + product.x3 = multiplicand.x3 * multiplier; + } + + public static void Divide(in F64Vector3 dividend, double divisor, out F64Vector3 quotient) + { + quotient.x1 = dividend.x1 / divisor; + quotient.x2 = dividend.x2 / divisor; + quotient.x3 = dividend.x3 / divisor; + } + + public static void GetWeightedSum2( + double weight1, in F64Vector3 vector1, + double weight2, in F64Vector3 vector2, + out F64Vector3 sum) + { + sum.x1 = vector1.x1 * weight1 + vector2.x1 * weight2; + sum.x2 = vector1.x2 * weight1 + vector2.x2 * weight2; + sum.x3 = vector1.x3 * weight1 + vector2.x3 * weight2; + } + + public static void GetWeightedSum3( + double weight1, in F64Vector3 vector1, + double weight2, in F64Vector3 vector2, + double weight3, in F64Vector3 vector3, + out F64Vector3 sum) + { + sum.x1 = vector1.x1 * weight1 + vector2.x1 * weight2 + vector3.x1 * weight3; + sum.x2 = vector1.x2 * weight1 + vector2.x2 * weight2 + vector3.x2 * weight3; + sum.x3 = vector1.x3 * weight1 + vector2.x3 * weight2 + vector3.x3 * weight3; + } + + public static void GetWeightedSum4( + double weight1, in F64Vector3 vector1, + double weight2, in F64Vector3 vector2, + double weight3, in F64Vector3 vector3, + double weight4, in F64Vector3 vector4, + out F64Vector3 sum) + { + sum.x1 = (vector1.x1 * weight1 + vector2.x1 * weight2) + (vector3.x1 * weight3 + vector4.x1 * weight4); + sum.x2 = (vector1.x2 * weight1 + vector2.x2 * weight2) + (vector3.x2 * weight3 + vector4.x2 * weight4); + sum.x3 = (vector1.x3 * weight1 + vector2.x3 * weight2) + (vector3.x3 * weight3 + vector4.x3 * weight4); + } + + public static void GetWeightedSum5( + double weight1, in F64Vector3 vector1, + double weight2, in F64Vector3 vector2, + double weight3, in F64Vector3 vector3, + double weight4, in F64Vector3 vector4, + double weight5, in F64Vector3 vector5, + out F64Vector3 sum) + { + sum.x1 = (vector1.x1 * weight1 + vector2.x1 * weight2) + (vector3.x1 * weight3 + vector4.x1 * weight4) + vector5.x1 * weight5; + sum.x2 = (vector1.x2 * weight1 + vector2.x2 * weight2) + (vector3.x2 * weight3 + vector4.x2 * weight4) + vector5.x2 * weight5; + sum.x3 = (vector1.x3 * weight1 + vector2.x3 * weight2) + (vector3.x3 * weight3 + vector4.x3 * weight4) + vector5.x3 * weight5; + } + + public static void GetMean2( + in F64Vector3 vector1, + in F64Vector3 vector2, + out F64Vector3 result) + { + result.x1 = (vector1.x1 + vector2.x1) * 0.5; + result.x2 = (vector1.x2 + vector2.x2) * 0.5; + result.x3 = (vector1.x3 + vector2.x3) * 0.5; + } + + public static void GetMean3( + in F64Vector3 vector1, + in F64Vector3 vector2, + in F64Vector3 vector3, + out F64Vector3 result) + { + result.x1 = (vector1.x1 + vector2.x1 + vector3.x1) * F64Utility.ONE_THIRD; + result.x2 = (vector1.x2 + vector2.x2 + vector3.x2) * F64Utility.ONE_THIRD; + result.x3 = (vector1.x3 + vector2.x3 + vector3.x3) * F64Utility.ONE_THIRD; + } + + public static void GetMean4( + in F64Vector3 vector1, + in F64Vector3 vector2, + in F64Vector3 vector3, + in F64Vector3 vector4, + out F64Vector3 result) + { + result.x1 = ((vector1.x1 + vector2.x1) + (vector3.x1 + vector4.x1)) * 0.25; + result.x2 = ((vector1.x2 + vector2.x2) + (vector3.x2 + vector4.x2)) * 0.25; + result.x3 = ((vector1.x3 + vector2.x3) + (vector3.x3 + vector4.x3)) * 0.25; + } + + public static void GetMean5( + in F64Vector3 vector1, + in F64Vector3 vector2, + in F64Vector3 vector3, + in F64Vector3 vector4, + in F64Vector3 vector5, + out F64Vector3 result) + { + result.x1 = ((vector1.x1 + vector2.x1) + (vector3.x1 + vector4.x1) + vector5.x1) * 0.2; + result.x2 = ((vector1.x2 + vector2.x2) + (vector3.x2 + vector4.x2) + vector5.x2) * 0.2; + result.x3 = ((vector1.x3 + vector2.x3) + (vector3.x3 + vector4.x3) + vector5.x3) * 0.2; + } + + public static double GetScalarProduct(in F64Vector3 vector1, in F64Vector3 vector2) + { + return vector1.x1 * vector2.x1 + vector1.x2 * vector2.x2 + vector1.x3 * vector2.x3; + } + + public static void GetCrossProduct(in F64Vector3 vector1, in F64Vector3 vector2, out F64Vector3 result) + { + double x1 = vector1.x2 * vector2.x3 - vector1.x3 * vector2.x2; + double x2 = vector1.x3 * vector2.x1 - vector1.x1 * vector2.x3; + double x3 = vector1.x1 * vector2.x2 - vector1.x2 * vector2.x1; + + result.x1 = x1; + result.x2 = x2; + result.x3 = x3; + } + + public static double GetTripleProduct(in F64Vector3 vector1, in F64Vector3 vector2, in F64Vector3 vector3) + { + return vector1.x1 * (vector2.x2 * vector3.x3 - vector2.x3 * vector3.x2) + + vector1.x2 * (vector2.x3 * vector3.x1 - vector2.x1 * vector3.x3) + + vector1.x3 * (vector2.x1 * vector3.x2 - vector2.x2 * vector3.x1); + } + + public static void GetDoubleCrossProduct(in F64Vector3 vector1, in F64Vector3 vector2, in F64Vector3 vector3, out F64Vector3 result) + { + // [a x [b x c]] = b * (a, c) - c * (a, b) + double ac = GetScalarProduct(vector1, vector3); + double ab = GetScalarProduct(vector1, vector2); + + result.x1 = ac * vector2.x1 - ab * vector3.x1; + result.x2 = ac * vector2.x2 - ab * vector3.x2; + result.x3 = ac * vector2.x3 - ab * vector3.x3; + } + + public static double GetAngle(in F64Vector3 vector1, in F64Vector3 vector2, AngleUnit unit) + { + double squareModule1 = vector1.GetSquareModule(); + + if (squareModule1 <= F64Utility.SQUARE_EPSYLON) + { + return 0.0; + } + + double squareModule2 = vector2.GetSquareModule(); + + if (squareModule2 <= F64Utility.SQUARE_EPSYLON) + { + return 0.0; + } + + double cosine = F64Vector3.GetScalarProduct(vector1, vector2) / Math.Sqrt(squareModule1 * squareModule2); + + if (1.0 - F64Utility.EPSYLON <= cosine) + { + return 0.0; + } + + if (cosine <= -(1.0 - F64Utility.EPSYLON)) + { + return F64Angle.GetHalfCircle(unit); + } + + return F64Radians.ToUnits(Math.Acos(cosine), unit); + } + + public static double GetSquareDistance(in F64Vector3 vector1, in F64Vector3 vector2) + { + double dx1 = vector1.x1 - vector2.x1; + double dx2 = vector1.x2 - vector2.x2; + double dx3 = vector1.x3 - vector2.x3; + + return dx1 * dx1 + dx2 * dx2 + dx3 * dx3; + } + + public static double GetDistance(in F64Vector3 vector1, in F64Vector3 vector2) + { + return Math.Sqrt(GetSquareDistance(vector1, vector2)); + } + + public static bool AreEqual(in F64Vector3 vector1, in F64Vector3 vector2) + { + double squareModule1 = vector1.GetSquareModule(); + double squareModule2 = vector2.GetSquareModule(); + double squareModule3 = GetSquareDistance(vector1, vector2); + + // 3.0 means dimension amount + if (squareModule1 < F64Utility.EPSYLON_EFFECTIVENESS_LIMIT || squareModule2 < F64Utility.EPSYLON_EFFECTIVENESS_LIMIT) + { + return squareModule3 < (3.0 * F64Utility.SQUARE_EPSYLON); + } + + if (squareModule1 <= squareModule2) + { + return squareModule3 <= (3.0 * F64Utility.SQUARE_EPSYLON) * squareModule2; + } + + return squareModule3 <= (3.0 * F64Utility.SQUARE_EPSYLON) * squareModule1; + } + } +} + diff --git a/Geometry/DPVersor.cs b/BGC/F64Versor.cs similarity index 81% rename from Geometry/DPVersor.cs rename to BGC/F64Versor.cs index 8f79f11..f16c91e 100644 --- a/Geometry/DPVersor.cs +++ b/BGC/F64Versor.cs @@ -20,11 +20,11 @@ * Date: 20 Oct 2024 */ -namespace Geometry +namespace BGC { - public struct DPVersor + public struct F64Versor { - public static readonly DPVersor IDLE = new DPVersor(1.0, 0.0, 0.0, 0.0, 1.0); + public static readonly F64Versor IDLE = new F64Versor(1.0, 0.0, 0.0, 0.0, 1.0); private double s0; private double x1; @@ -32,7 +32,7 @@ namespace Geometry private double x3; private double corrector; - private DPVersor(double s0, double x1, double x2, double x3, double corrector) + private F64Versor(double s0, double x1, double x2, double x3, double corrector) { this.s0 = s0; this.x1 = x1; @@ -41,7 +41,7 @@ namespace Geometry this.corrector = corrector; } - public DPVersor() + public F64Versor() { this.s0 = 1.0; this.x1 = 0.0; @@ -50,7 +50,7 @@ namespace Geometry this.corrector = 1.0; } - public DPVersor(double s0, double x1, double x2, double x3) + public F64Versor(double s0, double x1, double x2, double x3) { this.s0 = s0; this.x1 = x1; @@ -61,13 +61,13 @@ namespace Geometry this.corrector = 2.0 - squareModule; - if (squareModule < 1.0 - DPUtility.TWO_EPSYLON || 1.0 + DPUtility.TWO_EPSYLON < squareModule) + if (squareModule < 1.0 - F64Utility.TWO_EPSYLON || 1.0 + F64Utility.TWO_EPSYLON < squareModule) { this.Normalize(squareModule); } } - public DPVersor(in DPVersor versor) + public F64Versor(in F64Versor versor) { this.s0 = versor.s0; this.x1 = versor.x1; @@ -76,7 +76,7 @@ namespace Geometry this.corrector = versor.corrector; } - public DPVersor(in SPVersor versor) + public F64Versor(in F32Versor versor) { this.s0 = versor.GetScalar(); this.x1 = versor.GetX1(); @@ -87,7 +87,7 @@ namespace Geometry this.corrector = 2.0 - squareModule; - if (squareModule < 1.0 - DPUtility.TWO_EPSYLON || 1.0 + DPUtility.TWO_EPSYLON < squareModule) + if (squareModule < 1.0 - F64Utility.TWO_EPSYLON || 1.0 + F64Utility.TWO_EPSYLON < squareModule) { this.Normalize(squareModule); } @@ -120,7 +120,7 @@ namespace Geometry public readonly bool IsIdle() { - return this.s0 <= -(1.0 - DPUtility.EPSYLON) || (1.0 - DPUtility.EPSYLON) <= this.s0; + return this.s0 <= -(1.0 - F64Utility.EPSYLON) || (1.0 - F64Utility.EPSYLON) <= this.s0; } public void Reset() @@ -141,19 +141,19 @@ namespace Geometry public readonly double GetAngle(AngleUnit unit) { - if (this.s0 <= -(1.0 - DPUtility.TWO_EPSYLON) || 1.0 - DPUtility.TWO_EPSYLON <= this.s0) { + if (this.s0 <= -(1.0 - F64Utility.TWO_EPSYLON) || 1.0 - F64Utility.TWO_EPSYLON <= this.s0) { return 0.0; } - if (-DPUtility.EPSYLON <= this.s0 && this.s0 <= DPUtility.EPSYLON) + if (-F64Utility.EPSYLON <= this.s0 && this.s0 <= F64Utility.EPSYLON) { - return DPAngle.GetHalfCircle(unit); + return F64Angle.GetHalfCircle(unit); } - return DPAngle.ConvertFromRadians(2.0 * Math.Acos(s0), unit); + return F64Radians.ToUnits(2.0 * Math.Acos(s0), unit); } - public readonly void MakeRotationMatrix(out DPMatrix3x3 matrix) + public readonly void MakeRotationMatrix(out F64Matrix3x3 matrix) { double s0s0 = this.s0 * this.s0; double x1x1 = this.x1 * this.x1; @@ -184,7 +184,7 @@ namespace Geometry matrix.r1c3 = corrector2 * (x1x3 + s0x2); } - public readonly void MakeReverseMatrix(out DPMatrix3x3 matrix) + public readonly void MakeReverseMatrix(out F64Matrix3x3 matrix) { double s0s0 = this.s0 * this.s0; double x1x1 = this.x1 * this.x1; @@ -226,13 +226,13 @@ namespace Geometry this.corrector = 2.0 - squareModule; - if (squareModule < 1.0 - DPUtility.TWO_EPSYLON || 1.0 + DPUtility.TWO_EPSYLON < squareModule) + if (squareModule < 1.0 - F64Utility.TWO_EPSYLON || 1.0 + F64Utility.TWO_EPSYLON < squareModule) { this.Normalize(squareModule); } } - public void SetValues(in DPVersor versor) + public void SetValues(in F64Versor versor) { this.s0 = versor.s0; this.x1 = versor.x1; @@ -241,7 +241,7 @@ namespace Geometry this.corrector = versor.corrector; } - public void SetValues(in SPVersor versor) + public void SetValues(in F32Versor versor) { this.s0 = versor.GetScalar(); this.x1 = versor.GetX1(); @@ -252,13 +252,13 @@ namespace Geometry this.corrector = 2.0 - squareModule; - if (squareModule < 1.0 - DPUtility.TWO_EPSYLON || 1.0 + DPUtility.TWO_EPSYLON < squareModule) + if (squareModule < 1.0 - F64Utility.TWO_EPSYLON || 1.0 + F64Utility.TWO_EPSYLON < squareModule) { this.Normalize(squareModule); } } - public void SetInverted(in DPVersor versor) + public void SetInverted(in F64Versor versor) { this.s0 = versor.s0; this.x1 = -versor.x1; @@ -267,7 +267,7 @@ namespace Geometry this.corrector = versor.corrector; } - public void SetInverted(in SPVersor versor) + public void SetInverted(in F32Versor versor) { this.s0 = versor.GetScalar(); this.x1 = -versor.GetX1(); @@ -278,13 +278,13 @@ namespace Geometry this.corrector = 2.0 - squareModule; - if (squareModule < 1.0 - DPUtility.TWO_EPSYLON || 1.0 + DPUtility.TWO_EPSYLON < squareModule) + if (squareModule < 1.0 - F64Utility.TWO_EPSYLON || 1.0 + F64Utility.TWO_EPSYLON < squareModule) { this.Normalize(squareModule); } } - public readonly void Turn(in DPVector3 vector, out DPVector3 result) + public readonly void Turn(in F64Vector3 vector, out F64Vector3 result) { double multiplier = 2.0 * this.corrector; double tx1 = multiplier * (this.x2 * vector.x3 - this.x3 * vector.x2); @@ -300,7 +300,7 @@ namespace Geometry result.x3 = x3; } - public readonly void TurnBack(in DPVector3 vector, out DPVector3 result) + public readonly void TurnBack(in F64Vector3 vector, out F64Vector3 result) { double multiplier = 2.0 * this.corrector; double tx1 = multiplier * (this.x2 * vector.x3 - this.x3 * vector.x2); @@ -318,7 +318,7 @@ namespace Geometry private void Normalize(double squareModule) { - if (squareModule <= DPUtility.SQUARE_EPSYLON || (this.x1 * this.x1 + this.x2 * this.x2 + this.x3 * this.x3) <= DPUtility.SQUARE_EPSYLON * squareModule) + if (squareModule <= F64Utility.SQUARE_EPSYLON || (this.x1 * this.x1 + this.x2 * this.x2 + this.x3 * this.x3) <= F64Utility.SQUARE_EPSYLON * squareModule) { this.Reset(); return; @@ -334,7 +334,7 @@ namespace Geometry this.corrector = 2.0 - (this.s0 * this.s0 + this.x1 * this.x1) - (this.x2 * this.x2 + this.x3 * this.x3); } - public static void Combine(in DPVersor second, in DPVersor first, out DPVersor result) + public static void Combine(in F64Versor second, in F64Versor first, out F64Versor result) { double s0 = (second.s0 * first.s0 - second.x1 * first.x1) - (second.x2 * first.x2 + second.x3 * first.x3); double x1 = (second.x1 * first.s0 + second.s0 * first.x1) - (second.x3 * first.x2 - second.x2 * first.x3); @@ -350,7 +350,7 @@ namespace Geometry result.corrector = 2.0 - squareModule; - if (squareModule < 1.0 - DPUtility.TWO_EPSYLON || 1.0 + DPUtility.TWO_EPSYLON < squareModule) + if (squareModule < 1.0 - F64Utility.TWO_EPSYLON || 1.0 + F64Utility.TWO_EPSYLON < squareModule) { result.Normalize(squareModule); } diff --git a/GeometryDev/GeometryDev.csproj b/BGCDev/BGCDev.csproj similarity index 64% rename from GeometryDev/GeometryDev.csproj rename to BGCDev/BGCDev.csproj index 672f08b..4adcca4 100644 --- a/GeometryDev/GeometryDev.csproj +++ b/BGCDev/BGCDev.csproj @@ -1,14 +1,14 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - + + + + Exe + net6.0 + enable + enable + + + + + + + diff --git a/GeometryDev/Program.cs b/BGCDev/Program.cs similarity index 61% rename from GeometryDev/Program.cs rename to BGCDev/Program.cs index bb3b826..4d41a79 100644 --- a/GeometryDev/Program.cs +++ b/BGCDev/Program.cs @@ -1,80 +1,80 @@ -// See https://aka.ms/new-console-template for more information -using System; -using System.ComponentModel; -using System.Diagnostics; -using Geometry; - -public static class Program -{ - private static SPVersor[] AllocateVersors(int amount) - { - return new SPVersor[amount]; - } - - private static SPVersor[] MakeZeroVersors(int amount) - { - SPVersor[] versors = AllocateVersors(amount); - - for (int i = 0; i < amount; i++) - { - versors[i] = SPVersor.IDLE; - } - - return versors; - } - - private static SPVersor[] MakeRandomVersors(int amount) - { - Random randomizer = new Random(Environment.TickCount); - - SPVersor[] versors = AllocateVersors(amount); - - for (int i = 0; i < amount; i++) - { - versors[i] = new SPVersor( - randomizer.NextSingle(), - randomizer.NextSingle(), - randomizer.NextSingle(), - randomizer.NextSingle() - ); - } - - return versors; - } - - private static void PrintVersor(in SPVersor versor) - { - Console.WriteLine("({0}, {1}, {2}, {3}) / {4:E}", versor.GetScalar(), versor.GetX1(), versor.GetX2(), versor.GetX3(), versor.GetCorrector() - 1.0f); - } - - public static int Main() - { - int amount = 1000000; - - SPVersor[] versors1 = MakeRandomVersors(amount); - SPVersor[] versors2 = MakeRandomVersors(amount); - SPVersor[] results = MakeZeroVersors(amount); - - long start, end; - - start = Environment.TickCount64; - - for (int j = 0; j < 1000; j++) - { - for (int i = 0; i < amount; i++) - { - SPVersor.Combine(versors1[i], versors2[i], out results[i]); - } - } - - end = Environment.TickCount64; - - Console.WriteLine("Time: {0}", end - start); - - PrintVersor(versors1[10]); - PrintVersor(versors2[10]); - PrintVersor(results[10]); - - return 0; - } +// See https://aka.ms/new-console-template for more information +using System; +using System.ComponentModel; +using System.Diagnostics; +using BGC; + +public static class Program +{ + private static F32Versor[] AllocateVersors(int amount) + { + return new F32Versor[amount]; + } + + private static F32Versor[] MakeZeroVersors(int amount) + { + F32Versor[] versors = AllocateVersors(amount); + + for (int i = 0; i < amount; i++) + { + versors[i] = F32Versor.IDLE; + } + + return versors; + } + + private static F32Versor[] MakeRandomVersors(int amount) + { + Random randomizer = new Random(Environment.TickCount); + + F32Versor[] versors = AllocateVersors(amount); + + for (int i = 0; i < amount; i++) + { + versors[i] = new F32Versor( + randomizer.NextSingle(), + randomizer.NextSingle(), + randomizer.NextSingle(), + randomizer.NextSingle() + ); + } + + return versors; + } + + private static void PrintVersor(in F32Versor versor) + { + Console.WriteLine("({0}, {1}, {2}, {3}) / {4:E}", versor.GetScalar(), versor.GetX1(), versor.GetX2(), versor.GetX3(), versor.GetCorrector() - 1.0f); + } + + public static int Main() + { + int amount = 1000000; + + F32Versor[] versors1 = MakeRandomVersors(amount); + F32Versor[] versors2 = MakeRandomVersors(amount); + F32Versor[] results = MakeZeroVersors(amount); + + long start, end; + + start = Environment.TickCount64; + + for (int j = 0; j < 1000; j++) + { + for (int i = 0; i < amount; i++) + { + F32Versor.Combine(versors1[i], versors2[i], out results[i]); + } + } + + end = Environment.TickCount64; + + Console.WriteLine("Time: {0}", end - start); + + PrintVersor(versors1[10]); + PrintVersor(versors2[10]); + PrintVersor(results[10]); + + return 0; + } } \ No newline at end of file diff --git a/GeometryTest/GeometryTest.csproj b/BGCTest/BGCTest.csproj similarity index 78% rename from GeometryTest/GeometryTest.csproj rename to BGCTest/BGCTest.csproj index 59423a7..0084bbd 100644 --- a/GeometryTest/GeometryTest.csproj +++ b/BGCTest/BGCTest.csproj @@ -1,18 +1,18 @@ - - - - net8.0 - enable - - false - - - - - - - - - - - + + + + net6.0 + enable + + false + + + + + + + + + + + diff --git a/GeometryTest/Vector2FloatTest.cs b/BGCTest/F32Vector2Test.cs similarity index 56% rename from GeometryTest/Vector2FloatTest.cs rename to BGCTest/F32Vector2Test.cs index d8bfba9..06a6df5 100644 --- a/GeometryTest/Vector2FloatTest.cs +++ b/BGCTest/F32Vector2Test.cs @@ -1,19 +1,19 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; - -using System; -using System.IO; - -using Geometry; - -namespace GeometryTest -{ - [TestClass] - public class Vector2FloatTest - { - [TestMethod] - public void TestInitialization() - { - SPVector2 vector = new SPVector2(1.0f, 2.0f); - } - } -} \ No newline at end of file +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using System; +using System.IO; + +using BGC; + +namespace BGCTest +{ + [TestClass] + public class F32Vector2Test + { + [TestMethod] + public void TestInitialization() + { + F32Vector2 vector = new F32Vector2(1.0f, 2.0f); + } + } +} diff --git a/Geometry/DPAngle.cs b/Geometry/DPAngle.cs deleted file mode 100644 index 89e9356..0000000 --- a/Geometry/DPAngle.cs +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright 2019-2025 Andrey Pokidov - * - * 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: 1 Feb 2019 - */ - -namespace Geometry -{ - public static class DPAngle - { - public const double PI = 3.14159265358979324; - public const double TWO_PI = 6.28318530717958648; - public const double HALF_OF_PI = 1.57079632679489662; - public const double THIRD_OF_PI = 1.04719755119659775; - public const double FOURTH_OF_PI = 0.78539816339744831; - public const double SIXTH_OF_PI = 0.523598775598298873; - - public const double DEGREES_IN_RADIAN = 57.2957795130823209; - public const double TURNS_IN_RADIAN = 0.159154943091895336; - public const double RADIANS_IN_DEGREE = 1.74532925199432958E-2; - public const double TURNS_IN_DEGREE = 2.77777777777777778E-3; - - public static double RadiansToDegrees(double radians) - { - return radians * DEGREES_IN_RADIAN; - } - - public static double RadiansToTurns(double radians) - { - return radians * TURNS_IN_RADIAN; - } - - public static double DegreesToRadians(double degrees) - { - return degrees * RADIANS_IN_DEGREE; - } - - public static double DegreesToTurns(double degrees) - { - return degrees * TURNS_IN_DEGREE; - } - - public static double TurnsToRadians(double turns) - { - return turns * TWO_PI; - } - - public static double TurnsToDegrees(double turns) - { - return turns * 360.0; - } - - public static double ConvertFromRadians(double radians, AngleUnit toUnit) - { - if (toUnit == AngleUnit.DEGREES) - { - return radians * DEGREES_IN_RADIAN; - } - - if (toUnit == AngleUnit.TURNS) - { - return radians * TURNS_IN_RADIAN; - } - - return radians; - } - - public static double ConvertFromDegrees(double degrees, AngleUnit toUnit) - { - if (toUnit == AngleUnit.RADIANS) - { - return degrees * RADIANS_IN_DEGREE; - } - - if (toUnit == AngleUnit.TURNS) - { - return degrees * TURNS_IN_DEGREE; - } - - return degrees; - } - - public static double ConvertFromTurns(double turns, AngleUnit toUnit) - { - if (toUnit == AngleUnit.RADIANS) - { - return turns * TWO_PI; - } - - if (toUnit == AngleUnit.DEGREES) - { - return turns * 360.0; - } - - return turns; - } - public static double ConvertToRadians(double angle, AngleUnit unit) - { - if (unit == AngleUnit.DEGREES) - { - return angle * RADIANS_IN_DEGREE; - } - - if (unit == AngleUnit.TURNS) - { - return angle * TWO_PI; - } - - return angle; - } - - public static double ConvertToDegrees(double angle, AngleUnit unit) - { - if (unit == AngleUnit.RADIANS) - { - return angle * DEGREES_IN_RADIAN; - } - - if (unit == AngleUnit.TURNS) - { - return angle * 360.0; - } - - return angle; - } - - public static double ConvertToTurns(double angle, AngleUnit unit) - { - if (unit == AngleUnit.RADIANS) - { - return angle * TURNS_IN_RADIAN; - } - - if (unit == AngleUnit.DEGREES) - { - return angle * TURNS_IN_DEGREE; - } - - return angle; - } - - public static double GetFullCircle(AngleUnit unit) - { - if (unit == AngleUnit.RADIANS) - { - return TWO_PI; - } - - if (unit == AngleUnit.DEGREES) - { - return 360.0; - } - - return 1.0; - } - - public static double GetHalfCircle(AngleUnit unit) - { - if (unit == AngleUnit.RADIANS) - { - return PI; - } - - if (unit == AngleUnit.DEGREES) - { - return 180.0; - } - - return 0.5; - } - - public static double GetQuarterCircle(AngleUnit unit) - { - if (unit == AngleUnit.RADIANS) - { - return HALF_OF_PI; - } - - if (unit == AngleUnit.DEGREES) - { - return 90.0; - } - - return 0.25; - } - - public static double NormalizeRadians(double radians, AngleRange range) - { - if (range == AngleRange.UNSIGNED_RANGE) - { - if (0.0 <= radians && radians < TWO_PI) - { - return radians; - } - - } - else - { - if (-PI < radians && radians <= PI) - { - return radians; - } - } - - double turns = radians * TURNS_IN_RADIAN; - - turns -= Math.Floor(turns); - - if (range == AngleRange.SIGNED_RANGE && turns > 0.5) - { - turns -= 1.0; - } - - return turns * TWO_PI; - } - - public static double NormalizeDegrees(double degrees, AngleRange range) - { - if (range == AngleRange.UNSIGNED_RANGE) - { - if (0.0 <= degrees && degrees < 360.0) - { - return degrees; - } - } - else - { - if (-180.0 < degrees && degrees <= 180.0) - { - return degrees; - } - } - - double turns = degrees * TURNS_IN_DEGREE; - - turns -= Math.Floor(turns); - - if (range == AngleRange.SIGNED_RANGE && turns > 0.5) - { - turns -= 1.0; - } - - return turns * 360.0; - } - - public static double NormalizeTurns(double turns, AngleRange range) - { - if (range == AngleRange.UNSIGNED_RANGE) - { - if (0.0 <= turns && turns < 1.0) - { - return turns; - } - } - else - { - if (-0.5 < turns && turns <= 0.5) - { - return turns; - } - } - - double rest = turns - Math.Floor(turns); - - if (range == AngleRange.SIGNED_RANGE && rest > 0.5) - { - rest -= 1.0; - } - - return rest; - } - - public static double Normalize(double angle, AngleUnit unit, AngleRange range) - { - if (unit == AngleUnit.RADIANS) - { - return NormalizeRadians(angle, range); - } - - if (unit == AngleUnit.DEGREES) - { - return NormalizeDegrees(angle, range); - } - - return NormalizeTurns(angle, range); - } - } -} diff --git a/Geometry/SPAngle.cs b/Geometry/SPAngle.cs deleted file mode 100644 index d665ec8..0000000 --- a/Geometry/SPAngle.cs +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright 2019-2025 Andrey Pokidov - * - * 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: 1 Feb 2019 - */ - -namespace Geometry -{ - public static class SPAngle - { - public const float PI = 3.1415926536f; - public const float TWO_PI = 6.2831853072f; - public const float HALF_OF_PI = 1.5707963268f; - public const float THIRD_OF_PI = 1.0471975512f; - public const float FOURTH_OF_PI = 0.7853981634f; - public const float SIXTH_OF_PI = 0.5235987756f; - - public const float DEGREES_IN_RADIAN = 57.295779513f; - public const float TURNS_IN_RADIAN = 0.1591549431f; - public const float RADIANS_IN_DEGREE = 1.745329252E-2f; - public const float TURNS_IN_DEGREE = 2.7777777778E-3f; - - public static float RadiansToDegrees(float radians) - { - return radians * DEGREES_IN_RADIAN; - } - - public static float RadiansToTurns(float radians) - { - return radians * TURNS_IN_RADIAN; - } - - public static float DegreesToRadians(float degrees) - { - return degrees * RADIANS_IN_DEGREE; - } - - public static float DegreesToTurns(float degrees) - { - return degrees * TURNS_IN_DEGREE; - } - - public static float TurnsToRadians(float turns) - { - return turns * TWO_PI; - } - - public static float TurnsToDegrees(float turns) - { - return turns * 360.0f; - } - - public static float ConvertFromRadians(float radians, AngleUnit toUnit) - { - if (toUnit == AngleUnit.DEGREES) - { - return radians * DEGREES_IN_RADIAN; - } - - if (toUnit == AngleUnit.TURNS) - { - return radians * TURNS_IN_RADIAN; - } - - return radians; - } - - public static float ConvertFromDegrees(float degrees, AngleUnit toUnit) - { - if (toUnit == AngleUnit.RADIANS) - { - return degrees * RADIANS_IN_DEGREE; - } - - if (toUnit == AngleUnit.TURNS) - { - return degrees * TURNS_IN_DEGREE; - } - - return degrees; - } - - public static float ConvertFromTurns(float turns, AngleUnit toUnit) - { - if (toUnit == AngleUnit.RADIANS) - { - return turns * TWO_PI; - } - - if (toUnit == AngleUnit.DEGREES) - { - return turns * 360.0f; - } - - return turns; - } - - public static float ConvertToRadians(float angle, AngleUnit unit) - { - if (unit == AngleUnit.DEGREES) - { - return angle * RADIANS_IN_DEGREE; - } - - if (unit == AngleUnit.TURNS) - { - return angle * TWO_PI; - } - - return angle; - } - - public static float ConvertToDegrees(float angle, AngleUnit unit) - { - if (unit == AngleUnit.RADIANS) - { - return angle * DEGREES_IN_RADIAN; - } - - if (unit == AngleUnit.TURNS) - { - return angle * 360.0f; - } - - return angle; - } - - public static float ConvertToTurns(float angle, AngleUnit unit) - { - if (unit == AngleUnit.RADIANS) - { - return angle * TURNS_IN_RADIAN; - } - - if (unit == AngleUnit.DEGREES) - { - return angle * TURNS_IN_DEGREE; - } - - return angle; - } - - public static float GetFullCircle(AngleUnit unit) - { - if (unit == AngleUnit.RADIANS) - { - return TWO_PI; - } - - if (unit == AngleUnit.DEGREES) - { - return 360.0f; - } - - return 1.0f; - } - - public static float GetHalfCircle(AngleUnit unit) - { - if (unit == AngleUnit.RADIANS) - { - return PI; - } - - if (unit == AngleUnit.DEGREES) - { - return 180.0f; - } - - return 0.5f; - } - - public static float GetQuarterCircle(AngleUnit unit) - { - if (unit == AngleUnit.RADIANS) - { - return HALF_OF_PI; - } - - if (unit == AngleUnit.DEGREES) - { - return 90.0f; - } - - return 0.25f; - } - - public static float NormalizeRadians(float radians, AngleRange range) - { - if (range == AngleRange.UNSIGNED_RANGE) - { - if (0.0 <= radians && radians < TWO_PI) - { - return radians; - } - - } - else - { - if (-PI < radians && radians <= PI) - { - return radians; - } - } - - float turns = radians * TURNS_IN_RADIAN; - - turns -= MathF.Floor(turns); - - if (range == AngleRange.SIGNED_RANGE && turns > 0.5f) - { - turns -= 1.0f; - } - - return turns * TWO_PI; - } - - public static float NormalizeDegrees(float radians, AngleRange range) - { - if (range == AngleRange.UNSIGNED_RANGE) - { - if (0.0f <= radians && radians < 360.0f) - { - return radians; - } - } - else - { - if (-180.0f < radians && radians <= 180.0f) - { - return radians; - } - } - - float turns = radians * TURNS_IN_DEGREE; - - turns -= MathF.Floor(turns); - - if (range == AngleRange.SIGNED_RANGE && turns > 0.5f) - { - turns -= 1.0f; - } - - return turns * 360.0f; - } - - public static float NormalizeTurns(float turns, AngleRange range) - { - if (range == AngleRange.UNSIGNED_RANGE) - { - if (0.0f <= turns && turns < 1.0f) - { - return turns; - } - } - else - { - if (-0.5f < turns && turns <= 0.5f) - { - return turns; - } - } - - float rest = turns - MathF.Floor(turns); - - if (range == AngleRange.SIGNED_RANGE && rest > 0.5f) - { - rest -= 1.0f; - } - - return rest; - } - - public static float Normalize(float angle, AngleUnit unit, AngleRange range) - { - if (unit == AngleUnit.RADIANS) - { - return NormalizeRadians(angle, range); - } - - if (unit == AngleUnit.DEGREES) - { - return NormalizeDegrees(angle, range); - } - - return NormalizeTurns(angle, range); - } - } -}