Ejemplo n.º 1
0
        private void FinishLine(JCVEdge e)
        {
            if (!clipper.ClipEdge(e))
            {
                return;
            }

            // Make sure the graph edges are CCW
            int flip = TriIsCCW(e.Sites[0].center, e.Points[0], e.Points[1]) ? 0 : 1;

            for (int i = 0; i < 2; i++)
            {
                PointF[] tempPts  = new PointF[2];
                JCVSite  home     = e.Sites[i];
                JCVSite  neighbor = e.Sites[1 - i];
                tempPts[flip]     = e.Points[i];
                tempPts[1 - flip] = e.Points[1 - i];

                JCVGraphEdge ge = new JCVGraphEdge(e, home, neighbor, tempPts);
                home.edges.Add(ge);
            }
            //        // check that we didn't accidentally add a duplicate (rare), then remove it
            //        if(ge->next && ge->angle == ge->next->angle )
            //        {
            //            if(jcv_point_eq( &ge->pos[0], &ge->next->pos[0] ) && jcv_point_eq( &ge->pos[1], &ge->next->pos[1] ) )
            //            {
            //                ge->next = ge->next->next; // Throw it away, they're so few anyways
            //            }
            //      }
            //    }
        }
Ejemplo n.º 2
0
        // They're sorted CCW, so if the current->pos[1] != next->pos[0], then we have a gap
        public override bool FillGaps(JCVSite site, JCVDiagram diagram)
        {
            if (site.edges.Count == 0) //no edges, must be single cell graph
            {
                if (diagram.sites.Count != 0)
                {
                    throw new Exception("Invalid graph: edgeless site in graph");
                }

                PointF[] points = new PointF[2];
                points[0] = new PointF(boundingBox.Left, boundingBox.Top);
                points[1] = new PointF(boundingBox.Right, boundingBox.Top);

                JCVEdge edge = new JCVEdge(site, points);
                diagram.edges.Add(edge);
                JCVGraphEdge gap = new JCVGraphEdge(edge, site, null, points);
                site.edges.Add(gap);
            }

            if (site.edges.Count == 1) // one edge, assume corner gap
            {
                JCVGraphEdge current = site.edges[0];

                PointF[] points = new PointF[2];
                points[0] = current.Points[1];
                if (current.Points[1].X < boundingBox.Right && current.Points[1].Y == boundingBox.Top)
                {
                    points[1] = new PointF(boundingBox.Right, boundingBox.Top);
                }
                else if (current.Points[1].X > boundingBox.Left && current.Points[1].Y == boundingBox.Bottom)
                {
                    points[1] = new PointF(boundingBox.Left, boundingBox.Bottom);
                }
                else if (current.Points[1].Y > boundingBox.Top && current.Points[1].X == boundingBox.Left)
                {
                    points[1] = new PointF(boundingBox.Left, boundingBox.Top);
                }
                else if (current.Points[1].Y < boundingBox.Bottom && current.Points[1].X == boundingBox.Right)
                {
                    points[1] = new PointF(boundingBox.Right, boundingBox.Bottom);
                }

                JCVEdge edge = new JCVEdge(site, points);
                diagram.edges.Add(edge);
                JCVGraphEdge gap = new JCVGraphEdge(edge, site, null, points);
                site.edges.Add(gap);
            }

            int eIndex = 0;

            while (eIndex < site.edges.Count)
            {
                JCVGraphEdge current = site.edges[eIndex];
                JCVGraphEdge next    = site.edges[(eIndex + 1) % site.edges.Count];
                if (PointIsOnEdge(current.Points[1]) && current.Points[1] != next.Points[0])
                {
                    //border gap
                    if (current.Points[1].X == next.Points[0].X || current.Points[1].Y == next.Points[0].Y)
                    {
                        PointF[] points = { current.Points[1], next.Points[0] };
                        JCVEdge  edge   = new JCVEdge(site, points);
                        diagram.edges.Add(edge);
                        JCVGraphEdge gap = new JCVGraphEdge(edge, site, null, points);

                        // note: performance of repeated insertions may justify switching to linked list or SortedSet structure
                        // for processing phase; List currently used due to ease of use, and fact that it will be as fast or
                        // faster than other structures when the diagram is later used (post generation)
                        site.edges.Insert(eIndex + 1, gap);
                    }
                    else if (PointIsOnEdge(current.Points[1]) && PointIsOnEdge(next.Points[0]))
                    {
                        PointF[] points = new PointF[2];
                        points[0] = current.Points[1];
                        if (current.Points[1].X < boundingBox.Right && current.Points[1].Y == boundingBox.Top)
                        {
                            points[1] = new PointF(boundingBox.Right, boundingBox.Top);
                        }
                        else if (current.Points[1].X > boundingBox.Left && current.Points[1].Y == boundingBox.Bottom)
                        {
                            points[1] = new PointF(boundingBox.Left, boundingBox.Bottom);
                        }
                        else if (current.Points[1].Y > boundingBox.Top && current.Points[1].X == boundingBox.Left)
                        {
                            points[1] = new PointF(boundingBox.Left, boundingBox.Top);
                        }
                        else if (current.Points[1].Y < boundingBox.Bottom && current.Points[1].X == boundingBox.Right)
                        {
                            points[1] = new PointF(boundingBox.Right, boundingBox.Bottom);
                        }

                        JCVEdge edge = new JCVEdge(site, points);
                        diagram.edges.Add(edge);
                        JCVGraphEdge gap = new JCVGraphEdge(edge, site, null, points);
                        site.edges.Insert(eIndex + 1, gap);
                    }
                    else
                    {
                        //something went wrong; abort instead of looping indefinitely
                        throw new Exception("Invalid Gap state, site location " + site.center.ToString());
                    }
                }
                eIndex++;
            }

            //    current = current->next;
            //    if (current)
            //    {
            //        next = current->next;
            //        if (!next)
            //            next = site->edges;
            //    }
            //}

            ////*********** moved down from top ****************
            //jcv_graphedge* current = site->edges;
            //if (!current)
            //{
            //    // No edges, then it should be a single cell
            //    assert(allocator->numsites == 1);

            //    jcv_graphedge* gap = jcv_alloc_graphedge(allocator);
            //    gap->neighbor = 0;
            //    gap->pos[0] = clipper->min;
            //    gap->pos[1].x = clipper->max.x;
            //    gap->pos[1].y = clipper->min.y;
            //    gap->angle = jcv_calc_sort_metric(site, gap);
            //    gap->next = 0;
            //    gap->edge = jcv_create_gap_edge(allocator, site, gap);

            //    current = gap;
            //    site->edges = gap;
            //}

            //jcv_graphedge* next = current->next;
            //if (!next)
            //{
            //    // Only one edge, then we assume it's a corner gap
            //    jcv_graphedge* gap = jcv_alloc_graphedge(allocator);
            //    jcv_create_corner_edge(allocator, site, current, gap);
            //    gap->edge = jcv_create_gap_edge(allocator, site, gap);

            //    gap->next = current->next;
            //    current->next = gap;
            //    current = gap;
            //    next = site->edges;
            //}
            return(false);
        }