Example #1
0
        /// <summary>
        /// Generate the voronoi diagram.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="rect"></param>
        /// <param name="clipper"></param>
        public void GenerateDiagram(ref List <PointF> points, RectangleF rect, JCVClipper userClipper)
        {
            beachlineStart = new JCVHalfEdge(null, false);
            beachlineEnd   = new JCVHalfEdge(null, false);
            clipper        = userClipper;
            priorityQueue  = new SortedSet <JCVHalfEdge>();

            beachlineStart.right = beachlineEnd;
            beachlineEnd.left    = beachlineStart;

            lastInserted = null; //maybe not needed; added for clarity
            edges        = new List <JCVEdge>();

            //create sites for each distinct point, sorted by min(y),min(x)
            sites = points.Distinct().Select((p, index) => new JCVSite(p, index)).OrderBy(s => s.Y).ThenBy(s => s.X).ToList();

            bool noRect = (rect == default);

            if (noRect)
            {
                rect.X      = sites.Min(s => s.X);
                rect.Y      = sites.Min(s => s.Y);
                rect.Width  = sites.Max(s => s.X) - rect.X;
                rect.Height = sites.Max(s => s.Y) - rect.Y;
            }

            //uses clipper to clip any points outside bounds.
            clipper.boundingBox = rect;
            sites = (List <JCVSite>)sites.Where(s => clipper.TestPoint(s.center)).ToList();

            if (noRect)
            {
                // JCash used ceil and floor to adjust the bounding box to int coords- necessary?
                // see: jcv_rect_round(&tmp_rect);
                // Will add later if needed

                //pad bounding box by 10 in all directions
                clipper.boundingBox.Inflate(10, 10);
                rect = clipper.boundingBox;
            }

            this.Bounds = rect;

            int siteIndex = 1; //sites[0] is saved for initial bottom site
            int sCount    = sites.Count;

            bool finished = false;

            while (!finished)
            {
                bool pqEmpty = (priorityQueue.Count == 0);
                bool before  = true;
                if (!pqEmpty && siteIndex < sCount)
                {
                    JCVHalfEdge he = priorityQueue.ElementAt(0);
                    PointF      p  = new PointF(he.vertex.X, he.Y);
                    before = IsPointBefore(sites[siteIndex].center, p);
                }


                if (siteIndex < sCount && (pqEmpty || before))
                {
                    SiteEvent(sites[siteIndex++]);
                }
                else if (!pqEmpty)
                {
                    CircleEvent();
                }
                else
                {
                    finished = true;
                }
            } //end while

            for (JCVHalfEdge temphe = beachlineStart.right; temphe != beachlineEnd; temphe = temphe.right)
            {
                FinishLine(temphe.Edge);
            }

            FillGaps();
        }
Example #2
0
 /// <summary>
 /// calls GenerateDiagram
 /// </summary>
 /// <param name="points"></param>
 /// <param name="rect"></param>
 /// <param name="clipper"></param>
 public JCVDiagram(ref List <PointF> points, RectangleF rect, JCVClipper clipper)
 {
     GenerateDiagram(ref points, rect, clipper);
 }