本文整理匯總了C#中Poly2Tri.DTSweepContext類的典型用法代碼示例。如果您正苦於以下問題:C# DTSweepContext類的具體用法?C# DTSweepContext怎麽用?C# DTSweepContext使用的例子?那麽, 這裏精選的類代碼示例或許可以為您提供幫助。
DTSweepContext類屬於Poly2Tri命名空間,在下文中一共展示了DTSweepContext類的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的C#代碼示例。
示例1: Triangulate
/// <summary>
/// Triangulate simple polygon with holes
/// </summary>
public static void Triangulate(DTSweepContext tcx)
{
tcx.CreateAdvancingFront();
Sweep(tcx);
FixupConstrainedEdges(tcx);
// Finalize triangulation
if (tcx.TriangulationMode == TriangulationMode.Polygon)
{
FinalizationPolygon(tcx);
}
else
{
FinalizationConvexHull(tcx);
if (tcx.TriangulationMode == TriangulationMode.Constrained)
{
// work in progress. When it's done, call FinalizationConstraints INSTEAD of tcx.FinalizeTriangulation
//FinalizationConstraints(tcx);
tcx.FinalizeTriangulation();
}
else
{
tcx.FinalizeTriangulation();
}
}
tcx.Done();
}
示例2: Triangulate
/// <summary>
/// Triangulate simple polygon with holes
/// </summary>
public static void Triangulate(DTSweepContext tcx)
{
tcx.CreateAdvancingFront();
Sweep(tcx);
// TODO: remove temporary
// Check if the sweep algorithm is legalize robust
// By doing a legalize on all triangles and see if anything happens
// we know if the sweep algorithm missed some legalizations
// Console.WriteLine("============================");
// foreach ( DelaunayTriangle t in tcx.Triangles )
// {
// if( Legalize( tcx, t ) )
// {
// tcx.getDebugContext().setPrimaryTriangle( t );
// Console.WriteLine("[FIX] Triangle needed legalization after sweep");
// }
// }
// Finalize triangulation
if (tcx.TriangulationMode == TriangulationMode.Polygon)
{
FinalizationPolygon(tcx);
}
else
{
FinalizationConvexHull(tcx);
}
tcx.Done();
}
示例3: CreateMesh
private void CreateMesh() {
Sprite sprite = spriteRenderer.sprite;
Rect bounds = GetBounds(polygon);
DTSweepContext ctx = new DTSweepContext();
Polygon poly = new Polygon(polygon.Select(p => new PolygonPoint(p.x, p.y)));
ctx.PrepareTriangulation(poly);
DTSweep.Triangulate(ctx);
List<Vector2> verts = new List<Vector2>();
List<int> tris = new List<int>();
foreach (DelaunayTriangle tri in poly.Triangles) {
verts.AddRange(tri.Points.Reverse().Select(p => new Vector2(p.Xf, p.Yf)));
for (int i = 0; i < 3; i++) {
tris.Add(tris.Count);
}
}
Mesh mesh = new Mesh();
mesh.vertices = verts.Select(x => (Vector3)x).ToArray();
mesh.triangles = tris.ToArray();
List<Vector2> uv = new List<Vector2>();
Vector3 lower = new Vector3(bounds.x, bounds.y);
Vector3 size = new Vector3(bounds.xMax, bounds.yMax) - lower;
Rect uv_bounds = new Rect(sprite.rect.x / sprite.texture.width, sprite.rect.y / sprite.texture.height, sprite.rect.width / sprite.texture.width, sprite.rect.height / sprite.texture.height);
float scalex = sprite.bounds.size.x / bounds.width;
float scaley = sprite.bounds.size.y / bounds.height;
Vector3[] scaled = mesh.vertices;
for (int i = 0; i < mesh.vertices.Length; i++) {
Vector3 v = scaled[i];
Vector3 rel = v - lower;
uv.Add(new Vector2(rel.x / size.x * uv_bounds.width, rel.y / size.y * uv_bounds.height) + new Vector2(uv_bounds.x, uv_bounds.y));
scaled[i] = new Vector3(v.x * scalex, v.y * scaley, v.z) - ((Vector3)bounds.center * scalex) + sprite.bounds.center;
}
mesh.vertices = scaled;
mesh.uv = uv.ToArray();
mesh.RecalculateNormals();
mesh.RecalculateBounds();
mesh.Optimize();
//GameObject go = new GameObject();
//MeshFilter mf = go.AddComponent<MeshFilter>();
//mf.sharedMesh = mesh;
//MeshRenderer mr = go.AddComponent<MeshRenderer>();
//mr.sharedMaterial = spriteRenderer.sharedMaterial;
ScriptableObjectUtility.CreateAsset(mesh);
}
示例4: CreateMesh
/// <summary>
/// Create a Mesh from a given Polygon.
/// </summary>
/// <returns>The freshly minted mesh.</returns>
/// <param name="polygon">Polygon you want to triangulate.</param>
public static Mesh CreateMesh(Polygon polygon)
{
// Ensure we have the rotation properly calculated
if (polygon.rotation == Quaternion.identity) polygon.CalcRotation();
// Rotate 1 point and note where it ends up in Z
float z = (polygon.rotation * polygon.outside[0]).z;
// Convert the outside points (throwing out Z at this point)
Poly2Tri.Polygon poly = new Poly2Tri.Polygon(ConvertPoints(polygon.outside, polygon.rotation));
// Convert each of the holes
foreach (List<Vector3> hole in polygon.holes) {
poly.AddHole(new Poly2Tri.Polygon(ConvertPoints(hole, polygon.rotation)));
}
// Triangulate it! Note that this may throw an exception if the data is bogus.
DTSweepContext tcx = new DTSweepContext();
tcx.PrepareTriangulation(poly);
DTSweep.Triangulate(tcx);
tcx = null;
// Create the Vector3 vertices (undoing the rotation),
// and also build a map of vertex codes to indices
Quaternion invRot = Quaternion.Inverse(polygon.rotation);
Dictionary<uint, int> codeToIndex = new Dictionary<uint, int>();
List<Vector3> vertexList = new List<Vector3>();
foreach (DelaunayTriangle t in poly.Triangles) {
foreach (var p in t.Points) {
if (codeToIndex.ContainsKey(p.VertexCode)) continue;
codeToIndex[p.VertexCode] = vertexList.Count;
Vector3 pos = new Vector3(p.Xf, p.Yf, z); // (restore the Z we saved earlier)
vertexList.Add(invRot * pos);
}
}
// Create the indices array
int[] indices = new int[poly.Triangles.Count * 3];
{
int i = 0;
foreach (DelaunayTriangle t in poly.Triangles) {
indices[i++] = codeToIndex[t.Points[0].VertexCode];
indices[i++] = codeToIndex[t.Points[1].VertexCode];
indices[i++] = codeToIndex[t.Points[2].VertexCode];
}
}
// Create the UV list, by looking up the closest point for each in our poly
Mesh msh = new Mesh();
msh.vertices = vertexList.ToArray();
Vector2[] uvs = new Vector2[msh.vertices.Length];
for (int i=0; i < uvs.Length; i++) {
uvs[i] = new Vector2(msh.vertices[i].x, msh.vertices[i].y);
}
msh.uv = uvs;
/*if (polygon.OutsideUVs != null) {
uv = new Vector2[vertexList.Count];
for (int i=0; i<vertexList.Count; i++) {
uv[i] = polygon.ClosestUV(vertexList[i]);
}
}*/
// Create the mesh
msh.triangles = indices;
msh.RecalculateNormals();
msh.RecalculateBounds();
return msh;
}
示例5: Legalize
/// <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;
TriangulationPoint p = t.Points[i];
TriangulationPoint 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;
}
示例6: IsShallow
private static bool IsShallow(DTSweepContext tcx, AdvancingFrontNode node)
{
double height;
if (tcx.Basin.leftHighest)
{
height = tcx.Basin.leftNode.Point.Y - node.Point.Y;
}
else
{
height = tcx.Basin.rightNode.Point.Y - node.Point.Y;
}
if (tcx.Basin.width > height)
{
return true;
}
return false;
}
示例7: FillBasin
/// <summary>
/// Fills a basin that has formed on the Advancing Front to the right
/// of given node.<br/>
/// First we decide a left,bottom and right node that forms the
/// boundaries of the basin. Then we do a reqursive fill.
/// </summary>
/// <param name="tcx"></param>
/// <param name="node">starting node, this or next node will be left node</param>
private static void FillBasin(DTSweepContext tcx, AdvancingFrontNode node)
{
if (TriangulationUtil.Orient2d(node.Point, node.Next.Point, node.Next.Next.Point) == Orientation.CCW)
{
// tcx.basin.leftNode = node.next.next;
tcx.Basin.leftNode = node;
}
else
{
tcx.Basin.leftNode = node.Next;
}
// Find the bottom and right node
tcx.Basin.bottomNode = tcx.Basin.leftNode;
while (tcx.Basin.bottomNode.HasNext && tcx.Basin.bottomNode.Point.Y >= tcx.Basin.bottomNode.Next.Point.Y) tcx.Basin.bottomNode = tcx.Basin.bottomNode.Next;
if (tcx.Basin.bottomNode == tcx.Basin.leftNode) return; // No valid basin
tcx.Basin.rightNode = tcx.Basin.bottomNode;
while (tcx.Basin.rightNode.HasNext && tcx.Basin.rightNode.Point.Y < tcx.Basin.rightNode.Next.Point.Y) tcx.Basin.rightNode = tcx.Basin.rightNode.Next;
if (tcx.Basin.rightNode == tcx.Basin.bottomNode) return; // No valid basins
tcx.Basin.width = tcx.Basin.rightNode.Point.X - tcx.Basin.leftNode.Point.X;
tcx.Basin.leftHighest = tcx.Basin.leftNode.Point.Y > tcx.Basin.rightNode.Point.Y;
FillBasinReq(tcx, tcx.Basin.bottomNode);
}
示例8: FlipScanEdgeEvent
/// <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);
}
}
示例9: EdgeEvent
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);
}
}
示例10: TurnAdvancingFrontConvex
/// <summary>
/// We will traverse the entire advancing front and fill it to form a convex hull.
/// </summary>
private static void TurnAdvancingFrontConvex(DTSweepContext tcx, AdvancingFrontNode b, AdvancingFrontNode c)
{
AdvancingFrontNode first = b;
while (c != tcx.Front.Tail)
{
if (tcx.IsDebugEnabled) tcx.DTDebugContext.ActiveNode = c;
if (TriangulationUtil.Orient2d(b.Point, c.Point, c.Next.Point) == Orientation.CCW)
{
// [b,c,d] Concave - fill around c
Fill(tcx, c);
c = c.Next;
}
else
{
// [b,c,d] Convex
if (b != first && TriangulationUtil.Orient2d(b.Prev.Point, b.Point, c.Point) == Orientation.CCW)
{
// [a,b,c] Concave - fill around b
Fill(tcx, b);
b = b.Prev;
}
else
{
// [a,b,c] Convex - nothing to fill
b = c;
c = c.Next;
}
}
}
}
示例11: FinalizationConvexHull
/// <summary>
/// If this is a Delaunay Triangulation of a pointset we need to fill so the triangle mesh gets a ConvexHull
/// </summary>
private static void FinalizationConvexHull(DTSweepContext tcx)
{
AdvancingFrontNode n1, n2, n3;
DelaunayTriangle t1;
TriangulationPoint first, p1;
n1 = tcx.Front.Head.Next;
n2 = n1.Next;
n3 = n2.Next;
first = n1.Point;
TurnAdvancingFrontConvex(tcx, n1, n2);
n1 = tcx.Front.Tail.Prev;
if (n1.Triangle.Contains(n1.Next.Point) && n1.Triangle.Contains(n1.Prev.Point))
{
t1 = n1.Triangle.NeighborAcrossFrom(n1.Point);
RotateTrianglePair(n1.Triangle, n1.Point, t1, t1.OppositePoint(n1.Triangle, n1.Point));
tcx.MapTriangleToNodes(n1.Triangle);
tcx.MapTriangleToNodes(t1);
}
n1 = tcx.Front.Head.Next;
if (n1.Triangle.Contains(n1.Prev.Point) && n1.Triangle.Contains(n1.Next.Point))
{
t1 = n1.Triangle.NeighborAcrossFrom(n1.Point);
RotateTrianglePair(n1.Triangle, n1.Point, t1, t1.OppositePoint(n1.Triangle, n1.Point));
tcx.MapTriangleToNodes(n1.Triangle);
tcx.MapTriangleToNodes(t1);
}
// TODO: implement ConvexHull for lower right and left boundary
// Lower right boundary
first = tcx.Front.Head.Point;
n2 = tcx.Front.Tail.Prev;
t1 = n2.Triangle;
p1 = n2.Point;
do
{
tcx.RemoveFromList(t1);
p1 = t1.PointCCWFrom(p1);
if (p1 == first) break;
t1 = t1.NeighborCCWFrom(p1);
} while (true);
// Lower left boundary
first = tcx.Front.Head.Next.Point;
p1 = t1.PointCWFrom(tcx.Front.Head.Point);
t1 = t1.NeighborCWFrom(tcx.Front.Head.Point);
do
{
tcx.RemoveFromList(t1);
p1 = t1.PointCCWFrom(p1);
t1 = t1.NeighborCCWFrom(p1);
} while (p1 != first);
tcx.FinalizeTriangulation();
}
示例12: EdgeEvent
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)
{
if (triangle.Contains(eq) && triangle.Contains(p1))
{
triangle.MarkConstrainedEdge(eq, p1);
// We are modifying the constraint maybe it would be better to
// not change the given constraint and just keep a variable for the new constraint
tcx.EdgeEvent.ConstrainedEdge.Q = p1;
triangle = triangle.NeighborAcrossFrom(point);
EdgeEvent(tcx, ep, p1, triangle, p1);
}
else
{
throw new PointOnEdgeException("EdgeEvent - Point on constrained edge not supported yet", ep, eq, p1);
}
if (tcx.IsDebugEnabled)
{
Console.WriteLine("EdgeEvent - Point on constrained edge");
}
return;
}
p2 = triangle.PointCWFrom(point);
Orientation o2 = TriangulationUtil.Orient2d(eq, p2, ep);
if (o2 == Orientation.Collinear)
{
if (triangle.Contains(eq) && triangle.Contains(p2))
{
triangle.MarkConstrainedEdge(eq, p2);
// We are modifying the constraint maybe it would be better to
// not change the given constraint and just keep a variable for the new constraint
tcx.EdgeEvent.ConstrainedEdge.Q = p2;
triangle = triangle.NeighborAcrossFrom(point);
EdgeEvent(tcx, ep, p2, triangle, p2);
}
else
{
throw new PointOnEdgeException("EdgeEvent - Point on constrained edge not supported yet", ep, eq, p2);
}
if (tcx.IsDebugEnabled)
{
Console.WriteLine("EdgeEvent - Point on constrained edge");
}
return;
}
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);
}
}
示例13: FinalizationConstraints
/// <summary>
/// NOTE: WORK IN PROGRESS - for now this will just clean out all triangles from
/// inside the outermost holes without paying attention to holes within holes..
/// hence the work in progress :)
///
/// Removes triangles inside "holes" (that are not inside of other holes already)
///
/// In the example below, assume that triangle ABC is a user-defined "hole". Thus
/// any triangles inside it (that aren't inside yet another user-defined hole inside
/// triangle ABC) should get removed. In this case, since there are no user-defined
/// holes inside ABC, we would remove triangles ADE, BCE, and CDE. We would also
/// need to combine the appropriate edges so that we end up with just triangle ABC
///
/// E
/// A +------+-----+ B A +-----------+ B
/// \ /| / \ /
/// \ / | / \ /
/// D + | / ======> \ /
/// \ | / \ /
/// \ |/ \ /
/// + +
/// C C
///
/// </summary>
private static void FinalizationConstraints(DTSweepContext tcx)
{
// Get an Internal triangle to start with
DelaunayTriangle t = tcx.Front.Head.Triangle;
TriangulationPoint p = tcx.Front.Head.Point;
while (!t.GetConstrainedEdgeCW(p))
{
DelaunayTriangle tTmp = t.NeighborCCWFrom(p);
if (tTmp == null)
{
break;
}
t = tTmp;
}
// Collect interior triangles constrained by edges
tcx.MeshClean(t);
}
示例14: FinalizationConvexHull
/// <summary>
/// If this is a Delaunay Triangulation of a pointset we need to fill so the triangle mesh gets a ConvexHull
/// </summary>
private static void FinalizationConvexHull(DTSweepContext tcx)
{
AdvancingFrontNode n1, n2;
DelaunayTriangle t1, t2;
TriangulationPoint first, p1;
n1 = tcx.Front.Head.Next;
n2 = n1.Next;
first = n1.Point;
TurnAdvancingFrontConvex(tcx, n1, n2);
// Lets remove triangles connected to the two "algorithm" points
// XXX: When the first three nodes are points in a triangle we need to do a flip before
// removing triangles or we will lose a valid triangle.
// Same for last three nodes!
// !!! If I implement ConvexHull for lower right and left boundary this fix should not be
// needed and the removed triangles will be added again by default
n1 = tcx.Front.Tail.Prev;
if (n1.Triangle.Contains(n1.Next.Point) && n1.Triangle.Contains(n1.Prev.Point))
{
t1 = n1.Triangle.NeighborAcrossFrom(n1.Point);
RotateTrianglePair(n1.Triangle, n1.Point, t1, t1.OppositePoint(n1.Triangle, n1.Point));
tcx.MapTriangleToNodes(n1.Triangle);
tcx.MapTriangleToNodes(t1);
}
n1 = tcx.Front.Head.Next;
if (n1.Triangle.Contains(n1.Prev.Point) && n1.Triangle.Contains(n1.Next.Point))
{
t1 = n1.Triangle.NeighborAcrossFrom(n1.Point);
RotateTrianglePair(n1.Triangle, n1.Point, t1, t1.OppositePoint(n1.Triangle, n1.Point));
tcx.MapTriangleToNodes(n1.Triangle);
tcx.MapTriangleToNodes(t1);
}
// Lower right boundary
first = tcx.Front.Head.Point;
n2 = tcx.Front.Tail.Prev;
t1 = n2.Triangle;
p1 = n2.Point;
n2.Triangle = null;
do
{
tcx.RemoveFromList(t1);
p1 = t1.PointCCWFrom(p1);
if (p1 == first)
{
break;
}
t2 = t1.NeighborCCWFrom(p1);
t1.Clear();
t1 = t2;
} while (true);
// Lower left boundary
first = tcx.Front.Head.Next.Point;
p1 = t1.PointCWFrom(tcx.Front.Head.Point);
t2 = t1.NeighborCWFrom(tcx.Front.Head.Point);
t1.Clear();
t1 = t2;
while (p1 != first)
{
tcx.RemoveFromList(t1);
p1 = t1.PointCCWFrom(p1);
t2 = t1.NeighborCCWFrom(p1);
t1.Clear();
t1 = t2;
}
// Remove current head and tail node now that we have removed all triangles attached
// to them. Then set new head and tail node points
tcx.Front.Head = tcx.Front.Head.Next;
tcx.Front.Head.Prev = null;
tcx.Front.Tail = tcx.Front.Tail.Prev;
tcx.Front.Tail.Next = null;
}
示例15: FixupConstrainedEdges
private static void FixupConstrainedEdges(DTSweepContext tcx)
{
foreach(DelaunayTriangle t in tcx.Triangles)
{
for (int i = 0; i < 3; ++i)
{
bool isConstrained = t.GetConstrainedEdgeCCW(t.Points[i]);
if (!isConstrained)
{
DTSweepConstraint edge = null;
bool hasConstrainedEdge = t.GetEdgeCCW(t.Points[i], out edge);
if (hasConstrainedEdge)
{
t.MarkConstrainedEdge((i + 2) % 3);
//t.MarkConstrainedEdgeCCW(t.Points[i]);
}
}
}
}
}