public Polygon Cleaned(double distance = 1.415) { // distance = proximity in units/pixels below which vertices will be stripped. // Default ~= sqrt(2) so when adjacent vertices or semi-adjacent vertices have // both x & y coords within 1 unit, then the second vertex will be stripped. var pointCount = Count; if (pointCount == 0) { return(new Polygon()); } var outputPoints = new OutputPoint[pointCount]; for (var i = 0; i < pointCount; ++i) { outputPoints[i] = new OutputPoint(); } for (var i = 0; i < pointCount; ++i) { outputPoints[i].Point = this[i]; outputPoints[i].Next = outputPoints[(i + 1) % pointCount]; outputPoints[i].Next.Prev = outputPoints[i]; outputPoints[i].Index = 0; } var distSqrd = distance * distance; var op = outputPoints[0]; while (op.Index == 0 && op.Next != op.Prev) { if (GeometryHelper.PointsAreClose(op.Point, op.Prev.Point, distSqrd)) { op = ExcludeOutputPoint(op); pointCount--; } else if (GeometryHelper.PointsAreClose(op.Prev.Point, op.Next.Point, distSqrd)) { ExcludeOutputPoint(op.Next); op = ExcludeOutputPoint(op); pointCount -= 2; } else if (GeometryHelper.SlopesNearCollinear(op.Prev.Point, op.Point, op.Next.Point, distSqrd)) { op = ExcludeOutputPoint(op); pointCount--; } else { op.Index = 1; op = op.Next; } } if (pointCount < 3) { pointCount = 0; } var result = new Polygon(pointCount); for (var i = 0; i < pointCount; ++i) { result.Add(op.Point); op = op.Next; } return(result); }