NavisworksTransport/UnitTests/CoordinateSystem/RealObjectProjectedExtentResolverTests.cs

146 lines
6.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.VisualStudio.TestTools.UnitTesting;
using NavisworksTransport.Utils.CoordinateSystem;
using System.Numerics;
namespace NavisworksTransport.UnitTests.CoordinateSystem
{
[TestClass]
public class RealObjectProjectedExtentResolverTests
{
[TestMethod]
public void Ground_DualAxisCorrection_ShouldProjectAgainstFinalPose()
{
var convention = new ModelAxisConvention(LocalAxisDirection.PositiveX, LocalAxisDirection.PositiveY);
Vector3 targetForward = Vector3.Normalize(new Vector3(-0.8987f, 0.0f, 0.4386f));
Vector3 targetUp = Vector3.UnitY;
Quaternion baseline = Quaternion.Normalize(Quaternion.CreateFromRotationMatrix(new Matrix4x4(
-0.8987f, 0.0000f, 0.4386f, 0f,
0.0000f, 1.0000f, 0.0000f, 0f,
-0.4386f, 0.0000f,-0.8987f, 0f,
0f, 0f, 0f, 1f)));
var adapter = new HostCoordinateAdapter(CoordinateSystemType.YUp);
Quaternion final = adapter.ComposeHostQuaternion(
baseline,
new LocalEulerRotationCorrection(90.0, 0.0, 90.0));
var extents = RealObjectProjectedExtentResolver.CalculateProjectedSemanticExtents(
convention,
forwardSize: 6.0,
sideSize: 2.0,
upSize: 4.0,
baseline,
final,
targetForward,
targetUp);
Vector3 localSize = convention.CreateScaleVector3(6.0, 2.0, 4.0);
Vector3 rotatedLocalX = Vector3.Normalize(Vector3.Transform(Vector3.UnitX, final));
Vector3 rotatedLocalY = Vector3.Normalize(Vector3.Transform(Vector3.UnitY, final));
Vector3 rotatedLocalZ = Vector3.Normalize(Vector3.Transform(Vector3.UnitZ, final));
Vector3 targetSide = Vector3.Normalize(Vector3.Cross(targetForward, targetUp));
double expectedForward = ProjectExtent(localSize, rotatedLocalX, rotatedLocalY, rotatedLocalZ, targetForward);
double expectedSide = ProjectExtent(localSize, rotatedLocalX, rotatedLocalY, rotatedLocalZ, targetSide);
double expectedUp = ProjectExtent(localSize, rotatedLocalX, rotatedLocalY, rotatedLocalZ, targetUp);
Assert.AreEqual(expectedForward, extents.forwardExtent, 1e-5);
Assert.AreEqual(expectedSide, extents.sideExtent, 1e-5);
Assert.AreEqual(expectedUp, extents.upExtent, 1e-5);
Assert.AreNotEqual(4.0, extents.upExtent, 1e-3, "双轴旋转后Ground 的法线尺寸不应停留在旧高度。");
}
[TestMethod]
public void Ground_DisplayedHostAxesProjection_ShouldKeepXAxisLengthAndSwapXZAsAxesRotate()
{
Vector3 targetForward = Vector3.UnitX;
Vector3 targetUp = Vector3.UnitY;
var noCorrection = RealObjectProjectedExtentResolver.CalculateProjectedDisplayedExtents(
displayedAxisXSize: 6.0,
displayedAxisYSize: 2.0,
displayedAxisZSize: 4.0,
displayedHostAxisX: Vector3.UnitX,
displayedHostAxisY: Vector3.UnitZ,
displayedHostAxisZ: -Vector3.UnitY,
targetForward,
targetUp);
Assert.AreEqual(6.0, noCorrection.forwardExtent, 1e-5);
Assert.AreEqual(2.0, noCorrection.sideExtent, 1e-5);
Assert.AreEqual(4.0, noCorrection.upExtent, 1e-5);
var xRotated = RealObjectProjectedExtentResolver.CalculateProjectedDisplayedExtents(
displayedAxisXSize: 6.0,
displayedAxisYSize: 2.0,
displayedAxisZSize: 4.0,
displayedHostAxisX: Vector3.UnitX,
displayedHostAxisY: Vector3.UnitY,
displayedHostAxisZ: Vector3.UnitZ,
targetForward,
targetUp);
Assert.AreEqual(6.0, xRotated.forwardExtent, 1e-5);
Assert.AreEqual(4.0, xRotated.sideExtent, 1e-5);
Assert.AreEqual(2.0, xRotated.upExtent, 1e-5);
var zRotated = RealObjectProjectedExtentResolver.CalculateProjectedDisplayedExtents(
displayedAxisXSize: 6.0,
displayedAxisYSize: 2.0,
displayedAxisZSize: 4.0,
displayedHostAxisX: -Vector3.UnitZ,
displayedHostAxisY: Vector3.UnitX,
displayedHostAxisZ: -Vector3.UnitY,
targetForward,
targetUp);
Assert.AreEqual(2.0, zRotated.forwardExtent, 1e-5);
Assert.AreEqual(6.0, zRotated.sideExtent, 1e-5);
Assert.AreEqual(4.0, zRotated.upExtent, 1e-5);
}
[TestMethod]
public void Ground_DisplayedHostAxesProjection_ShouldIgnoreVerticalComponentInForward()
{
Vector3 targetUp = Vector3.UnitY;
Vector3 planarForward = Vector3.Normalize(new Vector3(1f, 0f, 1f));
Vector3 slopedForward = Vector3.Normalize(new Vector3(1f, 2f, 1f));
var planar = RealObjectProjectedExtentResolver.CalculateProjectedDisplayedExtents(
displayedAxisXSize: 6.0,
displayedAxisYSize: 2.0,
displayedAxisZSize: 4.0,
displayedHostAxisX: Vector3.UnitX,
displayedHostAxisY: Vector3.UnitZ,
displayedHostAxisZ: -Vector3.UnitY,
planarForward,
targetUp);
var sloped = RealObjectProjectedExtentResolver.CalculateProjectedDisplayedExtents(
displayedAxisXSize: 6.0,
displayedAxisYSize: 2.0,
displayedAxisZSize: 4.0,
displayedHostAxisX: Vector3.UnitX,
displayedHostAxisY: Vector3.UnitZ,
displayedHostAxisZ: -Vector3.UnitY,
slopedForward,
targetUp);
Assert.AreNotEqual(planar.forwardExtent, sloped.forwardExtent, 1e-3, "原始带竖直分量的路径方向会污染 Ground 尺寸投影。");
}
private static double ProjectExtent(
Vector3 localSize,
Vector3 rotatedLocalX,
Vector3 rotatedLocalY,
Vector3 rotatedLocalZ,
Vector3 targetAxis)
{
return System.Math.Abs(Vector3.Dot(rotatedLocalX, targetAxis)) * localSize.X +
System.Math.Abs(Vector3.Dot(rotatedLocalY, targetAxis)) * localSize.Y +
System.Math.Abs(Vector3.Dot(rotatedLocalZ, targetAxis)) * localSize.Z;
}
}
}