示例#1
0
        void CalcConvexHull_Executed(object sender, EventArgs e)
        {
            UpdateStatusLabel("calculating convex hull...");

            //clear old lines
            var oldHull = canvas.Geometries.OfType <Segment2d> ().ToArray();

            foreach (var l in oldHull)
            {
                canvas.Geometries.Remove(l);
            }

            //get all points
            var points = canvas.Geometries.OfType <Vector2d> ().ToArray();

            watch.Start();
            var convexHull = GeoAlgos.MonotoneChainConvexHull(points);

            watch.Stop();

            //draw convex hull
            for (var i = 0; i < convexHull.Length; i++)
            {
                var next = (i + 1) % convexHull.Length;
                canvas.Geometries.Add(new Segment2d(convexHull [i], convexHull [next]));
            }

            UpdateUi(watch.Duration.TotalSeconds + " ms");
        }
示例#2
0
        /// <summary>
        /// Calculates the minimum bounding box.
        /// </summary>
        /// <param name="points">Bounding Box.</param>
        public static Polygon2d Calculate(Vector2d[] points)
        {
            //calculate the convex hull
            var hullPoints = GeoAlgos.MonotoneChainConvexHull(points);

            //check if no bounding box available
            if (hullPoints.Length <= 1)
            {
                return new Polygon2d {
                           Points = hullPoints.ToList()
                }
            }
            ;

            Rectangle2d minBox   = null;
            var         minAngle = 0d;

            //foreach edge of the convex hull
            for (var i = 0; i < hullPoints.Length; i++)
            {
                var nextIndex = i + 1;

                var current = hullPoints [i];
                var next    = hullPoints [nextIndex % hullPoints.Length];

                var segment = new Segment2d(current, next);

                //min / max points
                var top    = double.MinValue;
                var bottom = double.MaxValue;
                var left   = double.MaxValue;
                var right  = double.MinValue;

                //get angle of segment to x axis
                var angle = AngleToXAxis(segment);

                //rotate every point and get min and max values for each direction
                foreach (var p in hullPoints)
                {
                    var rotatedPoint = RotateToXAxis(p, angle);

                    top    = Math.Max(top, rotatedPoint.Y);
                    bottom = Math.Min(bottom, rotatedPoint.Y);

                    left  = Math.Min(left, rotatedPoint.X);
                    right = Math.Max(right, rotatedPoint.X);
                }

                //create axis aligned bounding box
                var box = new Rectangle2d(new Vector2d(left, bottom), new Vector2d(right, top));

                if (minBox == null || minBox.Area() > box.Area())
                {
                    minBox   = box;
                    minAngle = angle;
                }
            }

            //rotate axis algined box back
            var minimalBoundingBox = new Polygon2d
            {
                Points = minBox.Points.Select(p => RotateToXAxis(p, -minAngle)).ToList()
            };

            return(minimalBoundingBox);
        }