using Microsoft.VisualStudio.TestTools.UnitTesting; using NavisworksTransport.Core; using NavisworksTransport.Utils; using NavisworksTransport.Utils.CoordinateSystem; using System.Numerics; namespace NavisworksTransport.UnitTests.CoordinateSystem { [TestClass] public class CanonicalRailOffsetResolverTests { [TestMethod] public void OverRail_ShouldOffsetTrackedCenterAlongNormalByHalfHeight() { PathRoute route = new PathRoute { PathType = PathType.Rail, RailMountMode = RailMountMode.OverRail, RailPathDefinitionMode = RailPathDefinitionMode.RailCenterLine }; RailLocalFrame frame = new RailLocalFrame(Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ); Vector3 trackedCenter = CanonicalRailOffsetResolver.ResolveTrackedCenter( route, Vector3.Zero, frame, 4.0); AssertVector(trackedCenter, 0.0, 0.0, 2.0); } [TestMethod] public void UnderRail_ShouldOffsetTrackedCenterOppositeToNormalByHalfHeight() { PathRoute route = new PathRoute { PathType = PathType.Rail, RailMountMode = RailMountMode.UnderRail, RailPathDefinitionMode = RailPathDefinitionMode.RailCenterLine }; RailLocalFrame frame = new RailLocalFrame(Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ); Vector3 trackedCenter = CanonicalRailOffsetResolver.ResolveTrackedCenter( route, Vector3.Zero, frame, 4.0); AssertVector(trackedCenter, 0.0, 0.0, -2.0); } [TestMethod] public void SlopedNormal_ShouldMoveTrackedCenterAlongRailNormalInsteadOfWorldUp() { PathRoute route = new PathRoute { PathType = PathType.Rail, RailMountMode = RailMountMode.OverRail, RailPathDefinitionMode = RailPathDefinitionMode.RailCenterLine }; Vector3 normal = Vector3.Normalize(new Vector3(0f, 1f, 1f)); RailLocalFrame frame = new RailLocalFrame(Vector3.UnitX, Vector3.UnitY, normal); Vector3 trackedCenter = CanonicalRailOffsetResolver.ResolveTrackedCenter( route, new Vector3(10f, 20f, 30f), frame, 4.0); Vector3 expected = new Vector3(10f, 20f, 30f) + normal * 2f; AssertVector(trackedCenter, expected.X, expected.Y, expected.Z); } [TestMethod] public void AnchorSemantic_ShouldOnlyUseHalfHeightOffset_WhenReferencePointIsAlreadyAnchor() { PathRoute route = new PathRoute { PathType = PathType.Rail, RailMountMode = RailMountMode.OverRail, RailPathDefinitionMode = RailPathDefinitionMode.RailCenterLine }; RailLocalFrame frame = new RailLocalFrame(Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ); Vector3 trackedCenter = CanonicalRailOffsetResolver.ResolveTrackedCenter( route, Vector3.Zero, frame, 4.0); AssertVector(trackedCenter, 0.0, 0.0, 2.0); } [TestMethod] public void RailNormalOffset_ShouldAddExtraDisplacementAlongRailNormal() { PathRoute route = new PathRoute { PathType = PathType.Rail, RailMountMode = RailMountMode.OverRail, RailPathDefinitionMode = RailPathDefinitionMode.RailCenterLine, RailNormalOffset = 1.5 }; RailLocalFrame frame = new RailLocalFrame(Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ); Vector3 trackedCenter = CanonicalRailOffsetResolver.ResolveTrackedCenter( route, Vector3.Zero, frame, 4.0); AssertVector(trackedCenter, 0.0, 0.0, 3.5); } [TestMethod] public void PreservedTrackedCenterOffset_ShouldBeMeasuredFromRailSemanticCenter() { Vector3 semanticTrackedCenter = new Vector3(10f, 20f, 30f); Vector3 actualTrackedCenter = new Vector3(11.25f, 19.5f, 30.75f); Vector3 offset = RailPathPoseHelper.CalculatePreservedTrackedCenterOffset( actualTrackedCenter, semanticTrackedCenter); AssertVector(offset, 1.25, -0.5, 0.75); } [TestMethod] public void ResolvePreservedTrackedCenterPosition_ShouldReuseRailSemanticCenterPlusOffset() { Vector3 semanticTrackedCenter = new Vector3(3f, -2f, 8f); Vector3 preservedOffset = new Vector3(0.2f, -0.4f, 0.6f); Vector3 preservedTrackedCenter = RailPathPoseHelper.ResolvePreservedTrackedCenterPosition( semanticTrackedCenter, preservedOffset); AssertVector(preservedTrackedCenter, 3.2, -2.4, 8.6); } private static void AssertVector(Vector3 actual, double x, double y, double z) { Assert.AreEqual(x, actual.X, 1e-6); Assert.AreEqual(y, actual.Y, 1e-6); Assert.AreEqual(z, actual.Z, 1e-6); } } }