From 192e25f27e7cc6c710f355cd842bae4f6d657dfd Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sun, 22 Oct 2017 21:44:30 +0100 Subject: [PATCH] [server] Write initial C# implementation of the JS line simplification algorithm I implemented earlier --- Nibriboard/Nibriboard.csproj | 6 +-- Nibriboard/Utilities/LineSimplifier.cs | 53 ++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 Nibriboard/Utilities/LineSimplifier.cs diff --git a/Nibriboard/Nibriboard.csproj b/Nibriboard/Nibriboard.csproj index 9cbfa77..a4b04b4 100644 --- a/Nibriboard/Nibriboard.csproj +++ b/Nibriboard/Nibriboard.csproj @@ -119,6 +119,7 @@ + @@ -147,10 +148,7 @@ - - - - + diff --git a/Nibriboard/Utilities/LineSimplifier.cs b/Nibriboard/Utilities/LineSimplifier.cs new file mode 100644 index 0000000..ba9d5d6 --- /dev/null +++ b/Nibriboard/Utilities/LineSimplifier.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using Nibriboard.RippleSpace; + +namespace Nibriboard.Utilities +{ + public static class LineSimplifier + { + public static List SimplifyLine(List points, float minArea) + { + // This algorithm requires more than 3 points + if(points.Count < 3) + return points; + + points = new List(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 + ); + } + } +}