diff --git a/AnyCAD.Math.Test/AnyCAD.Math.Test.csproj b/AnyCAD.Math.Test/AnyCAD.Math.Test.csproj new file mode 100644 index 0000000000000000000000000000000000000000..2cb5b863273c32a6f244c7e04f108c6af8ddb28e --- /dev/null +++ b/AnyCAD.Math.Test/AnyCAD.Math.Test.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + enable + enable + + false + true + + + + + + + + + + + diff --git a/AnyCAD.Math.Test/GPntTest.cs b/AnyCAD.Math.Test/GPntTest.cs new file mode 100644 index 0000000000000000000000000000000000000000..2207b49e2da76c586fdb7da7bb2bdf0bf72c5c93 --- /dev/null +++ b/AnyCAD.Math.Test/GPntTest.cs @@ -0,0 +1,446 @@ +namespace AnyCAD.Math.Test +{ + /// + /// GPnt对象(三维坐标点)相关接口的单元测试集 + /// API参考文档:http://anycad.cn/api/2024/class_g_pnt.html + /// + [TestClass] + public class GPntTest + { + [TestMethod] + public void TestDefaultConstructor() + { + // Arrange & Act + var point = new GPnt(); + + // Assert + Assert.AreEqual(0, point.X()); + Assert.AreEqual(0, point.Y()); + Assert.AreEqual(0, point.Z()); + } + + [TestMethod] + public void TestConstructorWithParameters() + { + // Arrange + double x = 1.0; + double y = 2.0; + double z = 3.0; + + // Act + var point = new GPnt(x, y, z); + + // Assert + Assert.AreEqual(x, point.X()); + Assert.AreEqual(y, point.Y()); + Assert.AreEqual(z, point.Z()); + } + + + [TestMethod] + public void TestBaryCenter_MidPoint() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var otherPoint = new GPnt(2.0, 3.0, 4.0); + double alpha = 1.0; + double beta = 1.0; + + // Act + point.BaryCenter(alpha, otherPoint, beta); + + // Assert + Assert.AreEqual(1.5, point.X()); + Assert.AreEqual(2.5, point.Y()); + Assert.AreEqual(3.5, point.Z()); + } + + [TestMethod] + public void TestBaryCenter_WeightedAverage() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var otherPoint = new GPnt(2.0, 3.0, 4.0); + double alpha = 1.0; + double beta = 2.0; + + // Act + point.BaryCenter(alpha, otherPoint, beta); + + // Assert + Assert.AreEqual(5.0 / 3.0, point.X()); + Assert.AreEqual(8.0 / 3.0, point.Y()); + Assert.AreEqual(11.0 / 3.0, point.Z()); + } + + [TestMethod] + public void TestIsEqual_SamePoint() + { + // Arrange + var point1 = new GPnt(1.0, 2.0, 3.0); + var point2 = new GPnt(1.0, 2.0, 3.0); + double tolerance = 0.1; + + // Act + bool isEqual = point1.IsEqual(point2, tolerance); + + // Assert + Assert.IsTrue(isEqual); + } + + [TestMethod] + public void TestIsEqual_DifferentPointsWithinTolerance() + { + // Arrange + var point1 = new GPnt(1.0, 2.0, 3.0); + var point2 = new GPnt(1.01, 2.01, 3.01); + double tolerance = 0.05; + + // Act + bool isEqual = point1.IsEqual(point2, tolerance); + + // Assert + Assert.IsTrue(isEqual); + } + + [TestMethod] + public void TestIsEqual_DifferentPointsOutsideTolerance() + { + // Arrange + var point1 = new GPnt(1.0, 2.0, 3.0); + var point2 = new GPnt(2.0, 3.0, 4.0); + double tolerance = 0.1; + + // Act + bool isEqual = point1.IsEqual(point2, tolerance); + + // Assert + Assert.IsFalse(isEqual); + } + + [TestMethod] + public void TestDistance_SamePoint() + { + // Arrange + var point1 = new GPnt(1.0, 2.0, 3.0); + var point2 = new GPnt(1.0, 2.0, 3.0); + + // Act + double distance = point1.Distance(point2); + + // Assert + Assert.AreEqual(0, distance); + } + + [TestMethod] + public void TestDistance_DifferentPoints() + { + // Arrange + var point1 = new GPnt(1.0, 2.0, 3.0); + var point2 = new GPnt(4.0, 5.0, 6.0); + + // Act + double distance = point1.Distance(point2); + + // Assert + Assert.AreEqual(System.Math.Sqrt(27.0), distance); + } + + [TestMethod] + public void TestDistance_NegativeCoordinates() + { + // Arrange + var point1 = new GPnt(-1.0, -2.0, -3.0); + var point2 = new GPnt(-4.0, -5.0, -6.0); + + // Act + double distance = point1.Distance(point2); + + // Assert + Assert.AreEqual(System.Math.Sqrt(27.0), distance); + } + + [TestMethod] + public void TestSquareDistance_SamePoint() + { + // Arrange + var point1 = new GPnt(1.0, 2.0, 3.0); + var point2 = new GPnt(1.0, 2.0, 3.0); + + // Act + double squareDistance = point1.SquareDistance(point2); + + // Assert + Assert.AreEqual(0.0, squareDistance); + } + + [TestMethod] + public void TestSquareDistance_DifferentPoints() + { + // Arrange + var point1 = new GPnt(1.0, 2.0, 3.0); + var point2 = new GPnt(4.0, 5.0, 6.0); + + // Act + double squareDistance = point1.SquareDistance(point2); + + // Assert + Assert.AreEqual(27.0, squareDistance); + } + + [TestMethod] + public void TestMirror_Origin() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var mirrorPoint = new GPnt(0.0, 0.0, 0.0); + + // Act + var mirroredPoint = point.Mirrored(mirrorPoint); + point.Mirror(mirrorPoint); + + // Assert + Assert.AreEqual(-1.0, mirroredPoint.X()); + Assert.AreEqual(-2.0, mirroredPoint.Y()); + Assert.AreEqual(-3.0, mirroredPoint.Z()); + + Assert.AreEqual(-1.0, point.X()); + Assert.AreEqual(-2.0, point.Y()); + Assert.AreEqual(-3.0, point.Z()); + } + + [TestMethod] + public void TestMirror_NonOrigin() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var mirrorPoint = new GPnt(1.0, 1.0, 1.0); + + // Act + var mirroredPoint = point.Mirrored(mirrorPoint); + point.Mirror(mirrorPoint); + + // Assert + Assert.AreEqual(1.0, mirroredPoint.X()); + Assert.AreEqual(0.0, mirroredPoint.Y()); + Assert.AreEqual(-1.0, mirroredPoint.Z()); + + Assert.AreEqual(1.0, point.X()); + Assert.AreEqual(0.0, point.Y()); + Assert.AreEqual(-1.0, point.Z()); + } + + [TestMethod] + public void TestScale_Origin() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var scalePoint = new GPnt(0.0, 0.0, 0.0); + double scaleValue = 2.0; + + // Act + var scaledPoint = point.Scaled(scalePoint, scaleValue); + point.Scale(scalePoint, scaleValue); + + // Assert + Assert.AreEqual(2.0, point.X()); + Assert.AreEqual(4.0, point.Y()); + Assert.AreEqual(6.0, point.Z()); + } + + [TestMethod] + public void TestScale_NonOrigin() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var scalePoint = new GPnt(1.0, 1.0, 1.0); + double scaleValue = 2.0; + + // Act + point.Scale(scalePoint, scaleValue); + + // Assert + Assert.AreEqual(1.0, point.X()); + Assert.AreEqual(3.0, point.Y()); + Assert.AreEqual(5.0, point.Z()); + } + + [TestMethod] + public void TestTranslate() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var point1 = new GPnt(1.0, 1.0, 1.0); + var point2 = new GPnt(2.0, 2.0, 2.0); + var expectedPoint = new GPnt(point.X() + point2.X() - point1.X(), point.Y() + point2.Y() - point1.Y(), point.Z() + point2.Z() - point1.Z()); + + // Act + point.Translate(point1, point2); + + // Assert + Assert.AreEqual(expectedPoint.X(), point.X()); + Assert.AreEqual(expectedPoint.Y(), point.Y()); + Assert.AreEqual(expectedPoint.Z(), point.Z()); + } + + [TestMethod] + public void TestTranslate_Vector() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var vector = new GVec(1.0, 1.0, 1.0); + + // Act + point.Translate(vector); + + // Assert + Assert.AreEqual(2.0, point.X()); + Assert.AreEqual(3.0, point.Y()); + Assert.AreEqual(4.0, point.Z()); + } + + [TestMethod] + public void TestTranslate_NegativeVector() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var vector = new GVec(-1.0, -1.0, -1.0); + + // Act + point.Translate(vector); + + // Assert + Assert.AreEqual(0.0, point.X()); + Assert.AreEqual(1.0, point.Y()); + Assert.AreEqual(2.0, point.Z()); + } + + [TestMethod] + public void TestRotate_ZeroAngle() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var axis = new GAx1(new GPnt(0.0, 0.0, 0.0), new GDir(0.0, 0.0, 1.0)); + double angle = 0.0; + + // Act + point.Rotate(axis, angle); + + // Assert + Assert.AreEqual(1.0, point.X()); + Assert.AreEqual(2.0, point.Y()); + Assert.AreEqual(3.0, point.Z()); + } + + [TestMethod] + public void TestRotate_NonZeroAngle() + { + // Arrange + var point = new GPnt(1.0, 0.0, 0.0); + var axis = new GAx1(new GPnt(0.0, 0.0, 0.0), new GDir(0.0, 0.0, 1.0)); + double angle = System.Math.PI / 2; // 90 degrees + + // Act + point.Rotate(axis, angle); + + // Assert + Assert.AreEqual(0.0, point.X(), 1e-10); + Assert.AreEqual(1.0, point.Y(), 1e-10); + Assert.AreEqual(0.0, point.Z(), 1e-10); + } + + [TestMethod] + public void TestRotate_NonAlignedAxis() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var axis = new GAx1(new GPnt(1.0, 1.0, 1.0), new GDir(1.0, 1.0, 1.0)); + double angle = System.Math.PI / 2; // 90 degrees + + // Act + point.Rotate(axis, angle); + + // Assert + Assert.AreEqual(2.5773502691896262, point.X(), 1e-10); + Assert.AreEqual(0.84529946162074832, point.Y(), 1e-10); + Assert.AreEqual(2.5773502691896257, point.Z(), 1e-10); + } + + [TestMethod] + public void TestTransform_Translation() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var transformation = new GTrsf(); + transformation.SetTranslation(new GVec(1.0, 1.0, 1.0)); + + // Act + point.Transform(transformation); + + // Assert + Assert.AreEqual(2.0, point.X()); + Assert.AreEqual(3.0, point.Y()); + Assert.AreEqual(4.0, point.Z()); + } + + [TestMethod] + public void TestTransform_Rotation() + { + // Arrange + var point = new GPnt(1.0, 0.0, 0.0); + var transformation = new GTrsf(); + transformation.SetRotation(new GAx1(new GPnt(0.0, 0.0, 0.0), new GDir(0.0, 0.0, 1.0)), System.Math.PI / 2); + + // Act + point.Transform(transformation); + + // Assert + Assert.AreEqual(0.0, point.X(), 1e-10); + Assert.AreEqual(1.0, point.Y(), 1e-10); + Assert.AreEqual(0.0, point.Z(), 1e-10); + } + + [TestMethod] + public void TestTransform_Scaling() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var transformation = new GTrsf(); + transformation.SetScale(new GPnt(0.0, 0.0, 0.0), 2.0); + + // Act + point.Transform(transformation); + + // Assert + Assert.AreEqual(2.0, point.X()); + Assert.AreEqual(4.0, point.Y()); + Assert.AreEqual(6.0, point.Z()); + } + + [TestMethod] + public void TestTransform_ComplexTransformation() + { + // Arrange + var point = new GPnt(1.0, 2.0, 3.0); + var expectedPoint = new GPnt(point.X(), point.Y(), point.Z()); + var transformation = new GTrsf(); + transformation.SetScaleFactor(2.0); + var quaternion = new GQuaternion(new GVec(0.0, 0.0, 1.0), System.Math.PI / 2); + transformation.SetRotationPart(quaternion); + transformation.SetTranslationPart(new GVec(1.0, 1.0, 1.0)); + + // Apply the transformations to the expected point + expectedPoint.Scale(new GPnt(0.0, 0.0, 0.0), 2.0); + expectedPoint.Rotate(new GAx1(new GPnt(0.0, 0.0, 0.0), new GDir(0.0, 0.0, 1.0)), System.Math.PI / 2); + expectedPoint.Translate(new GVec(1.0, 1.0, 1.0)); + + // Act + point.Transform(transformation); + + // Assert + Assert.AreEqual(expectedPoint.X(), point.X(), 1e-10); + Assert.AreEqual(expectedPoint.Y(), point.Y(), 1e-10); + Assert.AreEqual(expectedPoint.Z(), point.Z(), 1e-10); + } + } +} \ No newline at end of file diff --git a/AnyCAD.Math.Test/Usings.cs b/AnyCAD.Math.Test/Usings.cs new file mode 100644 index 0000000000000000000000000000000000000000..9486fdc5d9cf0f386624d7f48001a511acd76074 --- /dev/null +++ b/AnyCAD.Math.Test/Usings.cs @@ -0,0 +1,2 @@ +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using AnyCAD.Foundation; \ No newline at end of file diff --git a/AnyCAD.WPF.sln b/AnyCAD.WPF.sln index a8e71b3326e19fba2e13e19fb2f6596569c43003..2fed8e1f7d27c08d5192c7b15745409b00381b25 100644 --- a/AnyCAD.WPF.sln +++ b/AnyCAD.WPF.sln @@ -15,6 +15,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo", "Demo", "{D5525FDA-F EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ThirdParty", "ThirdParty", "{A327B286-99C8-4A86-99A6-36B8B5E049B2}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTest", "UnitTest", "{4A50FDEE-FAE5-47A0-98C0-E4DFB97C32D4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnyCAD.Math.Test", "AnyCAD.Math.Test\AnyCAD.Math.Test.csproj", "{AB11DAA2-1350-4834-8087-A06919B17785}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,6 +37,10 @@ Global {26A2B2C6-7F2A-4AEC-A30C-2127F744CDD8}.Debug|Any CPU.Build.0 = Debug|Any CPU {26A2B2C6-7F2A-4AEC-A30C-2127F744CDD8}.Release|Any CPU.ActiveCfg = Release|Any CPU {26A2B2C6-7F2A-4AEC-A30C-2127F744CDD8}.Release|Any CPU.Build.0 = Release|Any CPU + {AB11DAA2-1350-4834-8087-A06919B17785}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AB11DAA2-1350-4834-8087-A06919B17785}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AB11DAA2-1350-4834-8087-A06919B17785}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AB11DAA2-1350-4834-8087-A06919B17785}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -41,6 +49,7 @@ Global {06D82C47-4E79-48D8-A8EE-5C9D543CC2D8} = {E7BD2F7C-A826-4279-9DBB-4B759743B462} {D09227E0-376D-4447-BA56-1BF23C881560} = {D5525FDA-F8A6-4E28-BBFE-3EEA850F27C5} {26A2B2C6-7F2A-4AEC-A30C-2127F744CDD8} = {D5525FDA-F8A6-4E28-BBFE-3EEA850F27C5} + {AB11DAA2-1350-4834-8087-A06919B17785} = {4A50FDEE-FAE5-47A0-98C0-E4DFB97C32D4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E7B41709-A273-4FB1-A228-F92061A2833D}