private void DoSmoothing(long maxDist, int interations) { bool closedPath = true; var path = this.Children.OfType <IPathObject>().FirstOrDefault(); if (path == null) { // clear our existing data VertexSource = new VertexStorage(); return; } var sourceVertices = path.VertexSource; var inputPolygons = sourceVertices.CreatePolygons(); Polygons outputPolygons = new Polygons(); foreach (Polygon inputPolygon in inputPolygons) { int numVerts = inputPolygon.Count; long maxDistSquared = maxDist * maxDist; var smoothedPositions = new Polygon(numVerts); foreach (IntPoint inputPosition in inputPolygon) { smoothedPositions.Add(inputPosition); } for (int iteration = 0; iteration < interations; iteration++) { var positionsThisPass = new Polygon(numVerts); foreach (IntPoint inputPosition in smoothedPositions) { positionsThisPass.Add(inputPosition); } int startIndex = closedPath ? 0 : 1; int endIndex = closedPath ? numVerts : numVerts - 1; for (int i = startIndex; i < endIndex; i++) { // wrap back to the previous index IntPoint prev = positionsThisPass[(i + numVerts - 1) % numVerts]; IntPoint cur = positionsThisPass[i]; IntPoint next = positionsThisPass[(i + 1) % numVerts]; IntPoint newPos = (prev + cur + next) / 3; IntPoint delta = newPos - inputPolygon[i]; if (delta.LengthSquared() > maxDistSquared) { delta = delta.GetLength(maxDist); newPos = inputPolygon[i] + delta; } smoothedPositions[i] = newPos; } } outputPolygons.Add(smoothedPositions); outputPolygons = ClipperLib.Clipper.CleanPolygons(outputPolygons, Math.Max(maxDist / 10, 1.415)); } VertexSource = outputPolygons.CreateVertexStorage(); }