/// <summary> /// /// </summary> /// <param name="points"></param> /// <param name="threshold">Must be between 0 and 1</param> /// <returns></returns> public static IPoint[] SimplifyByAngle(IPoint[] points, double threshold) { if (points == null || points.Length == 0) { return(null); } else if (points.Length == 2) { return(points); } List <Tuple <int, double> > angles = new List <Tuple <int, double> >(); for (int i = 0; i < points.Length - 2; i++) { var angle = SpatialUtility.CalculateSemiCosineOfAngle(points[i], points[i + 1], points[i + 2]); angles.Add(new Tuple <int, double>(i + 1, angle)); } //When i.Item2 ~ 1 it means points are on a line var filter1 = angles.Where(i => i.Item2 < threshold).Select(i => i.Item1).ToList(); filter1.Insert(0, 0); filter1.Add(points.Length - 1); var output1 = filter1.Select(i => points[i]).ToArray(); return(output1); }
/// <summary> /// Additive Angle + Area Check /// </summary> /// <param name="points"></param> /// <param name="anglethreshold">Must be between 0 and 1</param> /// <returns></returns> public static IPoint[] AdditiveSimplifyByAngleArea(IPoint[] points, double angleThreshold, double areaThreshold) { if (points == null || points.Length == 0) { return(null); } else if (points.Length == 2) { return(points); } List <int> filtered = new List <int>(); filtered.Add(0); int firstIndex = 0, secondIndex = 1, thirdIndex = 2; double tempArea = 0; while (thirdIndex < points.Length) { var angle = SpatialUtility.CalculateSemiCosineOfAngle(points[firstIndex], points[secondIndex], points[thirdIndex]); var area = SpatialUtility.CalculateTriangleArea(points[firstIndex], points[secondIndex], points[thirdIndex]); tempArea += area; //if (Math.Abs(angle) < threshold) //{ if ((angle < 0 || angle < angleThreshold) || tempArea > areaThreshold) { filtered.Add(secondIndex); firstIndex = secondIndex; tempArea = 0; } secondIndex = thirdIndex; thirdIndex = thirdIndex + 1; } if (filtered.Count == 1) { filtered.Add(points.Count() / 2); } filtered.Add(points.Length - 1); var output1 = filtered.Select(i => points[i]).ToArray(); return(output1); }