Пример #1
0
		/// <param name="t">Opposite triangle</param>
		/// <param name="p">The point in t that isn't shared between the triangles</param>
		public TriangulationPoint OppositePoint( DelaunayTriangle t, TriangulationPoint p )
		{
			Debug.Assert( t != this, "self-pointer error" );
			return PointCW( t.PointCW( p ) );
		}
Пример #2
0
		public void MarkEdge( DelaunayTriangle triangle )
		{
			for( int i = 0; i < 3; i++ )
				if( edgeIsConstrained[i] )
				{
					triangle.MarkConstrainedEdge( points[( i + 1 ) % 3], points[( i + 2 ) % 3] );
				}
		}
Пример #3
0
		/// <summary>
		/// Exhaustive search to update neighbor pointers
		/// </summary>
		public void MarkNeighbor( DelaunayTriangle t )
		{
			if( t.Contains( points[1], points[2] ) )
			{
				neighbors[0] = t;
				t.MarkNeighbor( points[1], points[2], this );
			}
			else if( t.Contains( points[0], points[2] ) )
			{
				neighbors[1] = t;
				t.MarkNeighbor( points[0], points[2], this );
			}
			else if( t.Contains( points[0], points[1] ) )
			{
				neighbors[2] = t;
				t.MarkNeighbor( points[0], points[1], this );
			}
			else
			{
				Debug.WriteLine( "markNeighbor failed" );
			}
		}
Пример #4
0
		public void ClearNeighbor( DelaunayTriangle triangle )
		{
			if( neighbors[0] == triangle )
			{
				neighbors[0] = null;
			}
			else if( neighbors[1] == triangle )
			{
				neighbors[1] = null;
			}
			else
			{
				neighbors[2] = null;
			}
		}
Пример #5
0
		public void AddTriangle( DelaunayTriangle t )
		{
			_triangles.Add( t );
		}
Пример #6
0
		/// <summary>
		/// Update neighbor pointers
		/// </summary>
		/// <param name="p1">Point 1 of the shared edge</param>
		/// <param name="p2">Point 2 of the shared edge</param>
		/// <param name="t">This triangle's new neighbor</param>
		private void MarkNeighbor( TriangulationPoint p1, TriangulationPoint p2, DelaunayTriangle t )
		{
			if( ( p1 == points[2] && p2 == points[1] ) || ( p1 == points[1] && p2 == points[2] ) )
			{
				neighbors[0] = t;
			}
			else if( ( p1 == points[0] && p2 == points[2] ) || ( p1 == points[2] && p2 == points[0] ) )
			{
				neighbors[1] = t;
			}
			else if( ( p1 == points[0] && p2 == points[1] ) || ( p1 == points[1] && p2 == points[0] ) )
			{
				neighbors[2] = t;
			}
			else
			{
				Debug.WriteLine( "Neighbor error, please report!" );
				// throw new Exception("Neighbor error, please report!");
			}
		}
Пример #7
0
 /// <summary>
 /// oppposite point
 /// </summary>
 /// <param name="t">Opposite triangle</param>
 /// <param name="p">The point in t that isn't shared between the triangles</param>
 public TriangulationPoint OppositePoint(DelaunayTriangle t, TriangulationPoint p)
 {
     Debug.Assert(t != this, "self-pointer error");
     return(PointCW(t.PointCW(p)));
 }
Пример #8
0
        /// <summary>
        /// Rotates a triangle pair one vertex CW
        ///       n2                    n2
        ///  P +-----+             P +-----+
        ///    | t  /|               |\  t |
        ///    |   / |               | \   |
        ///  n1|  /  |n3           n1|  \  |n3
        ///    | /   |    after CW   |   \ |
        ///    |/ oT |               | oT \|
        ///    +-----+ oP            +-----+
        ///       n4                    n4
        /// </summary>
        private static void RotateTrianglePair(DelaunayTriangle t, PolygonPoint p, DelaunayTriangle ot,
                                               PolygonPoint op)
        {
            DelaunayTriangle n1, n2, n3, n4;

            n1 = t.NeighborCCWFrom(p);
            n2 = t.NeighborCWFrom(p);
            n3 = ot.NeighborCCWFrom(op);
            n4 = ot.NeighborCWFrom(op);

            bool ce1, ce2, ce3, ce4;

            ce1 = t.GetConstrainedEdgeCCW(p);
            ce2 = t.GetConstrainedEdgeCW(p);
            ce3 = ot.GetConstrainedEdgeCCW(op);
            ce4 = ot.GetConstrainedEdgeCW(op);

            bool de1, de2, de3, de4;

            de1 = t.GetDelaunayEdgeCCW(p);
            de2 = t.GetDelaunayEdgeCW(p);
            de3 = ot.GetDelaunayEdgeCCW(op);
            de4 = ot.GetDelaunayEdgeCW(op);

            t.Legalize(p, op);
            ot.Legalize(op, p);

            // Remap dEdge
            ot.SetDelaunayEdgeCCW(p, de1);
            t.SetDelaunayEdgeCW(p, de2);
            t.SetDelaunayEdgeCCW(op, de3);
            ot.SetDelaunayEdgeCW(op, de4);

            // Remap cEdge
            ot.SetConstrainedEdgeCCW(p, ce1);
            t.SetConstrainedEdgeCW(p, ce2);
            t.SetConstrainedEdgeCCW(op, ce3);
            ot.SetConstrainedEdgeCW(op, ce4);

            // Remap neighbors
            // XXX: might optimize the markNeighbor by keeping track of
            //      what side should be assigned to what neighbor after the
            //      rotation. Now mark neighbor does lots of testing to find
            //      the right side.
            t.Neighbors.Clear();
            ot.Neighbors.Clear();
            if (n1 != null)
            {
                ot.MarkNeighbor(n1);
            }
            if (n2 != null)
            {
                t.MarkNeighbor(n2);
            }
            if (n3 != null)
            {
                t.MarkNeighbor(n3);
            }
            if (n4 != null)
            {
                ot.MarkNeighbor(n4);
            }
            t.MarkNeighbor(ot);
        }
Пример #9
0
        /// <summary>
        /// Returns true if triangle was legalized
        /// </summary>
        private static bool Legalize(DTSweepContext tcx, DelaunayTriangle t)
        {
            // To legalize a triangle we start by finding if any of the three edges
            // violate the Delaunay condition
            for (int i = 0; i < 3; i++)
            {
                // TODO: fix so that cEdge is always valid when creating new triangles then we can check it here
                //       instead of below with ot
                if (t.EdgeIsDelaunay[i])
                {
                    continue;
                }

                DelaunayTriangle ot = t.Neighbors[i];
                if (ot == null)
                {
                    continue;
                }

                PolygonPoint p  = t.Points[i];
                PolygonPoint op = ot.OppositePoint(t, p);
                int          oi = ot.IndexOf(op);
                // If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
                // then we should not try to legalize
                if (ot.EdgeIsConstrained[oi] || ot.EdgeIsDelaunay[oi])
                {
                    t.EdgeIsConstrained[i] = ot.EdgeIsConstrained[oi];
                    // XXX: have no good way of setting this property when creating new triangles so lets set it here
                    continue;
                }

                if (!TriangulationUtil.SmartIncircle(p, t.PointCCWFrom(p), t.PointCWFrom(p), op))
                {
                    continue;
                }

                // Lets mark this shared edge as Delaunay
                t.EdgeIsDelaunay[i]   = true;
                ot.EdgeIsDelaunay[oi] = true;

                // Lets rotate shared edge one vertex CW to legalize it
                RotateTrianglePair(t, p, ot, op);

                // We now got one valid Delaunay Edge shared by two triangles
                // This gives us 4 new edges to check for Delaunay

                // Make sure that triangle to node mapping is done only one time for a specific triangle
                if (!Legalize(tcx, t))
                {
                    tcx.MapTriangleToNodes(t);
                }
                if (!Legalize(tcx, ot))
                {
                    tcx.MapTriangleToNodes(ot);
                }

                // Reset the Delaunay edges, since they only are valid Delaunay edges
                // until we add a new triangle or point.
                // XXX: need to think about this. Can these edges be tried after we
                //      return to previous recursive level?
                t.EdgeIsDelaunay[i]   = false;
                ot.EdgeIsDelaunay[oi] = false;

                // If triangle have been legalized no need to check the other edges since
                // the recursive legalization will handles those so we can end here.
                return(true);
            }
            return(false);
        }
Пример #10
0
        /// <summary>
        /// After a flip we have two triangles and know that only one will still be
        /// intersecting the edge. So decide which to contiune with and legalize the other
        /// </summary>
        /// <param name="tcx"></param>
        /// <param name="o">should be the result of an TriangulationUtil.orient2d( eq, op, ep )</param>
        /// <param name="t">triangle 1</param>
        /// <param name="ot">triangle 2</param>
        /// <param name="p">a point shared by both triangles</param>
        /// <param name="op">another point shared by both triangles</param>
        /// <returns>returns the triangle still intersecting the edge</returns>
        private static DelaunayTriangle NextFlipTriangle(DTSweepContext tcx, Orientation o, DelaunayTriangle t,
                                                         DelaunayTriangle ot, PolygonPoint p,
                                                         PolygonPoint op)
        {
            int edgeIndex;

            if (o == Orientation.CCW)
            {
                // ot is not crossing edge after flip
                edgeIndex = ot.EdgeIndex(p, op);
                ot.EdgeIsDelaunay[edgeIndex] = true;
                Legalize(tcx, ot);
                ot.EdgeIsDelaunay.Clear();
                return(t);
            }
            // t is not crossing edge after flip
            edgeIndex = t.EdgeIndex(p, op);
            t.EdgeIsDelaunay[edgeIndex] = true;
            Legalize(tcx, t);
            t.EdgeIsDelaunay.Clear();
            return(ot);
        }
Пример #11
0
 /// <param name="t">Opposite triangle</param>
 /// <param name="p">The point in t that isn't shared between the triangles</param>
 public PolygonPoint OppositePoint(DelaunayTriangle t, PolygonPoint p)
 {
     Debug.Assert(t != this, "self-pointer error");
     return(PointCWFrom(t.PointCWFrom(p)));
 }