diff --git a/PointCloudWeb.Server/PointCloudWeb.Server.Tests/PointCloudWeb.Server.Tests.csproj b/PointCloudWeb.Server/PointCloudWeb.Server.Tests/PointCloudWeb.Server.Tests.csproj
new file mode 100644
index 0000000..7638eda
--- /dev/null
+++ b/PointCloudWeb.Server/PointCloudWeb.Server.Tests/PointCloudWeb.Server.Tests.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net5.0
+
+ false
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
diff --git a/PointCloudWeb.Server/PointCloudWeb.Server.Tests/Services/ScanConverterServiceTest.cs b/PointCloudWeb.Server/PointCloudWeb.Server.Tests/Services/ScanConverterServiceTest.cs
new file mode 100644
index 0000000..24b975e
--- /dev/null
+++ b/PointCloudWeb.Server/PointCloudWeb.Server.Tests/Services/ScanConverterServiceTest.cs
@@ -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
+ );
+ }
+ }
+}
diff --git a/PointCloudWeb.Server/PointCloudWeb.Server.sln b/PointCloudWeb.Server/PointCloudWeb.Server.sln
index ce42869..b0906d9 100644
--- a/PointCloudWeb.Server/PointCloudWeb.Server.sln
+++ b/PointCloudWeb.Server/PointCloudWeb.Server.sln
@@ -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
diff --git a/PointCloudWeb.Server/PointCloudWeb.Server/Models/PointCloud.cs b/PointCloudWeb.Server/PointCloudWeb.Server/Models/PointCloud.cs
index 0c80d77..59b970d 100644
--- a/PointCloudWeb.Server/PointCloudWeb.Server/Models/PointCloud.cs
+++ b/PointCloudWeb.Server/PointCloudWeb.Server/Models/PointCloud.cs
@@ -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));
}
}
-
}
\ No newline at end of file
diff --git a/PointCloudWeb.Server/PointCloudWeb.Server/Models/ScanData.cs b/PointCloudWeb.Server/PointCloudWeb.Server/Models/ScanData.cs
index 28b2644..eeb713e 100644
--- a/PointCloudWeb.Server/PointCloudWeb.Server/Models/ScanData.cs
+++ b/PointCloudWeb.Server/PointCloudWeb.Server/Models/ScanData.cs
@@ -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 List { get; set; }
+ public IList ScanPoints { get; set; }
}
}
\ No newline at end of file
diff --git a/PointCloudWeb.Server/PointCloudWeb.Server/Services/ScanConverterService.cs b/PointCloudWeb.Server/PointCloudWeb.Server/Services/ScanConverterService.cs
index 5b7ba9e..57358e7 100644
--- a/PointCloudWeb.Server/PointCloudWeb.Server/Services/ScanConverterService.cs
+++ b/PointCloudWeb.Server/PointCloudWeb.Server/Services/ScanConverterService.cs
@@ -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)
+ );
}
}
}
\ No newline at end of file
diff --git a/PointCloudWeb.Server/PointCloudWeb.Server/Services/ScanDataService.cs b/PointCloudWeb.Server/PointCloudWeb.Server/Services/ScanDataService.cs
index 92b887c..b94f4e4 100644
--- a/PointCloudWeb.Server/PointCloudWeb.Server/Services/ScanDataService.cs
+++ b/PointCloudWeb.Server/PointCloudWeb.Server/Services/ScanDataService.cs
@@ -24,7 +24,7 @@ namespace PointCloudWeb.Server.Services
{
var list = new List();
- foreach (var scan in scanData.List)
+ foreach (var scan in scanData.ScanPoints)
{
list.Add(_scanConverterService.Transform(scan));
}