예제 #1
0
        // 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());
        }
예제 #2
0
        /// <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));
        }
예제 #3
0
        /// <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]));
예제 #4
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();
            }
        }