143 lines
6.3 KiB
C#
143 lines
6.3 KiB
C#
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using NavisworksTransport.Utils.CoordinateSystem;
|
|
using System;
|
|
using System.Numerics;
|
|
|
|
namespace NavisworksTransport.UnitTests.CoordinateSystem
|
|
{
|
|
[TestClass]
|
|
public class RealObjectRailExtentResolverTests
|
|
{
|
|
[TestMethod]
|
|
public void YUp_ZeroCorrection_ShouldKeepResolvedRailUpExtent()
|
|
{
|
|
Vector3 referenceAxisX = new Vector3(-1.0f, 0.0f, 0.0f);
|
|
Vector3 referenceAxisY = new Vector3(0.0f, 1.0f, 0.0f);
|
|
Vector3 referenceAxisZ = new Vector3(0.0f, 0.0f, -1.0f);
|
|
Vector3 desiredForward = Vector3.Normalize(new Vector3(-0.8987f, 0.0f, 0.4386f));
|
|
Quaternion baseline = Quaternion.Identity;
|
|
|
|
bool ok = RealObjectRailExtentResolver.TryResolveProjectedSemanticExtents(
|
|
referenceAxisX,
|
|
referenceAxisY,
|
|
referenceAxisZ,
|
|
desiredForward,
|
|
CoordinateSystemType.YUp,
|
|
forwardSize: 6.0,
|
|
sideSize: 2.0,
|
|
upSize: 4.0,
|
|
baseline,
|
|
baseline,
|
|
out ModelAxisConvention convention,
|
|
out var extents);
|
|
|
|
Assert.IsTrue(ok);
|
|
Assert.AreEqual(LocalAxisDirection.PositiveX, convention.ForwardAxis);
|
|
Assert.AreEqual(LocalAxisDirection.PositiveY, convention.UpAxis);
|
|
Assert.AreEqual(6.0, extents.forwardExtent, 1e-6);
|
|
Assert.AreEqual(2.0, extents.sideExtent, 1e-6);
|
|
Assert.AreEqual(4.0, extents.upExtent, 1e-6);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void YUp_HostY90_ShouldKeepResolvedRailUpExtentAndSwapForwardSide()
|
|
{
|
|
Vector3 referenceAxisX = new Vector3(-1.0f, 0.0f, 0.0f);
|
|
Vector3 referenceAxisY = new Vector3(0.0f, 1.0f, 0.0f);
|
|
Vector3 referenceAxisZ = new Vector3(0.0f, 0.0f, -1.0f);
|
|
Vector3 desiredForward = Vector3.Normalize(new Vector3(-0.8987f, 0.0f, 0.4386f));
|
|
Quaternion baseline = Quaternion.Identity;
|
|
var adapter = new HostCoordinateAdapter(CoordinateSystemType.YUp);
|
|
Quaternion final = adapter.ComposeHostQuaternion(
|
|
baseline,
|
|
new LocalEulerRotationCorrection(0.0, 90.0, 0.0));
|
|
|
|
bool ok = RealObjectRailExtentResolver.TryResolveProjectedSemanticExtents(
|
|
referenceAxisX,
|
|
referenceAxisY,
|
|
referenceAxisZ,
|
|
desiredForward,
|
|
CoordinateSystemType.YUp,
|
|
forwardSize: 6.0,
|
|
sideSize: 2.0,
|
|
upSize: 4.0,
|
|
baseline,
|
|
final,
|
|
out _,
|
|
out var extents);
|
|
|
|
Assert.IsTrue(ok);
|
|
Assert.AreEqual(2.0, extents.forwardExtent, 1e-6);
|
|
Assert.AreEqual(6.0, extents.sideExtent, 1e-6);
|
|
Assert.AreEqual(4.0, extents.upExtent, 1e-6);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void YUp_DualAxisCorrection_WithRailBaseline_ShouldProjectAgainstFinalRailPose()
|
|
{
|
|
Vector3 referenceAxisX = new Vector3(-1.0f, 0.0f, 0.0f);
|
|
Vector3 referenceAxisY = new Vector3(0.0f, 1.0f, 0.0f);
|
|
Vector3 referenceAxisZ = new Vector3(0.0f, 0.0f, -1.0f);
|
|
Vector3 desiredForward = Vector3.Normalize(new Vector3(-0.8987f, 0.0f, 0.4386f));
|
|
|
|
Quaternion baseline = Quaternion.Normalize(Quaternion.CreateFromRotationMatrix(new Matrix4x4(
|
|
0.9900f, -0.1403f, -0.0161f, 0f,
|
|
0.1403f, 0.9901f, -0.0023f, 0f,
|
|
0.0163f, 0.0000f, 0.9999f, 0f,
|
|
0f, 0f, 0f, 1f)));
|
|
|
|
var adapter = new HostCoordinateAdapter(CoordinateSystemType.YUp);
|
|
Quaternion final = adapter.ComposeHostQuaternion(
|
|
baseline,
|
|
new LocalEulerRotationCorrection(0.0, 90.0, 90.0));
|
|
|
|
bool ok = RealObjectRailExtentResolver.TryResolveProjectedSemanticExtents(
|
|
referenceAxisX,
|
|
referenceAxisY,
|
|
referenceAxisZ,
|
|
desiredForward,
|
|
CoordinateSystemType.YUp,
|
|
forwardSize: 6.0,
|
|
sideSize: 2.0,
|
|
upSize: 4.0,
|
|
baseline,
|
|
final,
|
|
out ModelAxisConvention convention,
|
|
out var extents);
|
|
|
|
Assert.IsTrue(ok);
|
|
Assert.AreEqual(LocalAxisDirection.PositiveX, convention.ForwardAxis);
|
|
Assert.AreEqual(LocalAxisDirection.PositiveY, convention.UpAxis);
|
|
|
|
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 targetForward = Vector3.Normalize(Vector3.Transform(convention.ForwardUnitVector, baseline));
|
|
Vector3 targetUp = Vector3.Normalize(Vector3.Transform(convention.UpUnitVector, baseline));
|
|
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, "双轴旋转后,法向尺寸不应仍停留在单轴结果。");
|
|
}
|
|
|
|
private static double ProjectExtent(
|
|
Vector3 localSize,
|
|
Vector3 rotatedLocalX,
|
|
Vector3 rotatedLocalY,
|
|
Vector3 rotatedLocalZ,
|
|
Vector3 targetAxis)
|
|
{
|
|
return Math.Abs(Vector3.Dot(rotatedLocalX, targetAxis)) * localSize.X +
|
|
Math.Abs(Vector3.Dot(rotatedLocalY, targetAxis)) * localSize.Y +
|
|
Math.Abs(Vector3.Dot(rotatedLocalZ, targetAxis)) * localSize.Z;
|
|
}
|
|
}
|
|
}
|