add test for ScanConverterService
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="3.0.2">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PointCloudWeb.Server\PointCloudWeb.Server.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,72 @@
|
||||
using PointCloudWeb.Server.Models;
|
||||
using PointCloudWeb.Server.Services;
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace PointCloudWeb.Server.Tests.Services
|
||||
{
|
||||
public class ScanConverterServiceTest
|
||||
{
|
||||
|
||||
[Theory]
|
||||
[InlineData(1, 1, 1)]
|
||||
//[InlineData(-1, 1, 1)]
|
||||
//[InlineData(1, -1, 1)]
|
||||
//[InlineData(1, 1, -1)]
|
||||
//[InlineData(-1, -1, 1)]
|
||||
//[InlineData(-1, 1, -1)]
|
||||
//[InlineData(1, -1, -1)]
|
||||
|
||||
|
||||
//[InlineData(10, 15, 32)]
|
||||
//[InlineData(5, 12, 7)]
|
||||
//[InlineData(-5, 12, 7)]
|
||||
//[InlineData(5, -12, 7)]
|
||||
//[InlineData(5, 12, -7)]
|
||||
//[InlineData(-5, -12, 7)]
|
||||
//[InlineData(-5, 12, -7)]
|
||||
//[InlineData(-5, -12, -7)]
|
||||
//[InlineData(-22, 13, 11)]
|
||||
public static void ScanConverterTest(int x, int y, int z)
|
||||
{
|
||||
var scan = new ScanDataPoint
|
||||
{
|
||||
RAX = 45,//(Math.Acos(y / Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2) + Math.Pow(z, 2))) * 180 / Math.PI),
|
||||
RAY = 45,//(Math.Acos(z / Math.Sqrt(Math.Pow(z, 2) + Math.Pow(x, 2))) * 180 / Math.PI),
|
||||
//RAY = 360 - (Math.Acos(z / Math.Sqrt(Math.Pow(z, 2) + Math.Pow(x, 2))) * 180 / Math.PI),
|
||||
//RAY = 180 - (Math.Acos(z / Math.Sqrt(Math.Pow(z, 2) + Math.Pow(x, 2))) * 180 / Math.PI),
|
||||
DistanceMM = (float)Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2) + Math.Pow(z, 2))
|
||||
};
|
||||
|
||||
//if (scan.RAX >= 0 && scan.RAX < 90)
|
||||
// scan.RAY = 360 - scan.RAY;
|
||||
//else if (scan.RAX >= 90 && scan.RAX < 180)
|
||||
// scan.RAY = 180 - scan.RAY;
|
||||
|
||||
//if (scan.RAX < 270 && scan.RAY >= 270 && scan.RAY < 360)
|
||||
// scan.RAX = 360 - scan.RAX;
|
||||
//else if (angle >= 180 && angle < 270)
|
||||
//{
|
||||
// sin *= -1;
|
||||
// cos *= -1;
|
||||
//}
|
||||
//else if (angle >= 270 && angle < 360)
|
||||
//{
|
||||
// sin *= -1;
|
||||
//}
|
||||
|
||||
var expected = new Point(x, y, z);
|
||||
|
||||
var service = new ScanConverterService();
|
||||
var point = service.Transform(scan);
|
||||
//Assert.Equal(expected, point);
|
||||
Assert.True(
|
||||
point.X >= expected.X - 1 && point.X <= expected.X + 1
|
||||
&& point.Y >= expected.Y - 1 && point.Y <= expected.Y + 1
|
||||
&& point.Z >= expected.Z - 1 && point.Z <= expected.Z + 1,
|
||||
"expected: " + expected.ToString() + " \nactual: " + point.ToString() +
|
||||
"\nAX: " + scan.RAX + "\n AY: " + scan.RAY
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.31410.357
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PointCloudWeb.Server", "PointCloudWeb.Server\PointCloudWeb.Server.csproj", "{BD246537-F063-4A5A-8957-AF25E021132D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PointCloudWeb.Server.Tests", "PointCloudWeb.Server.Tests\PointCloudWeb.Server.Tests.csproj", "{A2493168-0373-460F-8F1D-48F62ED804BA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -15,6 +17,10 @@ Global
|
||||
{BD246537-F063-4A5A-8957-AF25E021132D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BD246537-F063-4A5A-8957-AF25E021132D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BD246537-F063-4A5A-8957-AF25E021132D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A2493168-0373-460F-8F1D-48F62ED804BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A2493168-0373-460F-8F1D-48F62ED804BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A2493168-0373-460F-8F1D-48F62ED804BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A2493168-0373-460F-8F1D-48F62ED804BA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -6,21 +6,33 @@ namespace PointCloudWeb.Server.Models
|
||||
{
|
||||
public class Point
|
||||
{
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Z { get; set; }
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public int Z { get; set; }
|
||||
|
||||
|
||||
public Point() : this(0, 0, 0) { }
|
||||
public Point(double x, double y, double z)
|
||||
public Point(int x, int y, int z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if ((obj == null) || !GetType().Equals(obj.GetType()))
|
||||
return false;
|
||||
else
|
||||
{
|
||||
Point p = (Point)obj;
|
||||
return (X == p.X) && (Y == p.Y) && (Z == p.Z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string ToString() => (X.ToString() + " " + Y.ToString() + " " + Z.ToString());
|
||||
public override int GetHashCode() => HashCode.Combine(X, Y, Z);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,5 +81,4 @@ namespace PointCloudWeb.Server.Models
|
||||
Remove(GetById(id));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,16 +6,29 @@ namespace PointCloudWeb.Server.Models
|
||||
{
|
||||
public class ScanDataPoint
|
||||
{
|
||||
//RotationAngle on {Y,Z,X} Axis
|
||||
public double RAY { get; set; }
|
||||
public double RAZ { get; set; }
|
||||
//RotationAngle on {X, Y} Axis
|
||||
public double RAX { get; set; }
|
||||
public double DistanceMM { get; set; }
|
||||
public double RAY { get; set; }
|
||||
public float DistanceMM { get; set; }
|
||||
|
||||
public ScanDataPoint()
|
||||
{
|
||||
RAY = 0;
|
||||
RAX = 0;
|
||||
DistanceMM = 0;
|
||||
}
|
||||
|
||||
public ScanDataPoint(double rax, double ray, float distanceMM) : this()
|
||||
{
|
||||
RAX = rax;
|
||||
RAY = ray;
|
||||
DistanceMM = distanceMM;
|
||||
}
|
||||
}
|
||||
|
||||
public class ScanDataList
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public IList<ScanDataPoint> List { get; set; }
|
||||
public IList<ScanDataPoint> ScanPoints { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,32 @@ namespace PointCloudWeb.Server.Services
|
||||
{
|
||||
private enum RotationAxis { X, Y, Z };
|
||||
|
||||
private Matrix4x4 GetTransformationMatrix(ScanDataPoint scan, RotationAxis type)
|
||||
private static void CorrectQuadrants(double angle, ref float sin, ref float cos)
|
||||
{
|
||||
var angle = type switch
|
||||
if (angle < 0 || angle >= 360)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
if (angle > 90 && angle < 180)
|
||||
{
|
||||
RotationAxis.X => scan.RAX,
|
||||
RotationAxis.Y => scan.RAY,
|
||||
RotationAxis.Z => scan.RAZ,
|
||||
cos *= -1;
|
||||
}
|
||||
else if (angle >= 180 && angle < 270)
|
||||
{
|
||||
sin *= -1;
|
||||
cos *= -1;
|
||||
}
|
||||
else if (angle >= 270 && angle < 360)
|
||||
{
|
||||
sin *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static Matrix4x4 GetTransformationMatrix(ScanDataPoint scan, RotationAxis type)
|
||||
{
|
||||
double angle = type switch
|
||||
{
|
||||
RotationAxis.X => scan.RAX,//360 - 90 + scan.RAX,
|
||||
RotationAxis.Y => -scan.RAY,//360 - scan.RAY,
|
||||
RotationAxis.Z => 0,//360 - scan.RAY,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
|
||||
@@ -26,14 +45,22 @@ namespace PointCloudWeb.Server.Services
|
||||
0, 0, 0, 1
|
||||
);
|
||||
|
||||
var sin = (float)Math.Sin(angle);
|
||||
var cos = (float)Math.Cos(angle);
|
||||
angle %= 360;
|
||||
if (angle < 0)
|
||||
angle += 360;
|
||||
|
||||
var angleInR = angle * (Math.PI / 180.0);
|
||||
|
||||
var sin = (float)Math.Sin(angleInR);
|
||||
var cos = (float)Math.Cos(angleInR);
|
||||
|
||||
//CorrectQuadrants(angle, ref sin, ref cos);
|
||||
|
||||
return type switch
|
||||
{
|
||||
RotationAxis.X => new Matrix4x4(
|
||||
1, 0, 0, 0,
|
||||
0, sin, -sin, 0,
|
||||
0, cos, -sin, 0,
|
||||
0, sin, cos, 0,
|
||||
0, 0, 0, 1
|
||||
),
|
||||
@@ -53,14 +80,26 @@ namespace PointCloudWeb.Server.Services
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Point Transform(ScanDataPoint scan)
|
||||
{
|
||||
Vector3 v = new Vector3(0, 0, (int)scan.DistanceMM);
|
||||
Vector3.Transform(v, GetTransformationMatrix(scan, RotationAxis.X));
|
||||
Vector3.Transform(v, GetTransformationMatrix(scan, RotationAxis.Z));
|
||||
Vector3.Transform(v, GetTransformationMatrix(scan, RotationAxis.Y));
|
||||
Vector3 v = new Vector3(0, 0, 0);
|
||||
|
||||
return new Point(v.X, v.Y, v.Z);
|
||||
v.Z = scan.DistanceMM;
|
||||
|
||||
var matrixX = GetTransformationMatrix(scan, RotationAxis.X);
|
||||
var matrixY = GetTransformationMatrix(scan, RotationAxis.Y);
|
||||
var matrixZ = GetTransformationMatrix(scan, RotationAxis.Z);
|
||||
|
||||
v = Vector3.Transform(v, matrixX);
|
||||
v = Vector3.Transform(v, matrixY);
|
||||
v = Vector3.Transform(v, matrixZ);
|
||||
|
||||
return new Point(
|
||||
(int)Math.Round(v.X, 0, MidpointRounding.AwayFromZero),
|
||||
(int)Math.Round(v.Y, 0, MidpointRounding.AwayFromZero),
|
||||
(int)Math.Round(v.Z, 0, MidpointRounding.AwayFromZero)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ namespace PointCloudWeb.Server.Services
|
||||
{
|
||||
var list = new List<Point>();
|
||||
|
||||
foreach (var scan in scanData.List)
|
||||
foreach (var scan in scanData.ScanPoints)
|
||||
{
|
||||
list.Add(_scanConverterService.Transform(scan));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user