1
0
Fork 0
mirror of https://github.com/sbrl/Nibriboard.git synced 2018-01-10 21:33:49 +00:00

[server] Write initial C# implementation of the JS line simplification algorithm I implemented earlier

This commit is contained in:
Starbeamrainbowlabs 2017-10-22 21:44:30 +01:00
parent 45761ecb5d
commit 192e25f27e
2 changed files with 55 additions and 4 deletions

View file

@ -119,6 +119,7 @@
<Compile Include="Utilities\BinaryIO.cs" /> <Compile Include="Utilities\BinaryIO.cs" />
<Compile Include="Client\Messages\ViewportUpdateMessage.cs" /> <Compile Include="Client\Messages\ViewportUpdateMessage.cs" />
<Compile Include="NibriboardApp.cs" /> <Compile Include="NibriboardApp.cs" />
<Compile Include="Utilities\LineSimplifier.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="ClientFiles\index.html" /> <EmbeddedResource Include="ClientFiles\index.html" />
@ -147,10 +148,7 @@
<MonoDevelop> <MonoDevelop>
<Properties> <Properties>
<Policies> <Policies>
<DotNetNamingPolicy ResourceNamePolicy="FileFormatDefault" DirectoryNamespaceAssociation="PrefixedHierarchical"> <DotNetNamingPolicy ResourceNamePolicy="FileFormatDefault" DirectoryNamespaceAssociation="PrefixedHierarchical" />
<inheritsSet />
<inheritsScope />
</DotNetNamingPolicy>
</Policies> </Policies>
</Properties> </Properties>
</MonoDevelop> </MonoDevelop>

View file

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using Nibriboard.RippleSpace;
namespace Nibriboard.Utilities
{
public static class LineSimplifier
{
public static List<LocationReference> SimplifyLine(List<LocationReference> points, float minArea)
{
// This algorithm requires more than 3 points
if(points.Count < 3)
return points;
points = new List<LocationReference>(points); // Shallow clone the list
while(true)
{
float smallestArea = float.MaxValue;
int smallestAreaI = 1;
for(int i = 1; i < points.Count - 1; i++)
{
float nextArea = TriangleArea(points[i - 1], points[i], points[i + 1]);
if(nextArea < smallestArea) {
smallestArea = nextArea;
smallestAreaI = i;
}
}
if(smallestArea >= minArea || points.Count <= 3)
break;
// Remove the central point of the smallest triangle
points.RemoveAt(smallestAreaI);
}
return points;
}
public static float TriangleArea(LocationReference a, LocationReference b, LocationReference c)
{
return Math.Abs(
(
(float)a.X * (b.Y - c.Y) +
(float)b.X * (c.Y - a.Y) +
(float)c.X * (a.Y - b.Y)
) / 2f
);
}
}
}