// Return the points that make up a polygon's convex hull. // This method leaves the points list unchanged. public static List <Point> MakeConvexHull(List <Point> points) { var convexHull = new ConvexHull(points); convexHull.CalcConvexHull(ConvexHullThreadUsage.OnlyOne); return(convexHull.GetResultsAsArrayOfPoint().ToList()); }
/// <summary> /// Using algorithm from Ouellet - https://www.codeproject.com/Articles/1210225/Fast-and-improved-D-Convex-Hull-algorithm-and-its, take an IEnumerable of Point2Ds and computes the /// two dimensional convex hull, returning it as a Polygon2D object. /// </summary> /// <param name="pointList">A list of points</param> /// <param name="clockWise"> /// In which direction to return the points on the convex hull. /// If true, clockwise. Otherwise counter clockwise /// </param> /// <returns>A polygon.</returns> public static Polygon2D GetConvexHullFromPoints(IEnumerable <Point2D> pointList, bool clockWise = true) { int count = pointList.Count(); // Perform basic validation of the input point cloud for cases of less than // four points being given if (count <= 2) { throw new ArgumentException("Must have at least 3 points in the polygon to compute the convex hull"); } if (count <= 3) { return(new Polygon2D(pointList)); } var chull = new ConvexHull(pointList, false); chull.CalcConvexHull(); var hullPoints = chull.GetResultsAsArrayOfPoint(); // Order the hull points by angle to the centroid var centroid = Point2D.Centroid(hullPoints); var xAxis = new Vector2D(1, 0); var results = (from x in hullPoints select new Tuple <Angle, Point2D>(centroid.VectorTo(x).SignedAngleTo(xAxis, clockWise), x)).ToList(); results.Sort((a, b) => a.Item1.CompareTo(b.Item1)); return(new Polygon2D(from x in results select x.Item2)); }
/// <summary> /// Join two separated polygons together /// <see href="https://stackoverflow.com/questions/18619117/combine-nearby-polygons"/> /// Using a port of @brianmearns answer /// </summary> public static List <SKPoint> JoinPolygon(List <SKPoint> polygon1, List <SKPoint> polygon2) { ConvexHull convexHull = new ConvexHull(); convexHull.CalcConvexHull(new List <SKPoint>().Concat(polygon1).Concat(polygon2).ToList().AsReadOnly()); SKPoint[] points = convexHull.GetResultsAsArrayOfPoint(); Debug.Print(points.ToString()); List <SKPoint> finalPolygon = new List <SKPoint>(); finalPolygon.Add(points[0]); (List <SKPoint>, int)poly = polygon1.Contains(points[0]) ? (polygon1, FindIndex(polygon1, points[0])) : (polygon2, FindIndex(polygon2, points[0]));
public static void TestConvexHull() { var currentDoc = Application.DocumentManager.MdiActiveDocument; var editor = currentDoc.Editor; var database = currentDoc.Database; // Only select polyline and polyline 2d. ObjectId polylineId = ObjectId.Null; while (true) { var options = new PromptEntityOptions("\n选择一条曲线:"); var result = editor.GetEntity(options); if (result.Status == PromptStatus.OK) { polylineId = result.ObjectId; break; } if (result.Status == PromptStatus.Cancel) { break; } editor.WriteMessage("\n选择无效"); } if (polylineId.IsNull) { return; } using (var transaction = database.TransactionManager.StartTransaction()) { IEnumerable <Point3d> points = CurveUtils.GetDistinctVertices(polylineId, transaction); var convex = new ConvexHull <Point3d>(points, it => it.X, it => it.Y, (x, y) => new Point3d(x, y, 0), (a, b) => a == b); convex.CalcConvexHull(); var hullPoints = convex.GetResultsAsArrayOfPoint(); var polyline = new Autodesk.AutoCAD.DatabaseServices.Polyline(); for (int i = 0; i < hullPoints.Length; i++) { polyline.AddVertexAt(i, new Point2d(hullPoints[i].X, hullPoints[i].Y), 0, 1, 1); } polyline.ColorIndex = 2; var modelspaceId = SymbolUtilityServices.GetBlockModelSpaceId(database); var modelspace = transaction.GetObject(modelspaceId, OpenMode.ForWrite) as BlockTableRecord; modelspace.AppendEntity(polyline); transaction.AddNewlyCreatedDBObject(polyline, true); transaction.Commit(); } }