private double Distance(PointF p, LineF line) { var p1 = line.Point1; var p2 = line.Point2; return(Math.Abs( ((p2.Y - p1.Y) * p.X + (p1.X - p2.X) * p.Y + (p1.Y - p2.Y) * p1.X + (p2.X - p1.X) * p1.Y) / Math.Sqrt((p2.Y - p1.Y) * (p2.Y - p1.Y) + (p1.X - p2.X) * (p1.X - p2.X)) )); }
private List <PointF> CompressHelper(List <PointF> pointsList, double errorBound) { if (pointsList.Count < 2) { return(pointsList); } var result = new List <PointF>(); // 有可能是polygon if (pointsList.First().Equals(pointsList.Last())) { var r1 = CompressHelper(pointsList.GetRange(0, pointsList.Count / 2), errorBound); var r2 = CompressHelper( pointsList.GetRange(pointsList.Count / 2, pointsList.Count - pointsList.Count / 2), errorBound); result.AddRange(r1); result.AddRange(r2); return(result); } var line = new LineF(pointsList.First(), pointsList.Last()); double maxDistance = 0; int maxIndex = 0; for (int i = 1; i < pointsList.Count - 1; i++) { var distance = Distance(pointsList[i], line); if (distance > maxDistance) { maxDistance = distance; maxIndex = i; } } if (maxDistance <= errorBound) { result.Add(pointsList.First()); } else { var r1 = CompressHelper(pointsList.GetRange(0, maxIndex), errorBound); var r2 = CompressHelper(pointsList.GetRange(maxIndex + 1, pointsList.Count - maxIndex - 1), errorBound); result.AddRange(r1); result.Add(pointsList[maxIndex]); result.AddRange(r2); } return(result); }