/// <summary>
 /// Merges the constraint data in the vertex <tt>other</tt> into this vertex.
 /// This method is called when an inserted vertex is
 /// very close to an existing vertex in the triangulation.
 /// </summary>
 /// <param name="other">the constraint vertex to merge</param>
 protected internal void Merge(ConstraintVertex other)
 {
     if (other.isOnConstraint)
     {
         isOnConstraint = true;
         constraint     = other.constraint;
     }
 }
Exemple #2
0
 private void CreateVertices(IGeometry geom)
 {
     Coordinate[] coords = geom.Coordinates;
     for (int i = 0; i < coords.Length; i++)
     {
         Vertex v = new ConstraintVertex(coords[i]);
         _constraintVertexMap.Add(coords[i], v);
     }
 }
Exemple #3
0
        private ConstraintVertex CreateVertex(Coordinate p)
        {
            ConstraintVertex v = null;

            if (_vertexFactory != null)
            {
                v = _vertexFactory.CreateVertex(p, null);
            }
            else
            {
                v = new ConstraintVertex(p);
            }
            return(v);
        }
Exemple #4
0
        /// <summary>
        /// Creates a vertex on a constraint segment
        /// </summary>
        /// <param name="p">the location of the vertex to create</param>
        /// <param name="seg">the constraint segment it lies on</param>
        /// <returns>the new constraint vertex</returns>
        private ConstraintVertex CreateVertex(Coordinate p, Segment seg)
        {
            ConstraintVertex v;

            if (_vertexFactory != null)
            {
                v = _vertexFactory.CreateVertex(p, seg);
            }
            else
            {
                v = new ConstraintVertex(p);
            }
            v.IsOnConstraint = true;
            return(v);
        }
Exemple #5
0
        private ConstraintVertex InsertSite(ConstraintVertex v)
        {
            KdNode <Vertex> kdnode = _kdt.Insert(v.Coordinate, v);

            if (!kdnode.IsRepeated)
            {
                _incDel.InsertSite(v);
            }
            else
            {
                ConstraintVertex snappedV = (ConstraintVertex)kdnode.Data;
                snappedV.Merge(v);
                return(snappedV);
                // testing
                // if ( v.isOnConstraint() && ! currV.isOnConstraint()) {
                // System.out.println(v);
                // }
            }
            return(v);
        }
Exemple #6
0
        /*
         * private List findMissingConstraints() { List missingSegs = new ArrayList();
         * for (int i = 0; i < segments.size(); i++) { Segment s = (Segment)
         * segments.get(i); QuadEdge q = subdiv.locate(s.getStart(), s.getEnd()); if
         * (q == null) missingSegs.add(s); } return missingSegs; }
         */

        private int EnforceGabriel(ICollection <Segment> segsToInsert)
        {
            List <Segment> newSegments  = new List <Segment>();
            int            splits       = 0;
            List <Segment> segsToRemove = new List <Segment>();

            /*
             * On each iteration must always scan all constraint (sub)segments, since
             * some constraints may be rebroken by Delaunay triangle flipping caused by
             * insertion of another constraint. However, this process must converge
             * eventually, with no splits remaining to find.
             */
            foreach (Segment seg in segsToInsert)
            {
                // System.out.println(seg);

                Coordinate encroachPt = FindNonGabrielPoint(seg);
                // no encroachment found - segment must already be in subdivision
                if (encroachPt == null)
                {
                    continue;
                }

                // compute split point
                _splitPt = _splitFinder.FindSplitPoint(seg, encroachPt);
                ConstraintVertex splitVertex = CreateVertex(_splitPt, seg);

                /*
                 * Check whether the inserted point still equals the split pt. This will
                 * not be the case if the split pt was too close to an existing site. If
                 * the point was snapped, the triangulation will not respect the inserted
                 * constraint - this is a failure. This can be caused by:
                 * <ul>
                 * <li>An initial site that lies very close to a constraint segment The
                 * cure for this is to remove any initial sites which are close to
                 * constraint segments in a preprocessing phase.
                 * <li>A narrow constraint angle which causing repeated splitting until
                 * the split segments are too small. The cure for this is to either choose
                 * better split points or "guard" narrow angles by cracking the segments
                 * equidistant from the corner.
                 * </ul>
                 */
                ConstraintVertex insertedVertex = InsertSite(splitVertex);
                //Debugging FObermaier
                //Console.WriteLine("inserted vertex: " + insertedVertex.ToString());

                if (!insertedVertex.Coordinate.Equals2D(_splitPt))
                {
                    Debug.WriteLine("Split pt snapped to: " + insertedVertex);
                    // throw new ConstraintEnforcementException("Split point snapped to
                    // existing point
                    // (tolerance too large or constraint interior narrow angle?)",
                    // splitPt);
                }

                // split segment and record the new halves
                Segment s1 = new Segment(seg.StartX, seg.StartY, seg.StartZ,
                                         splitVertex.X, splitVertex.Y, splitVertex.Z,
                                         seg.Data);
                Segment s2 = new Segment(splitVertex.X, splitVertex.Y, splitVertex.Z,
                                         seg.EndX, seg.EndY, seg.EndZ,
                                         seg.Data);

                //Debugging FObermaier
                //Console.WriteLine("Segment " + seg.ToString() + " splitted to \n\t" + s1.ToString() + "\n\t"+ s2.ToString());
                newSegments.Add(s1);
                newSegments.Add(s2);
                segsToRemove.Add(seg);

                splits = splits + 1;
            }
            foreach (Segment seg in segsToRemove)
            {
                segsToInsert.Remove(seg);
            }

            foreach (Segment seg in newSegments)
            {
                segsToInsert.Add(seg);
            }

            return(splits);
        }