Esempio n. 1
0
 public Arc(VoronoiCell cell, Point p, Arc prev, Arc next)
     : this(cell, p, prev)
 {
     this.next = next;
 }
Esempio n. 2
0
 public Arc(VoronoiCell cell, Point p, Arc prev)
     : this(cell, p)
 {
     this.prev = prev;
 }
Esempio n. 3
0
        void FinishEdges()
        {
            // Advance the sweep line so no parabolas can cross the bounding box.
            double l = X1 + (X1 - X0) + (Y1 - Y0);

            // Extend each remaining segment to the new parabola intersections.
            for (Arc i = root; i.next != null; i = i.next)
            {
                if (i.s1 != null)
                {
                    i.s1.Finish(Intersection(i.p, i.next.p, l * 2));
                }
            }

            // Crop output
            for (int c = 0; c < cells.Length; c++)
            {
                VoronoiCell cell    = cells [c];
                bool        cropped = false;
                // Crop segments if needed
                for (int k = 0; k < cell.segments.Count; k++)
                {
                    Segment s = cell.segments [k];
                    // is the segment completely outside?
                    if (!s.done || (s.start.x < X0 && s.end.x < X0) || (s.start.y < Y0 && s.end.y < Y0) || (s.start.x > X1 && s.end.x > X1) || (s.start.y > Y1 && s.end.y > Y1) ||
                        Point.EqualsBoth(s.start, s.end))
                    {
                        s.deleted = true;
                        continue;
                    }

                    // is any endpoint outside of the canvas?
                    bool p1inside = PointInsideRect(s.start);
                    if (!p1inside)
                    {
                        s.start = CropPoint(s.start, s, cell);
                        cropped = true;
                    }
                    bool p2inside = PointInsideRect(s.end);
                    if (!p2inside)
                    {
                        s.end   = CropPoint(s.end, s, cell);
                        cropped = true;
                    }
                }

                if (cropped)
                {
                    // join borders with 2 points
                    if (cell.top.Count > 1)
                    {
                        cell.segments.Add(new Segment(cell.top [0], cell.top [1], true));
                    }
                    if (cell.bottom.Count > 1)
                    {
                        cell.segments.Add(new Segment(cell.bottom [0], cell.bottom [1], true));
                    }
                    if (cell.left.Count > 1)
                    {
                        cell.segments.Add(new Segment(cell.left [0], cell.left [1], true));
                    }
                    if (cell.right.Count > 1)
                    {
                        cell.segments.Add(new Segment(cell.right [0], cell.right [1], true));
                    }
                }
            }

            // 2nd step - snap to nearest corners
            Point[] corners = new Point[4];
            corners [0] = new Point(X0, Y0);
            corners [1] = new Point(X0, Y1);
            corners [2] = new Point(X1, Y0);
            corners [3] = new Point(X1, Y1);
            Point np;

            for (int cornerIndex = 0; cornerIndex < corners.Length; cornerIndex++)
            {
                Point corner = corners [cornerIndex];
                // Get the nearest point of the segments
                VoronoiCell nearestCell = GetNearestCellFrom(corner);
                // this territory is the nearest to the corner so now we can snap the nearest segment safely
                if (GetNearestSegmentPointToCorner(corner, nearestCell.segments, true, out np))
                {
                    nearestCell.segments.Add(new Segment(np, corner, true));
                }
                if (GetNearestSegmentPointToCorner(corner, nearestCell.segments, false, out np))
                {
                    nearestCell.segments.Add(new Segment(np, corner, true));
                }
            }
        }
Esempio n. 4
0
 public Arc(VoronoiCell cell, Point p)
 {
     this.p = p;
     this.cell = cell;
 }
Esempio n. 5
0
        public void AssignData(Point[] centers)
        {
            if (this.cells == null || this.cells.Length != centers.Length)
            {
                this.cells = new VoronoiCell[centers.Length];
            }
            for (int k = 0; k < cells.Length; k++)
            {
                cells [k] = new VoronoiCell(centers [k]);
            }

            if (eventQueue == null)
            {
                eventQueue = new List <Event> (cells.Length);
            }
            else
            {
                eventQueue.Clear();
            }
            root          = null;
            eventQueueTop = 0;

            if (hit == null)
            {
                hit = new Dictionary <Point, bool> (cells.Length);
            }
            else
            {
                hit.Clear();
            }
            for (int k = 0; k < cells.Length; k++)
            {
                Point p = cells [k].center;
                // Checks that p is not near than PRECISION from other point
                while (hit.ContainsKey(p))
                {
                    if (p.x > 0)
                    {
                        p.x -= Point.PRECISION * 2.0f;
                    }
                    else
                    {
                        p.x += Point.PRECISION * 2.0f;
                    }
                }
                hit.Add(p, true);
                Event siteEvent = new Event(EVENT_TYPE.SiteEvent);
                siteEvent.p    = p;
                siteEvent.x    = p.x;
                siteEvent.cell = cells [k];
                eventQueue.Add(siteEvent);
            }

            eventQueue.Sort((Event e1, Event e2) => {
                if (e1.x < e2.x - Point.PRECISION)
                {
                    return(-1);
                }
                else if (e1.x > e2.x + Point.PRECISION)
                {
                    return(1);
                }
                else if (e1.p.y < e2.p.y - Point.PRECISION)
                {
                    return(-1);
                }
                else if (e1.p.y > e2.p.y + Point.PRECISION)
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            });
        }