public DelaunayTriangle(TriangulationPoint p1, TriangulationPoint p2, TriangulationPoint p3, int i1, int i2, int i3) {
			Points[0] = p1;
			Points[1] = p2;
			Points[2] = p3;

            indices = new int[] { i1, i2, i3 };
		}
 public PointOnEdgeException(string message, TriangulationPoint a, TriangulationPoint b, TriangulationPoint c)
     : base(message)
 {
     A = a;
     B = b;
     C = c;
 }
        public EdgeLine(Poly2Tri.TriangulationPoint p, Poly2Tri.TriangulationPoint q)
        {
            this.p = p;
            this.q = q;

            x0 = p.X;
            y0 = p.Y;
            x1 = q.X;
            y1 = q.Y;
            //-------------------
            if (x1 == x0)
            {
                this.SlopKind = LineSlopeKind.Vertical;
                SlopAngle     = 1;
            }
            else
            {
                SlopAngle = Math.Abs(Math.Atan2(Math.Abs(y1 - y0), Math.Abs(x1 - x0)));
                if (SlopAngle > _85degreeToRad)
                {
                    SlopKind = LineSlopeKind.Vertical;
                }
                else if (SlopAngle < _15degreeToRad)
                {
                    SlopKind = LineSlopeKind.Horizontal;
                }
                else
                {
                    SlopKind = LineSlopeKind.Other;
                }
            }
        }
    /// <summary>
    /// Creates a triangulation of the vertices given, and gives you the indices of it.
    /// </summary>
    /// <param name="aPoints">A list of points to triangulate.</param>
    /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param>
    /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param>
    /// <returns>A magical list of indices describing the triangulation!</returns>
	public  static List<int> GetIndices           (ref List<Vector2> aPoints, bool aTreatAsPath, bool aInvert, float aVertGridSpacing = 0) {
		
		Vector4 bounds = GetBounds(aPoints);
		
        if (aVertGridSpacing > 0) {
            SplitEdges(ref aPoints, aVertGridSpacing);
        }

		List<PolygonPoint> verts = new List<PolygonPoint>(aPoints.Count);
		for (int i = 0; i < aPoints.Count; i++) {
			verts.Add(new PolygonPoint( aPoints[i].x, aPoints[i].y));
		}

		Polygon poly;
		if (aInvert) {
			aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 4
			aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.w - (bounds.y - bounds.w) * 1)); // 3
			aPoints.Add(new Vector2(bounds.z + (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 2
			aPoints.Add(new Vector2(bounds.x - (bounds.z - bounds.x) * 1, bounds.y + (bounds.y - bounds.w) * 1)); // 1
			List<PolygonPoint> outer = new List<PolygonPoint>(4);
			for (int i = 0; i < 4; i++) {
				outer.Add( new PolygonPoint( aPoints[(aPoints.Count - 4) + i].x, aPoints[(aPoints.Count - 4) + i].y) );
			}
			poly = new Polygon(outer);
			poly.AddHole(new Polygon(verts));
		} else {
			poly = new Polygon(verts);
		}
		
		if (aVertGridSpacing > 0) {
			if (aInvert) bounds = GetBounds(aPoints);
			for (float y = bounds.w + aVertGridSpacing; y <= bounds.y; y+=aVertGridSpacing) {
				for (float x = bounds.x + aVertGridSpacing; x <= bounds.z; x+=aVertGridSpacing) {
					TriangulationPoint pt     = new TriangulationPoint(x, y);
					bool               inside = poly.IsPointInside(pt);
					if (inside) poly.AddSteinerPoint(pt);
				}
			}
		}
		P2T.Triangulate(poly);
		 
		aPoints.Clear();
		List<int> result= new List<int>(poly.Triangles.Count * 3);
		int       ind   = 0;
		foreach (DelaunayTriangle triangle in poly.Triangles) {
			TriangulationPoint p1 = triangle.Points[0];
			TriangulationPoint p2 = triangle.PointCWFrom(p1);
			TriangulationPoint p3 = triangle.PointCWFrom(p2);
			
			aPoints.Add(new Vector2(p1.Xf, p1.Yf));
			aPoints.Add(new Vector2(p2.Xf, p2.Yf));
			aPoints.Add(new Vector2(p3.Xf, p3.Yf));
			result.Add(ind++);
			result.Add(ind++);
			result.Add(ind++);
		}
		return result;
	}
        public int IndexOf(TriangulationPoint p)
        {
            int i = Points.IndexOf(p);
            if (i == -1)
            {
                throw new Exception("Calling index with a point that doesn't exist in triangle");
            }

            return i;
        }
 public void SetConstrainedEdgeCW(TriangulationPoint p, bool ce)
 {
     int idx = (IndexOf(p) + 1) % 3;
     SetConstrainedEdge(idx, ce);
 }
 public TriangulationPoint PointCWFrom(TriangulationPoint point)
 {
     return Points[(IndexOf(point) + 2) % 3];
 }
 public DelaunayTriangle NeighborCWFrom(TriangulationPoint point)
 {
     return Neighbors[(Points.IndexOf(point) + 1) % 3];
 }
 /// <summary>
 /// Mark edge as constrained
 /// </summary>
 public void MarkConstrainedEdge(TriangulationPoint p, TriangulationPoint q)
 {
     int i = EdgeIndex(p, q);
     if (i != -1)
     {
         mEdgeIsConstrained[i] = true;
     }
 }
Exemple #10
0
 public DelaunayTriangle NeighborAcrossFrom(TriangulationPoint point)
 {
     return(Neighbors[Points.IndexOf(point)]);
 }
Exemple #11
0
		private static bool IsEdgeSideOfTriangle(DelaunayTriangle triangle, TriangulationPoint ep, TriangulationPoint eq)
		{
			int index = triangle.EdgeIndex(ep, eq);
			if (index == -1) return false;
			triangle.MarkConstrainedEdge(index);
			triangle = triangle.Neighbors[index];
			if (triangle != null) triangle.MarkConstrainedEdge(ep, eq);
			return true;
		}
Exemple #12
0
        /// <summary>
        /// This implementation will use simple node traversal algorithm to find a point on the front
        /// </summary>
        public AdvancingFrontNode LocatePoint(TriangulationPoint point)
        {
            double px = point.X;
            AdvancingFrontNode node = FindSearchNode(px);
            double nx = node.Point.X;

            if (px == nx)
            {
                if (point != node.Point)
                {
                    // We might have two nodes with same x value for a short time
                    if (point == node.Prev.Point)
                    {
                        node = node.Prev;
                    }
                    else if (point == node.Next.Point)
                    {
                        node = node.Next;
                    }
                    else
                    {
                        throw new Exception("Failed to find Node for given afront point");
                    }
                }
            }
            else if (px < nx)
            {
                while ((node = node.Prev) != null)
                {
                    if (point == node.Point)
                    {
                        break;
                    }
                }
            }
            else
            {
                while ((node = node.Next) != null)
                {
                    if (point == node.Point)
                    {
                        break;
                    }
                }
            }
            Search = node;

            return node;
        }
Exemple #13
0
 public bool GetDelaunayEdgeCW(TriangulationPoint p)
 {
     return(EdgeIsDelaunay[(IndexOf(p) + 1) % 3]);
 }
Exemple #14
0
        public void SetConstrainedEdgeAcross(TriangulationPoint p, bool ce)
        {
            int idx = IndexOf(p);

            SetConstrainedEdge(idx, ce);
        }
Exemple #15
0
        public void SetConstrainedEdgeCW(TriangulationPoint p, bool ce)
        {
            int idx = (IndexOf(p) + 1) % 3;

            SetConstrainedEdge(idx, ce);
        }
Exemple #16
0
 public bool GetConstrainedEdgeAcross(TriangulationPoint p)
 {
     return(EdgeIsConstrained[IndexOf(p)]);
 }
Exemple #17
0
 public bool GetConstrainedEdgeCW(TriangulationPoint p)
 {
     return(EdgeIsConstrained[(IndexOf(p) + 1) % 3]);
 }
Exemple #18
0
 /// <summary>
 /// Legalize triangle by rotating clockwise around oPoint
 /// </summary>
 /// <param name="oPoint">The origin point to rotate around</param>
 /// <param name="nPoint">???</param>
 public void Legalize(TriangulationPoint oPoint, TriangulationPoint nPoint)
 {
     RotateCW();
     Points[IndexCCWFrom(oPoint)] = nPoint;
 }
Exemple #19
0
 public TriangulationPoint PointCWFrom(TriangulationPoint point)
 {
     return(Points[(IndexOf(point) + 2) % 3]);
 }
 public void SetDelaunayEdgeCW(TriangulationPoint p, bool ce)
 {
     EdgeIsDelaunay[(IndexOf(p) + 1) % 3] = ce;
 }
 /// <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)
 {
     int i = EdgeIndex(p1, p2);
     if (i == -1)
     {
         throw new Exception("Error marking neighbors -- t doesn't contain edge p1-p2!");
     }
     Neighbors[i] = t;
 }
Exemple #22
0
 public bool GetDelaunayEdgeAcross(TriangulationPoint p)
 {
     return(EdgeIsDelaunay[IndexOf(p)]);
 }
Exemple #23
0
		/// <summary>
		/// Find closes node to the left of the new point and
		/// create a new triangle. If needed new holes and basins
		/// will be filled to.
		/// </summary>
		private static AdvancingFrontNode PointEvent(DTSweepContext tcx, TriangulationPoint point)
		{
			AdvancingFrontNode node, newNode;

			node = tcx.LocateNode(point);
			if (tcx.IsDebugEnabled) tcx.DTDebugContext.ActiveNode = node;
			newNode = NewFrontTriangle(tcx, point, node);

			// Only need to check +epsilon since point never have smaller
			// x value than node due to how we fetch nodes from the front
			if (point.X <= node.Point.X + TriangulationUtil.EPSILON) Fill(tcx, node);

			tcx.AddNode(newNode);

			FillAdvancingFront(tcx, newNode);
			return newNode;
		}
Exemple #24
0
 public void SetDelaunayEdgeCW(TriangulationPoint p, bool ce)
 {
     EdgeIsDelaunay[(IndexOf(p) + 1) % 3] = ce;
 }
Exemple #25
0
		/// <summary>
		/// In the case of a pointset with some constraint edges. If a triangle side is collinear
		/// with a part of the constraint we split the constraint into two constraints. This could
		/// happen when the given constraint migth intersect a point in the set.<br/>
		/// This can never happen in the case when we are working with a polygon.
		///
		/// Think of two triangles that have non shared sides that are collinear and the constraint
		/// is set from a point in triangle A to a point in triangle B so that the constraint is
		/// the union of both those sides. We then have to split the constraint into two so we get
		/// one constraint for each triangle.
		/// </summary>
		/// <param name="ep"></param>
		/// <param name="eq"></param>
		/// <param name="p">point on the edge between ep->eq</param>
		private static void SplitEdge(TriangulationPoint ep, TriangulationPoint eq, TriangulationPoint p)
		{
			DTSweepConstraint edge = eq.Edges.First(e => e.Q == ep || e.P == ep);
			edge.P = p;
			new DTSweepConstraint(ep, p); // Et tu, Brute? --MM

			//        // Redo this edge now that we have split the constraint
			//          newEdgeEvent( tcx, edge, triangle, point );
			//          // Continue with new edge
			//          newEdgeEvent( tcx, edge, triangle, p2 );
		}
Exemple #26
0
 public void SetDelaunayEdgeAcross(TriangulationPoint p, bool ce)
 {
     EdgeIsDelaunay[IndexOf(p)] = ce;
 }
 /// <summary>
 /// Legalize triangle by rotating clockwise around oPoint
 /// </summary>
 /// <param name="oPoint">The origin point to rotate around</param>
 /// <param name="nPoint">???</param>
 public void Legalize(TriangulationPoint oPoint, TriangulationPoint nPoint)
 {
     RotateCW();
     Points[IndexCCWFrom(oPoint)] = nPoint;
 }
Exemple #28
0
 public DelaunayTriangle(TriangulationPoint p1, TriangulationPoint p2, TriangulationPoint p3)
 {
     Points[0] = p1;
     Points[1] = p2;
     Points[2] = p3;
 }
 public DelaunayTriangle NeighborAcrossFrom(TriangulationPoint point)
 {
     return Neighbors[Points.IndexOf(point)];
 }
Exemple #30
0
 public int IndexCCWFrom(TriangulationPoint p)
 {
     return((IndexOf(p) + 1) % 3);
 }
 /// <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 PointCWFrom(t.PointCWFrom(p));
 }
Exemple #32
0
 public bool Contains(TriangulationPoint p)
 {
     return(Points.Contains(p));
 }
 public void SetConstrainedEdgeAcross(TriangulationPoint p, bool ce)
 {
     int idx = IndexOf(p);
     SetConstrainedEdge(idx, ce);
 }
Exemple #34
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(PointCWFrom(t.PointCWFrom(p)));
 }
 public void SetDelaunayEdgeAcross(TriangulationPoint p, bool ce)
 {
     EdgeIsDelaunay[IndexOf(p)] = ce;
 }
Exemple #36
0
 public static Vector3 V3(Poly2Tri.TriangulationPoint tp)
 {
     return(new Vector3((float)tp.X, (float)tp.Y, 0f));
 }
        public bool SharedEdge(TriangulationPoint p1, TriangulationPoint p2)
        {
            bool shared = false;
            foreach (DelaunayTriangle t in Neighbors)
            {

                if (t != null)
                {
                    if (t.Contains(p1) && t.Contains(p2))
                    {
                        shared = true;
                        UnityEngine.Debug.Log("Shared edge");
                    }
                    else
                    {
                        UnityEngine.Debug.Log("Non shared edge");
                    }
                }
                else
                {
                    UnityEngine.Debug.Log("Null edge");
                }
            }

            return shared;
        }
Exemple #38
0
 public static Vector2 UV(Poly2Tri.TriangulationPoint tp, float scale = 1.0f, float offset = 0.5f)
 {
     return(new Vector2((float)(tp.X + offset) * scale, (float)(tp.Y + offset) * scale));
 }
 public DelaunayTriangle(TriangulationPoint p1, TriangulationPoint p2, TriangulationPoint p3)
 {
     Points[0] = p1;
     Points[1] = p2;
     Points[2] = p3;
 }
Exemple #40
0
 public bool contains(TriangulationPoint p, TriangulationPoint q)
 {
     return(contains(p) && contains(q));
 }
Exemple #41
0
 /// <summary>
 /// We use a balancing tree to locate a node smaller or equal to given key value (in theory)
 /// </summary>
 public AdvancingFrontNode LocateNode(TriangulationPoint point)
 {
     return LocateNode(point.X);
 }
Exemple #42
0
		/// <summary>
		/// When we need to traverse from one triangle to the next we need
		/// the point in current triangle that is the opposite point to the next
		/// triangle.
		/// </summary>
		private static TriangulationPoint NextFlipPoint(TriangulationPoint ep, TriangulationPoint eq, DelaunayTriangle ot, TriangulationPoint op)
		{
			Orientation o2d = TriangulationUtil.Orient2d(eq, op, ep);
			switch (o2d)
			{
				case Orientation.CW: return ot.PointCCWFrom(op);
				case Orientation.CCW: return ot.PointCWFrom(op);
				case Orientation.Collinear:
					// TODO: implement support for point on constraint edge
					throw new PointOnEdgeException("Point on constrained edge not supported yet", eq, op, ep);
				default:
					throw new NotImplementedException("Orientation not handled");
			}
		}
Exemple #43
0
		/// <summary>
		/// Creates a new front triangle and legalize it
		/// </summary>
		private static AdvancingFrontNode NewFrontTriangle(DTSweepContext tcx, TriangulationPoint point, AdvancingFrontNode node)
		{
			AdvancingFrontNode newNode;
			DelaunayTriangle triangle;

			triangle = new DelaunayTriangle(point, node.Point, node.Next.Point);
			triangle.MarkNeighbor(node.Triangle);
			tcx.Triangles.Add(triangle);

			newNode = new AdvancingFrontNode(point);
			newNode.Next = node.Next;
			newNode.Prev = node;
			node.Next.Prev = newNode;
			node.Next = newNode;

			tcx.AddNode(newNode); // XXX: BST

			if (tcx.IsDebugEnabled) tcx.DTDebugContext.ActiveNode = newNode;

			if (!Legalize(tcx, triangle)) tcx.MapTriangleToNodes(triangle);

			return newNode;
		}
Exemple #44
0
		/// <summary>
		/// Scan part of the FlipScan algorithm<br/>
		/// When a triangle pair isn't flippable we will scan for the next
		/// point that is inside the flip triangle scan area. When found
		/// we generate a new flipEdgeEvent
		/// </summary>
		/// <param name="tcx"></param>
		/// <param name="ep">last point on the edge we are traversing</param>
		/// <param name="eq">first point on the edge we are traversing</param>
		/// <param name="flipTriangle">the current triangle sharing the point eq with edge</param>
		/// <param name="t"></param>
		/// <param name="p"></param>
		private static void FlipScanEdgeEvent(DTSweepContext tcx, TriangulationPoint ep, TriangulationPoint eq, DelaunayTriangle flipTriangle, DelaunayTriangle t, TriangulationPoint p)
		{
			DelaunayTriangle ot;
			TriangulationPoint op, newP;
			bool inScanArea;

			ot = t.NeighborAcrossFrom(p);
			op = ot.OppositePoint(t, p);

			if (ot == null)
			{
				// If we want to integrate the fillEdgeEvent do it here
				// With current implementation we should never get here
				throw new Exception("[BUG:FIXME] FLIP failed due to missing triangle");
			}

			if (tcx.IsDebugEnabled)
			{
				Console.WriteLine("[FLIP:SCAN] - scan next point"); // TODO: remove
				tcx.DTDebugContext.PrimaryTriangle = t;
				tcx.DTDebugContext.SecondaryTriangle = ot;
			}

			inScanArea = TriangulationUtil.InScanArea(eq, flipTriangle.PointCCWFrom(eq), flipTriangle.PointCWFrom(eq), op);
			if (inScanArea)
			{
				// flip with new edge op->eq
				FlipEdgeEvent(tcx, eq, op, ot, op);
				// TODO: Actually I just figured out that it should be possible to
				//       improve this by getting the next ot and op before the the above
				//       flip and continue the flipScanEdgeEvent here
				// set new ot and op here and loop back to inScanArea test
				// also need to set a new flipTriangle first
				// Turns out at first glance that this is somewhat complicated
				// so it will have to wait.
			}
			else
			{
				newP = NextFlipPoint(ep, eq, ot, op);
				FlipScanEdgeEvent(tcx, ep, eq, flipTriangle, ot, newP);
			}
		}
Exemple #45
0
		private static void EdgeEvent(DTSweepContext tcx, TriangulationPoint ep, TriangulationPoint eq, DelaunayTriangle triangle, TriangulationPoint point)
		{
			TriangulationPoint p1, p2;

			if (tcx.IsDebugEnabled) tcx.DTDebugContext.PrimaryTriangle = triangle;

			if (IsEdgeSideOfTriangle(triangle, ep, eq)) return;

			p1 = triangle.PointCCWFrom(point);
			Orientation o1 = TriangulationUtil.Orient2d(eq, p1, ep);
			if (o1 == Orientation.Collinear)
			{
				// TODO: Split edge in two
				////            splitEdge( ep, eq, p1 );
				//            edgeEvent( tcx, p1, eq, triangle, point );
				//            edgeEvent( tcx, ep, p1, triangle, p1 );
				//            return;
				throw new PointOnEdgeException("EdgeEvent - Point on constrained edge not supported yet", eq, p1, ep);
			}

			p2 = triangle.PointCWFrom(point);
			Orientation o2 = TriangulationUtil.Orient2d(eq, p2, ep);
			if (o2 == Orientation.Collinear)
			{
				// TODO: Split edge in two
				//            edgeEvent( tcx, p2, eq, triangle, point );
				//            edgeEvent( tcx, ep, p2, triangle, p2 );
				//            return;
				throw new PointOnEdgeException("EdgeEvent - Point on constrained edge not supported yet", eq, p2, ep);
			}

			if (o1 == o2)
			{
				// Need to decide if we are rotating CW or CCW to get to a triangle
				// that will cross edge
				if (o1 == Orientation.CW)
				{
					triangle = triangle.NeighborCCWFrom(point);
				}
				else
				{
					triangle = triangle.NeighborCWFrom(point);
				}
				EdgeEvent(tcx, ep, eq, triangle, point);
			}
			else
			{
				// This triangle crosses constraint so lets flippin start!
				FlipEdgeEvent(tcx, ep, eq, triangle, point);
			}
		}
Exemple #46
0
 public bool contains(TriangulationPoint p)
 {
     return(p == points[0] || p == points[1] || p == points[2]);
 }
Exemple #47
0
		private static void FlipEdgeEvent(DTSweepContext tcx, TriangulationPoint ep, TriangulationPoint eq, DelaunayTriangle t, TriangulationPoint p)
		{
			DelaunayTriangle ot = t.NeighborAcrossFrom(p);
			TriangulationPoint op = ot.OppositePoint(t, p);

			if (ot == null)
			{
				// If we want to integrate the fillEdgeEvent do it here
				// With current implementation we should never get here
				throw new InvalidOperationException("[BUG:FIXME] FLIP failed due to missing triangle");
			}

			if (tcx.IsDebugEnabled)
			{
				tcx.DTDebugContext.PrimaryTriangle = t;
				tcx.DTDebugContext.SecondaryTriangle = ot;
			} // TODO: remove

			bool inScanArea = TriangulationUtil.InScanArea(p, t.PointCCWFrom(p), t.PointCWFrom(p), op);
			if (inScanArea)
			{
				// Lets rotate shared edge one vertex CW
				RotateTrianglePair(t, p, ot, op);
				tcx.MapTriangleToNodes(t);
				tcx.MapTriangleToNodes(ot);

				if (p == eq && op == ep)
				{
					if (eq == tcx.EdgeEvent.ConstrainedEdge.Q
						&& ep == tcx.EdgeEvent.ConstrainedEdge.P)
					{
						if (tcx.IsDebugEnabled) Console.WriteLine("[FLIP] - constrained edge done"); // TODO: remove
						t.MarkConstrainedEdge(ep, eq);
						ot.MarkConstrainedEdge(ep, eq);
						Legalize(tcx, t);
						Legalize(tcx, ot);
					}
					else
					{
						if (tcx.IsDebugEnabled) Console.WriteLine("[FLIP] - subedge done"); // TODO: remove
																																								// XXX: I think one of the triangles should be legalized here?
					}
				}
				else
				{
					if (tcx.IsDebugEnabled) Console.WriteLine("[FLIP] - flipping and continuing with triangle still crossing edge"); // TODO: remove
					Orientation o = TriangulationUtil.Orient2d(eq, op, ep);
					t = NextFlipTriangle(tcx, o, t, ot, p, op);
					FlipEdgeEvent(tcx, ep, eq, t, p);
				}
			}
			else
			{
				TriangulationPoint newP = NextFlipPoint(ep, eq, ot, op);
				FlipScanEdgeEvent(tcx, ep, eq, t, ot, newP);
				EdgeEvent(tcx, ep, eq, t, p);
			}
		}
Exemple #48
0
 public DelaunayTriangle NeighborCCWFrom(TriangulationPoint point)
 {
     return(Neighbors[(Points.IndexOf(point) + 2) % 3]);
 }
Exemple #49
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, TriangulationPoint p, TriangulationPoint 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;
		}
 public int IndexCWFrom(TriangulationPoint p)
 {
     return (IndexOf(p) + 2) % 3;
 }
Exemple #51
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, TriangulationPoint p, DelaunayTriangle ot, TriangulationPoint 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);
		}
Exemple #52
0
 public PointOnEdgeException(string message, TriangulationPoint a, TriangulationPoint b, TriangulationPoint c)
     : base(message)
 {
     A = a;
     B = b;
     C = c;
 }