using Microsoft.VisualStudio.TestTools.UnitTesting; using NavisworksTransport.Utils.CoordinateSystem; using System; using System.Numerics; namespace NavisworksTransport.UnitTests.CoordinateSystem { [TestClass] public class RotatedObjectExtentHelperTests { [TestMethod] public void YUp_HostY90_ForRealObject_ShouldKeepUpExtentUnchanged() { var adapter = new HostCoordinateAdapter(CoordinateSystemType.YUp); var convention = ModelAxisConvention.CreateDefaultForHost(CoordinateSystemType.YUp); Quaternion correction = adapter.CreateHostRotationCorrection( new LocalEulerRotationCorrection(0.0, 90.0, 0.0)); var result = RotatedObjectExtentHelper.CalculateProjectedSemanticExtents( convention, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, correctionQuaternion: correction); Assert.AreEqual(4.0, result.forwardExtent, 1e-6); Assert.AreEqual(6.0, result.sideExtent, 1e-6); Assert.AreEqual(2.0, result.upExtent, 1e-6); } [TestMethod] public void YUp_HostZ90_ForRealObject_ShouldPromoteForwardSizeToUpExtent() { var adapter = new HostCoordinateAdapter(CoordinateSystemType.YUp); var convention = ModelAxisConvention.CreateDefaultForHost(CoordinateSystemType.YUp); Quaternion correction = adapter.CreateHostRotationCorrection( new LocalEulerRotationCorrection(0.0, 0.0, 90.0)); var result = RotatedObjectExtentHelper.CalculateProjectedSemanticExtents( convention, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, correctionQuaternion: correction); Assert.AreEqual(2.0, result.forwardExtent, 1e-6); Assert.AreEqual(4.0, result.sideExtent, 1e-6); Assert.AreEqual(6.0, result.upExtent, 1e-6); } [TestMethod] public void ZUp_HostZDegrees_ShouldPromoteForwardSizeToUpExtent() { // ZUp 下 ZDegrees = non-up 轴(=Y)。绕 Y 转 90°:X(forward)→-Z(up), Z(up)→X。 // forward(6) 提升到 up,up(2) 降到 forward。 var adapter = new HostCoordinateAdapter(CoordinateSystemType.ZUp); var convention = ModelAxisConvention.CreateDefaultForHost(CoordinateSystemType.ZUp); Quaternion correction = adapter.CreateCanonicalRotationCorrection( new LocalEulerRotationCorrection(0.0, 0.0, 90.0)); var result = RotatedObjectExtentHelper.CalculateProjectedSemanticExtents( convention, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, correctionQuaternion: correction); Assert.AreEqual(2.0, result.forwardExtent, 1e-6); Assert.AreEqual(4.0, result.sideExtent, 1e-6); Assert.AreEqual(6.0, result.upExtent, 1e-6); } [TestMethod] public void ZUp_HostYDegrees_ShouldKeepUpExtentUnchanged() { // ZUp 下 YDegrees = up 轴(=Z)。绕 Z 转 90°:X→Y, Y→-X, Z(up) 不变。 // forward 和 side 互换,up 不变。 var adapter = new HostCoordinateAdapter(CoordinateSystemType.ZUp); var convention = ModelAxisConvention.CreateDefaultForHost(CoordinateSystemType.ZUp); Quaternion correction = adapter.CreateCanonicalRotationCorrection( new LocalEulerRotationCorrection(0.0, 90.0, 0.0)); var result = RotatedObjectExtentHelper.CalculateProjectedSemanticExtents( convention, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, correctionQuaternion: correction); Assert.AreEqual(4.0, result.forwardExtent, 1e-6); Assert.AreEqual(6.0, result.sideExtent, 1e-6); Assert.AreEqual(2.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostY90_ShouldSwapForwardAndSide() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(0.0, 90.0, 0.0)); Assert.AreEqual(4.0, result.forwardExtent, 1e-6); Assert.AreEqual(6.0, result.sideExtent, 1e-6); Assert.AreEqual(2.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostY45_ShouldBlendForwardAndSide_AndKeepUp() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(0.0, 45.0, 0.0)); double expectedPlanar = 5.0 * Math.Sqrt(2.0); Assert.AreEqual(expectedPlanar, result.forwardExtent, 1e-6); Assert.AreEqual(expectedPlanar, result.sideExtent, 1e-6); Assert.AreEqual(2.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostY135_ShouldBlendForwardAndSide_AndKeepUp() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(0.0, 135.0, 0.0)); double expectedPlanar = 5.0 * Math.Sqrt(2.0); Assert.AreEqual(expectedPlanar, result.forwardExtent, 1e-6); Assert.AreEqual(expectedPlanar, result.sideExtent, 1e-6); Assert.AreEqual(2.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostY180_ShouldKeepSemanticExtents() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(0.0, 180.0, 0.0)); Assert.AreEqual(6.0, result.forwardExtent, 1e-6); Assert.AreEqual(4.0, result.sideExtent, 1e-6); Assert.AreEqual(2.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostY270_ShouldSwapForwardAndSide() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(0.0, 270.0, 0.0)); Assert.AreEqual(4.0, result.forwardExtent, 1e-6); Assert.AreEqual(6.0, result.sideExtent, 1e-6); Assert.AreEqual(2.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostX90_ShouldKeepForward_AndSwapSideWithUp() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(90.0, 0.0, 0.0)); Assert.AreEqual(6.0, result.forwardExtent, 1e-6); Assert.AreEqual(2.0, result.sideExtent, 1e-6); Assert.AreEqual(4.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostX45_ShouldKeepForward_AndBlendSideWithUp() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(45.0, 0.0, 0.0)); double expectedBlend = 3.0 * Math.Sqrt(2.0); Assert.AreEqual(6.0, result.forwardExtent, 1e-6); Assert.AreEqual(expectedBlend, result.sideExtent, 1e-6); Assert.AreEqual(expectedBlend, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostX135_ShouldKeepForward_AndBlendSideWithUp() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(135.0, 0.0, 0.0)); double expectedBlend = 3.0 * Math.Sqrt(2.0); Assert.AreEqual(6.0, result.forwardExtent, 1e-6); Assert.AreEqual(expectedBlend, result.sideExtent, 1e-6); Assert.AreEqual(expectedBlend, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostX180_ShouldKeepSemanticExtents() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(180.0, 0.0, 0.0)); Assert.AreEqual(6.0, result.forwardExtent, 1e-6); Assert.AreEqual(4.0, result.sideExtent, 1e-6); Assert.AreEqual(2.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostX270_ShouldKeepForward_AndSwapSideWithUp() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(270.0, 0.0, 0.0)); Assert.AreEqual(6.0, result.forwardExtent, 1e-6); Assert.AreEqual(2.0, result.sideExtent, 1e-6); Assert.AreEqual(4.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostZ90_ShouldPromoteUpToForward_AndKeepSide() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(0.0, 0.0, 90.0)); Assert.AreEqual(2.0, result.forwardExtent, 1e-6); Assert.AreEqual(4.0, result.sideExtent, 1e-6); Assert.AreEqual(6.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostZ45_ShouldBlendForwardWithUp_AndKeepSide() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(0.0, 0.0, 45.0)); double expectedBlend = 4.0 * Math.Sqrt(2.0); Assert.AreEqual(expectedBlend, result.forwardExtent, 1e-6); Assert.AreEqual(4.0, result.sideExtent, 1e-6); Assert.AreEqual(expectedBlend, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostZ135_ShouldBlendForwardWithUp_AndKeepSide() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(0.0, 0.0, 135.0)); double expectedBlend = 4.0 * Math.Sqrt(2.0); Assert.AreEqual(expectedBlend, result.forwardExtent, 1e-6); Assert.AreEqual(4.0, result.sideExtent, 1e-6); Assert.AreEqual(expectedBlend, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostZ180_ShouldKeepSemanticExtents() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(0.0, 0.0, 180.0)); Assert.AreEqual(6.0, result.forwardExtent, 1e-6); Assert.AreEqual(4.0, result.sideExtent, 1e-6); Assert.AreEqual(2.0, result.upExtent, 1e-6); } [TestMethod] public void Ground_YUp_HostZ270_ShouldPromoteUpToForward_AndKeepSide() { var result = RotatedObjectExtentHelper.CalculateGroundSemanticExtents( CoordinateSystemType.YUp, forwardSize: 6.0, sideSize: 4.0, upSize: 2.0, hostCorrection: new LocalEulerRotationCorrection(0.0, 0.0, 270.0)); Assert.AreEqual(2.0, result.forwardExtent, 1e-6); Assert.AreEqual(4.0, result.sideExtent, 1e-6); Assert.AreEqual(6.0, result.upExtent, 1e-6); } } }