Example #1
0
        void write_graph(DGraph2 graph, StreamWriter w)
        {
            string style = get_style(graph, ref DefaultDGraphStyle);

            StringBuilder b = new StringBuilder();

            foreach (int eid in graph.EdgeIndices())
            {
                Segment2d seg = graph.GetEdgeSegment(eid);
                b.Append("<line ");
                append_property("x1", seg.P0.x, b, true);
                append_property("y1", seg.P0.y, b, true);
                append_property("x2", seg.P1.x, b, true);
                append_property("y2", seg.P1.y, b, true);
                b.Append(style);
                b.Append(" />");
                b.AppendLine();
            }
            w.WriteLine(b);
        }
        /// <summary>
        /// insert edge [a,b] into the arrangement, splitting existing edges as necessary
        /// </summary>
        protected bool insert_segment(ref Vector2d a, ref Vector2d b, int gid = -1, double tol = 0)
        {
            // handle degenerate edges
            int a_idx = find_existing_vertex(a);
            int b_idx = find_existing_vertex(b);

            if (a_idx == b_idx && a_idx >= 0)
            {
                return(false);
            }

            // ok find all intersections
            List <Intersection> hits = new List <Intersection>();

            find_intersecting_edges(ref a, ref b, hits, tol);
            int N = hits.Count;

            // we are going to construct a list of <t,vertex_id> values along segment AB
            List <SegmentPoint> points = new List <SegmentPoint>();
            Segment2d           segAB  = new Segment2d(a, b);

            // insert intersections into existing segments
            for (int i = 0; i < N; ++i)
            {
                Intersection intr = hits[i];
                int          eid = intr.eid;
                double       t0 = intr.intr.Parameter0, t1 = intr.intr.Parameter1;

                // insert first point at t0
                int new_eid = -1;
                if (intr.intr.Type == IntersectionType.Point || intr.intr.Type == IntersectionType.Segment)
                {
                    Index2i new_info = split_segment_at_t(eid, t0, VertexSnapTol);
                    new_eid = new_info.b;
                    Vector2d v = Graph.GetVertex(new_info.a);
                    points.Add(new SegmentPoint()
                    {
                        t = segAB.Project(v), vid = new_info.a
                    });
                }

                // if intersection was on-segment, then we have a second point at t1
                if (intr.intr.Type == IntersectionType.Segment)
                {
                    if (new_eid == -1)
                    {
                        // did not actually split edge for t0, so we can still use eid
                        Index2i  new_info = split_segment_at_t(eid, t1, VertexSnapTol);
                        Vector2d v        = Graph.GetVertex(new_info.a);
                        points.Add(new SegmentPoint()
                        {
                            t = segAB.Project(v), vid = new_info.a
                        });
                    }
                    else
                    {
                        // find t1 was in eid, rebuild in new_eid
                        Segment2d new_seg = Graph.GetEdgeSegment(new_eid);
                        Vector2d  p1      = intr.intr.Segment1.PointAt(t1);
                        double    new_t1  = new_seg.Project(p1);
                        Util.gDevAssert(new_t1 <= Math.Abs(new_seg.Extent));

                        Index2i  new_info = split_segment_at_t(new_eid, new_t1, VertexSnapTol);
                        Vector2d v        = Graph.GetVertex(new_info.a);
                        points.Add(new SegmentPoint()
                        {
                            t = segAB.Project(v), vid = new_info.a
                        });
                    }
                }
            }

            // find or create start and end points
            if (a_idx == -1)
            {
                a_idx = find_existing_vertex(a);
            }
            if (a_idx == -1)
            {
                a_idx = Graph.AppendVertex(a);
                PointHash.InsertPointUnsafe(a_idx, a);
            }
            if (b_idx == -1)
            {
                b_idx = find_existing_vertex(b);
            }
            if (b_idx == -1)
            {
                b_idx = Graph.AppendVertex(b);
                PointHash.InsertPointUnsafe(b_idx, b);
            }

            // add start/end to points list. These may be duplicates but we will sort that out after
            points.Add(new SegmentPoint()
            {
                t = segAB.Project(a), vid = a_idx
            });
            points.Add(new SegmentPoint()
            {
                t = segAB.Project(b), vid = b_idx
            });
            // sort by t
            points.Sort((pa, pb) => { return((pa.t < pb.t) ? -1 : ((pa.t > pb.t) ? 1 : 0)); });

            // connect sequential points, as long as they aren't the same point,
            // and the segment doesn't already exist
            for (int k = 0; k < points.Count - 1; ++k)
            {
                int v0 = points[k].vid;
                int v1 = points[k + 1].vid;
                if (v0 == v1)
                {
                    continue;
                }
                if (Math.Abs(points[k].t - points[k + 1].t) < MathUtil.Epsilonf)
                {
                    System.Console.WriteLine("insert_segment: different points with same t??");
                }

                if (Graph.FindEdge(v0, v1) == DGraph2.InvalidID)
                {
                    Graph.AppendEdge(v0, v1, gid);
                }
            }

            return(true);
        }