Files
Dec2017-Script-Dump/Poly2Tri/DTSweep.cs
T
2026-06-04 11:42:34 +02:00

771 lines
26 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
namespace Poly2Tri
{
// Token: 0x02000009 RID: 9
public static class DTSweep
{
// Token: 0x06000058 RID: 88 RVA: 0x00002EBD File Offset: 0x000010BD
public static void Triangulate(DTSweepContext tcx)
{
tcx.CreateAdvancingFront();
DTSweep.Sweep(tcx);
if (tcx.TriangulationMode == TriangulationMode.Polygon)
{
DTSweep.FinalizationPolygon(tcx);
}
else
{
DTSweep.FinalizationConvexHull(tcx);
}
tcx.Done();
}
// Token: 0x06000059 RID: 89 RVA: 0x00002EE8 File Offset: 0x000010E8
private static void Sweep(DTSweepContext tcx)
{
List<TriangulationPoint> points = tcx.Points;
for (int i = 1; i < points.Count; i++)
{
TriangulationPoint triangulationPoint = points[i];
AdvancingFrontNode advancingFrontNode = DTSweep.PointEvent(tcx, triangulationPoint);
if (triangulationPoint.HasEdges)
{
foreach (DTSweepConstraint dtsweepConstraint in triangulationPoint.Edges)
{
if (tcx.IsDebugEnabled)
{
tcx.DTDebugContext.ActiveConstraint = dtsweepConstraint;
}
DTSweep.EdgeEvent(tcx, dtsweepConstraint, advancingFrontNode);
}
}
tcx.Update(null);
}
}
// Token: 0x0600005A RID: 90 RVA: 0x00002F8C File Offset: 0x0000118C
private static void FinalizationConvexHull(DTSweepContext tcx)
{
AdvancingFrontNode advancingFrontNode = tcx.Front.Head.Next;
AdvancingFrontNode advancingFrontNode2 = advancingFrontNode.Next;
AdvancingFrontNode next = advancingFrontNode2.Next;
TriangulationPoint triangulationPoint = advancingFrontNode.Point;
DTSweep.TurnAdvancingFrontConvex(tcx, advancingFrontNode, advancingFrontNode2);
advancingFrontNode = tcx.Front.Tail.Prev;
DelaunayTriangle delaunayTriangle;
if (advancingFrontNode.Triangle.Contains(advancingFrontNode.Next.Point) && advancingFrontNode.Triangle.Contains(advancingFrontNode.Prev.Point))
{
delaunayTriangle = advancingFrontNode.Triangle.NeighborAcrossFrom(advancingFrontNode.Point);
DTSweep.RotateTrianglePair(advancingFrontNode.Triangle, advancingFrontNode.Point, delaunayTriangle, delaunayTriangle.OppositePoint(advancingFrontNode.Triangle, advancingFrontNode.Point));
tcx.MapTriangleToNodes(advancingFrontNode.Triangle);
tcx.MapTriangleToNodes(delaunayTriangle);
}
advancingFrontNode = tcx.Front.Head.Next;
if (advancingFrontNode.Triangle.Contains(advancingFrontNode.Prev.Point) && advancingFrontNode.Triangle.Contains(advancingFrontNode.Next.Point))
{
delaunayTriangle = advancingFrontNode.Triangle.NeighborAcrossFrom(advancingFrontNode.Point);
DTSweep.RotateTrianglePair(advancingFrontNode.Triangle, advancingFrontNode.Point, delaunayTriangle, delaunayTriangle.OppositePoint(advancingFrontNode.Triangle, advancingFrontNode.Point));
tcx.MapTriangleToNodes(advancingFrontNode.Triangle);
tcx.MapTriangleToNodes(delaunayTriangle);
}
triangulationPoint = tcx.Front.Head.Point;
advancingFrontNode2 = tcx.Front.Tail.Prev;
delaunayTriangle = advancingFrontNode2.Triangle;
TriangulationPoint triangulationPoint2 = advancingFrontNode2.Point;
for (;;)
{
tcx.RemoveFromList(delaunayTriangle);
triangulationPoint2 = delaunayTriangle.PointCCWFrom(triangulationPoint2);
if (triangulationPoint2 == triangulationPoint)
{
break;
}
delaunayTriangle = delaunayTriangle.NeighborCCWFrom(triangulationPoint2);
}
triangulationPoint = tcx.Front.Head.Next.Point;
triangulationPoint2 = delaunayTriangle.PointCWFrom(tcx.Front.Head.Point);
delaunayTriangle = delaunayTriangle.NeighborCWFrom(tcx.Front.Head.Point);
do
{
tcx.RemoveFromList(delaunayTriangle);
triangulationPoint2 = delaunayTriangle.PointCCWFrom(triangulationPoint2);
delaunayTriangle = delaunayTriangle.NeighborCCWFrom(triangulationPoint2);
}
while (triangulationPoint2 != triangulationPoint);
tcx.FinalizeTriangulation();
}
// Token: 0x0600005B RID: 91 RVA: 0x00003198 File Offset: 0x00001398
private static void TurnAdvancingFrontConvex(DTSweepContext tcx, AdvancingFrontNode b, AdvancingFrontNode c)
{
AdvancingFrontNode advancingFrontNode = 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)
{
DTSweep.Fill(tcx, c);
c = c.Next;
}
else if (b != advancingFrontNode && TriangulationUtil.Orient2d(b.Prev.Point, b.Point, c.Point) == Orientation.CCW)
{
DTSweep.Fill(tcx, b);
b = b.Prev;
}
else
{
b = c;
c = c.Next;
}
}
}
// Token: 0x0600005C RID: 92 RVA: 0x00003240 File Offset: 0x00001440
private static void FinalizationPolygon(DTSweepContext tcx)
{
DelaunayTriangle delaunayTriangle = tcx.Front.Head.Next.Triangle;
TriangulationPoint point = tcx.Front.Head.Next.Point;
while (!delaunayTriangle.GetConstrainedEdgeCW(point))
{
delaunayTriangle = delaunayTriangle.NeighborCCWFrom(point);
}
tcx.MeshClean(delaunayTriangle);
}
// Token: 0x0600005D RID: 93 RVA: 0x00003294 File Offset: 0x00001494
private static AdvancingFrontNode PointEvent(DTSweepContext tcx, TriangulationPoint point)
{
AdvancingFrontNode advancingFrontNode = tcx.LocateNode(point);
if (tcx.IsDebugEnabled)
{
tcx.DTDebugContext.ActiveNode = advancingFrontNode;
}
AdvancingFrontNode advancingFrontNode2 = DTSweep.NewFrontTriangle(tcx, point, advancingFrontNode);
if (point.X <= advancingFrontNode.Point.X + TriangulationUtil.EPSILON)
{
DTSweep.Fill(tcx, advancingFrontNode);
}
tcx.AddNode(advancingFrontNode2);
DTSweep.FillAdvancingFront(tcx, advancingFrontNode2);
return advancingFrontNode2;
}
// Token: 0x0600005E RID: 94 RVA: 0x000032F8 File Offset: 0x000014F8
private static AdvancingFrontNode NewFrontTriangle(DTSweepContext tcx, TriangulationPoint point, AdvancingFrontNode node)
{
DelaunayTriangle delaunayTriangle = new DelaunayTriangle(point, node.Point, node.Next.Point);
delaunayTriangle.MarkNeighbor(node.Triangle);
tcx.Triangles.Add(delaunayTriangle);
AdvancingFrontNode advancingFrontNode = new AdvancingFrontNode(point);
advancingFrontNode.Next = node.Next;
advancingFrontNode.Prev = node;
node.Next.Prev = advancingFrontNode;
node.Next = advancingFrontNode;
tcx.AddNode(advancingFrontNode);
if (tcx.IsDebugEnabled)
{
tcx.DTDebugContext.ActiveNode = advancingFrontNode;
}
if (!DTSweep.Legalize(tcx, delaunayTriangle))
{
tcx.MapTriangleToNodes(delaunayTriangle);
}
return advancingFrontNode;
}
// Token: 0x0600005F RID: 95 RVA: 0x00003390 File Offset: 0x00001590
private static void EdgeEvent(DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node)
{
try
{
tcx.EdgeEvent.ConstrainedEdge = edge;
tcx.EdgeEvent.Right = edge.P.X > edge.Q.X;
if (tcx.IsDebugEnabled)
{
tcx.DTDebugContext.PrimaryTriangle = node.Triangle;
}
if (!DTSweep.IsEdgeSideOfTriangle(node.Triangle, edge.P, edge.Q))
{
DTSweep.FillEdgeEvent(tcx, edge, node);
DTSweep.EdgeEvent(tcx, edge.P, edge.Q, node.Triangle, edge.Q);
}
}
catch (PointOnEdgeException)
{
throw;
}
}
// Token: 0x06000060 RID: 96 RVA: 0x0000343C File Offset: 0x0000163C
private static void FillEdgeEvent(DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node)
{
if (tcx.EdgeEvent.Right)
{
DTSweep.FillRightAboveEdgeEvent(tcx, edge, node);
return;
}
DTSweep.FillLeftAboveEdgeEvent(tcx, edge, node);
}
// Token: 0x06000061 RID: 97 RVA: 0x0000345C File Offset: 0x0000165C
private static void FillRightConcaveEdgeEvent(DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node)
{
DTSweep.Fill(tcx, node.Next);
if (node.Next.Point != edge.P && TriangulationUtil.Orient2d(edge.Q, node.Next.Point, edge.P) == Orientation.CCW && TriangulationUtil.Orient2d(node.Point, node.Next.Point, node.Next.Next.Point) == Orientation.CCW)
{
DTSweep.FillRightConcaveEdgeEvent(tcx, edge, node);
}
}
// Token: 0x06000062 RID: 98 RVA: 0x000034D8 File Offset: 0x000016D8
private static void FillRightConvexEdgeEvent(DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node)
{
if (TriangulationUtil.Orient2d(node.Next.Point, node.Next.Next.Point, node.Next.Next.Next.Point) == Orientation.CCW)
{
DTSweep.FillRightConcaveEdgeEvent(tcx, edge, node.Next);
return;
}
if (TriangulationUtil.Orient2d(edge.Q, node.Next.Next.Point, edge.P) == Orientation.CCW)
{
DTSweep.FillRightConvexEdgeEvent(tcx, edge, node.Next);
}
}
// Token: 0x06000063 RID: 99 RVA: 0x0000355C File Offset: 0x0000175C
private static void FillRightBelowEdgeEvent(DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node)
{
if (tcx.IsDebugEnabled)
{
tcx.DTDebugContext.ActiveNode = node;
}
if (node.Point.X < edge.P.X)
{
if (TriangulationUtil.Orient2d(node.Point, node.Next.Point, node.Next.Next.Point) == Orientation.CCW)
{
DTSweep.FillRightConcaveEdgeEvent(tcx, edge, node);
return;
}
DTSweep.FillRightConvexEdgeEvent(tcx, edge, node);
DTSweep.FillRightBelowEdgeEvent(tcx, edge, node);
}
}
// Token: 0x06000064 RID: 100 RVA: 0x000035D8 File Offset: 0x000017D8
private static void FillRightAboveEdgeEvent(DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node)
{
while (node.Next.Point.X < edge.P.X)
{
if (tcx.IsDebugEnabled)
{
tcx.DTDebugContext.ActiveNode = node;
}
if (TriangulationUtil.Orient2d(edge.Q, node.Next.Point, edge.P) == Orientation.CCW)
{
DTSweep.FillRightBelowEdgeEvent(tcx, edge, node);
}
else
{
node = node.Next;
}
}
}
// Token: 0x06000065 RID: 101 RVA: 0x0000364C File Offset: 0x0000184C
private static void FillLeftConvexEdgeEvent(DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node)
{
if (TriangulationUtil.Orient2d(node.Prev.Point, node.Prev.Prev.Point, node.Prev.Prev.Prev.Point) == Orientation.CW)
{
DTSweep.FillLeftConcaveEdgeEvent(tcx, edge, node.Prev);
return;
}
if (TriangulationUtil.Orient2d(edge.Q, node.Prev.Prev.Point, edge.P) == Orientation.CW)
{
DTSweep.FillLeftConvexEdgeEvent(tcx, edge, node.Prev);
}
}
// Token: 0x06000066 RID: 102 RVA: 0x000036D0 File Offset: 0x000018D0
private static void FillLeftConcaveEdgeEvent(DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node)
{
DTSweep.Fill(tcx, node.Prev);
if (node.Prev.Point != edge.P && TriangulationUtil.Orient2d(edge.Q, node.Prev.Point, edge.P) == Orientation.CW && TriangulationUtil.Orient2d(node.Point, node.Prev.Point, node.Prev.Prev.Point) == Orientation.CW)
{
DTSweep.FillLeftConcaveEdgeEvent(tcx, edge, node);
}
}
// Token: 0x06000067 RID: 103 RVA: 0x0000374C File Offset: 0x0000194C
private static void FillLeftBelowEdgeEvent(DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node)
{
if (tcx.IsDebugEnabled)
{
tcx.DTDebugContext.ActiveNode = node;
}
if (node.Point.X > edge.P.X)
{
if (TriangulationUtil.Orient2d(node.Point, node.Prev.Point, node.Prev.Prev.Point) == Orientation.CW)
{
DTSweep.FillLeftConcaveEdgeEvent(tcx, edge, node);
return;
}
DTSweep.FillLeftConvexEdgeEvent(tcx, edge, node);
DTSweep.FillLeftBelowEdgeEvent(tcx, edge, node);
}
}
// Token: 0x06000068 RID: 104 RVA: 0x000037C8 File Offset: 0x000019C8
private static void FillLeftAboveEdgeEvent(DTSweepContext tcx, DTSweepConstraint edge, AdvancingFrontNode node)
{
while (node.Prev.Point.X > edge.P.X)
{
if (tcx.IsDebugEnabled)
{
tcx.DTDebugContext.ActiveNode = node;
}
if (TriangulationUtil.Orient2d(edge.Q, node.Prev.Point, edge.P) == Orientation.CW)
{
DTSweep.FillLeftBelowEdgeEvent(tcx, edge, node);
}
else
{
node = node.Prev;
}
}
}
// Token: 0x06000069 RID: 105 RVA: 0x00003838 File Offset: 0x00001A38
private static bool IsEdgeSideOfTriangle(DelaunayTriangle triangle, TriangulationPoint ep, TriangulationPoint eq)
{
int num = triangle.EdgeIndex(ep, eq);
if (num == -1)
{
return false;
}
triangle.MarkConstrainedEdge(num);
triangle = triangle.Neighbors[num];
if (triangle != null)
{
triangle.MarkConstrainedEdge(ep, eq);
}
return true;
}
// Token: 0x0600006A RID: 106 RVA: 0x00003878 File Offset: 0x00001A78
private static void EdgeEvent(DTSweepContext tcx, TriangulationPoint ep, TriangulationPoint eq, DelaunayTriangle triangle, TriangulationPoint point)
{
if (tcx.IsDebugEnabled)
{
tcx.DTDebugContext.PrimaryTriangle = triangle;
}
if (DTSweep.IsEdgeSideOfTriangle(triangle, ep, eq))
{
return;
}
TriangulationPoint triangulationPoint = triangle.PointCCWFrom(point);
Orientation orientation = TriangulationUtil.Orient2d(eq, triangulationPoint, ep);
if (orientation == Orientation.Collinear)
{
throw new PointOnEdgeException("EdgeEvent - Point on constrained edge not supported yet", eq, triangulationPoint, ep);
}
TriangulationPoint triangulationPoint2 = triangle.PointCWFrom(point);
Orientation orientation2 = TriangulationUtil.Orient2d(eq, triangulationPoint2, ep);
if (orientation2 == Orientation.Collinear)
{
throw new PointOnEdgeException("EdgeEvent - Point on constrained edge not supported yet", eq, triangulationPoint2, ep);
}
if (orientation == orientation2)
{
if (orientation == Orientation.CW)
{
triangle = triangle.NeighborCCWFrom(point);
}
else
{
triangle = triangle.NeighborCWFrom(point);
}
DTSweep.EdgeEvent(tcx, ep, eq, triangle, point);
return;
}
DTSweep.FlipEdgeEvent(tcx, ep, eq, triangle, point);
}
// Token: 0x0600006B RID: 107 RVA: 0x00003920 File Offset: 0x00001B20
private static void SplitEdge(TriangulationPoint ep, TriangulationPoint eq, TriangulationPoint p)
{
eq.Edges.First((DTSweepConstraint e) => e.Q == ep || e.P == ep).P = p;
new DTSweepConstraint(ep, p);
}
// Token: 0x0600006C RID: 108 RVA: 0x00003964 File Offset: 0x00001B64
private static void FlipEdgeEvent(DTSweepContext tcx, TriangulationPoint ep, TriangulationPoint eq, DelaunayTriangle t, TriangulationPoint p)
{
DelaunayTriangle delaunayTriangle = t.NeighborAcrossFrom(p);
TriangulationPoint triangulationPoint = delaunayTriangle.OppositePoint(t, p);
if (delaunayTriangle == null)
{
throw new InvalidOperationException("[BUG:FIXME] FLIP failed due to missing triangle");
}
if (tcx.IsDebugEnabled)
{
tcx.DTDebugContext.PrimaryTriangle = t;
tcx.DTDebugContext.SecondaryTriangle = delaunayTriangle;
}
if (TriangulationUtil.InScanArea(p, t.PointCCWFrom(p), t.PointCWFrom(p), triangulationPoint))
{
DTSweep.RotateTrianglePair(t, p, delaunayTriangle, triangulationPoint);
tcx.MapTriangleToNodes(t);
tcx.MapTriangleToNodes(delaunayTriangle);
if (p != eq || triangulationPoint != ep)
{
if (tcx.IsDebugEnabled)
{
Console.WriteLine("[FLIP] - flipping and continuing with triangle still crossing edge");
}
Orientation orientation = TriangulationUtil.Orient2d(eq, triangulationPoint, ep);
t = DTSweep.NextFlipTriangle(tcx, orientation, t, delaunayTriangle, p, triangulationPoint);
DTSweep.FlipEdgeEvent(tcx, ep, eq, t, p);
return;
}
if (eq == tcx.EdgeEvent.ConstrainedEdge.Q && ep == tcx.EdgeEvent.ConstrainedEdge.P)
{
if (tcx.IsDebugEnabled)
{
Console.WriteLine("[FLIP] - constrained edge done");
}
t.MarkConstrainedEdge(ep, eq);
delaunayTriangle.MarkConstrainedEdge(ep, eq);
DTSweep.Legalize(tcx, t);
DTSweep.Legalize(tcx, delaunayTriangle);
return;
}
if (tcx.IsDebugEnabled)
{
Console.WriteLine("[FLIP] - subedge done");
return;
}
}
else
{
TriangulationPoint triangulationPoint2 = DTSweep.NextFlipPoint(ep, eq, delaunayTriangle, triangulationPoint);
DTSweep.FlipScanEdgeEvent(tcx, ep, eq, t, delaunayTriangle, triangulationPoint2);
DTSweep.EdgeEvent(tcx, ep, eq, t, p);
}
}
// Token: 0x0600006D RID: 109 RVA: 0x00003AB4 File Offset: 0x00001CB4
private static TriangulationPoint NextFlipPoint(TriangulationPoint ep, TriangulationPoint eq, DelaunayTriangle ot, TriangulationPoint op)
{
switch (TriangulationUtil.Orient2d(eq, op, ep))
{
case Orientation.CW:
return ot.PointCCWFrom(op);
case Orientation.CCW:
return ot.PointCWFrom(op);
case Orientation.Collinear:
throw new PointOnEdgeException("Point on constrained edge not supported yet", eq, op, ep);
default:
throw new NotImplementedException("Orientation not handled");
}
}
// Token: 0x0600006E RID: 110 RVA: 0x00003B08 File Offset: 0x00001D08
private static DelaunayTriangle NextFlipTriangle(DTSweepContext tcx, Orientation o, DelaunayTriangle t, DelaunayTriangle ot, TriangulationPoint p, TriangulationPoint op)
{
int num;
if (o == Orientation.CCW)
{
num = ot.EdgeIndex(p, op);
ot.EdgeIsDelaunay[num] = true;
DTSweep.Legalize(tcx, ot);
ot.EdgeIsDelaunay.Clear();
return t;
}
num = t.EdgeIndex(p, op);
t.EdgeIsDelaunay[num] = true;
DTSweep.Legalize(tcx, t);
t.EdgeIsDelaunay.Clear();
return ot;
}
// Token: 0x0600006F RID: 111 RVA: 0x00003B74 File Offset: 0x00001D74
private static void FlipScanEdgeEvent(DTSweepContext tcx, TriangulationPoint ep, TriangulationPoint eq, DelaunayTriangle flipTriangle, DelaunayTriangle t, TriangulationPoint p)
{
DelaunayTriangle delaunayTriangle = t.NeighborAcrossFrom(p);
TriangulationPoint triangulationPoint = delaunayTriangle.OppositePoint(t, p);
if (delaunayTriangle == null)
{
throw new Exception("[BUG:FIXME] FLIP failed due to missing triangle");
}
if (tcx.IsDebugEnabled)
{
Console.WriteLine("[FLIP:SCAN] - scan next point");
tcx.DTDebugContext.PrimaryTriangle = t;
tcx.DTDebugContext.SecondaryTriangle = delaunayTriangle;
}
if (TriangulationUtil.InScanArea(eq, flipTriangle.PointCCWFrom(eq), flipTriangle.PointCWFrom(eq), triangulationPoint))
{
DTSweep.FlipEdgeEvent(tcx, eq, triangulationPoint, delaunayTriangle, triangulationPoint);
return;
}
TriangulationPoint triangulationPoint2 = DTSweep.NextFlipPoint(ep, eq, delaunayTriangle, triangulationPoint);
DTSweep.FlipScanEdgeEvent(tcx, ep, eq, flipTriangle, delaunayTriangle, triangulationPoint2);
}
// Token: 0x06000070 RID: 112 RVA: 0x00003C08 File Offset: 0x00001E08
private static void FillAdvancingFront(DTSweepContext tcx, AdvancingFrontNode n)
{
AdvancingFrontNode advancingFrontNode = n.Next;
while (advancingFrontNode.HasNext)
{
double num = DTSweep.HoleAngle(advancingFrontNode);
if (num > 1.5707963267948966 || num < -1.5707963267948966)
{
break;
}
DTSweep.Fill(tcx, advancingFrontNode);
advancingFrontNode = advancingFrontNode.Next;
}
advancingFrontNode = n.Prev;
while (advancingFrontNode.HasPrev)
{
double num = DTSweep.HoleAngle(advancingFrontNode);
if (num > 1.5707963267948966 || num < -1.5707963267948966)
{
break;
}
DTSweep.Fill(tcx, advancingFrontNode);
advancingFrontNode = advancingFrontNode.Prev;
}
if (n.HasNext && n.Next.HasNext)
{
double num = DTSweep.BasinAngle(n);
if (num < 2.356194490192345)
{
DTSweep.FillBasin(tcx, n);
}
}
}
// Token: 0x06000071 RID: 113 RVA: 0x00003CC0 File Offset: 0x00001EC0
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;
}
else
{
tcx.Basin.leftNode = node.Next;
}
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;
}
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;
}
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;
DTSweep.FillBasinReq(tcx, tcx.Basin.bottomNode);
}
// Token: 0x06000072 RID: 114 RVA: 0x00003EB4 File Offset: 0x000020B4
private static void FillBasinReq(DTSweepContext tcx, AdvancingFrontNode node)
{
if (DTSweep.IsShallow(tcx, node))
{
return;
}
DTSweep.Fill(tcx, node);
if (node.Prev == tcx.Basin.leftNode && node.Next == tcx.Basin.rightNode)
{
return;
}
if (node.Prev == tcx.Basin.leftNode)
{
if (TriangulationUtil.Orient2d(node.Point, node.Next.Point, node.Next.Next.Point) == Orientation.CW)
{
return;
}
node = node.Next;
}
else if (node.Next == tcx.Basin.rightNode)
{
if (TriangulationUtil.Orient2d(node.Point, node.Prev.Point, node.Prev.Prev.Point) == Orientation.CCW)
{
return;
}
node = node.Prev;
}
else if (node.Prev.Point.Y < node.Next.Point.Y)
{
node = node.Prev;
}
else
{
node = node.Next;
}
DTSweep.FillBasinReq(tcx, node);
}
// Token: 0x06000073 RID: 115 RVA: 0x00003FC4 File Offset: 0x000021C4
private static bool IsShallow(DTSweepContext tcx, AdvancingFrontNode node)
{
double num;
if (tcx.Basin.leftHighest)
{
num = tcx.Basin.leftNode.Point.Y - node.Point.Y;
}
else
{
num = tcx.Basin.rightNode.Point.Y - node.Point.Y;
}
return tcx.Basin.width > num;
}
// Token: 0x06000074 RID: 116 RVA: 0x00004038 File Offset: 0x00002238
private static double HoleAngle(AdvancingFrontNode node)
{
double x = node.Point.X;
double y = node.Point.Y;
double num = node.Next.Point.X - x;
double num2 = node.Next.Point.Y - y;
double num3 = node.Prev.Point.X - x;
double num4 = node.Prev.Point.Y - y;
return Math.Atan2(num * num4 - num2 * num3, num * num3 + num2 * num4);
}
// Token: 0x06000075 RID: 117 RVA: 0x000040C4 File Offset: 0x000022C4
private static double BasinAngle(AdvancingFrontNode node)
{
double num = node.Point.X - node.Next.Next.Point.X;
return Math.Atan2(node.Point.Y - node.Next.Next.Point.Y, num);
}
// Token: 0x06000076 RID: 118 RVA: 0x0000411C File Offset: 0x0000231C
private static void Fill(DTSweepContext tcx, AdvancingFrontNode node)
{
DelaunayTriangle delaunayTriangle = new DelaunayTriangle(node.Prev.Point, node.Point, node.Next.Point);
delaunayTriangle.MarkNeighbor(node.Prev.Triangle);
delaunayTriangle.MarkNeighbor(node.Triangle);
tcx.Triangles.Add(delaunayTriangle);
node.Prev.Next = node.Next;
node.Next.Prev = node.Prev;
tcx.RemoveNode(node);
if (!DTSweep.Legalize(tcx, delaunayTriangle))
{
tcx.MapTriangleToNodes(delaunayTriangle);
}
}
// Token: 0x06000077 RID: 119 RVA: 0x000041B0 File Offset: 0x000023B0
private static bool Legalize(DTSweepContext tcx, DelaunayTriangle t)
{
for (int i = 0; i < 3; i++)
{
if (!t.EdgeIsDelaunay[i])
{
DelaunayTriangle delaunayTriangle = t.Neighbors[i];
if (delaunayTriangle != null)
{
TriangulationPoint triangulationPoint = t.Points[i];
TriangulationPoint triangulationPoint2 = delaunayTriangle.OppositePoint(t, triangulationPoint);
int num = delaunayTriangle.IndexOf(triangulationPoint2);
if (delaunayTriangle.EdgeIsConstrained[num] || delaunayTriangle.EdgeIsDelaunay[num])
{
t.EdgeIsConstrained[i] = delaunayTriangle.EdgeIsConstrained[num];
}
else if (TriangulationUtil.SmartIncircle(triangulationPoint, t.PointCCWFrom(triangulationPoint), t.PointCWFrom(triangulationPoint), triangulationPoint2))
{
t.EdgeIsDelaunay[i] = true;
delaunayTriangle.EdgeIsDelaunay[num] = true;
DTSweep.RotateTrianglePair(t, triangulationPoint, delaunayTriangle, triangulationPoint2);
if (!DTSweep.Legalize(tcx, t))
{
tcx.MapTriangleToNodes(t);
}
if (!DTSweep.Legalize(tcx, delaunayTriangle))
{
tcx.MapTriangleToNodes(delaunayTriangle);
}
t.EdgeIsDelaunay[i] = false;
delaunayTriangle.EdgeIsDelaunay[num] = false;
return true;
}
}
}
}
return false;
}
// Token: 0x06000078 RID: 120 RVA: 0x000042C4 File Offset: 0x000024C4
private static void RotateTrianglePair(DelaunayTriangle t, TriangulationPoint p, DelaunayTriangle ot, TriangulationPoint op)
{
DelaunayTriangle delaunayTriangle = t.NeighborCCWFrom(p);
DelaunayTriangle delaunayTriangle2 = t.NeighborCWFrom(p);
DelaunayTriangle delaunayTriangle3 = ot.NeighborCCWFrom(op);
DelaunayTriangle delaunayTriangle4 = ot.NeighborCWFrom(op);
bool constrainedEdgeCCW = t.GetConstrainedEdgeCCW(p);
bool constrainedEdgeCW = t.GetConstrainedEdgeCW(p);
bool constrainedEdgeCCW2 = ot.GetConstrainedEdgeCCW(op);
bool constrainedEdgeCW2 = ot.GetConstrainedEdgeCW(op);
bool delaunayEdgeCCW = t.GetDelaunayEdgeCCW(p);
bool delaunayEdgeCW = t.GetDelaunayEdgeCW(p);
bool delaunayEdgeCCW2 = ot.GetDelaunayEdgeCCW(op);
bool delaunayEdgeCW2 = ot.GetDelaunayEdgeCW(op);
t.Legalize(p, op);
ot.Legalize(op, p);
ot.SetDelaunayEdgeCCW(p, delaunayEdgeCCW);
t.SetDelaunayEdgeCW(p, delaunayEdgeCW);
t.SetDelaunayEdgeCCW(op, delaunayEdgeCCW2);
ot.SetDelaunayEdgeCW(op, delaunayEdgeCW2);
ot.SetConstrainedEdgeCCW(p, constrainedEdgeCCW);
t.SetConstrainedEdgeCW(p, constrainedEdgeCW);
t.SetConstrainedEdgeCCW(op, constrainedEdgeCCW2);
ot.SetConstrainedEdgeCW(op, constrainedEdgeCW2);
t.Neighbors.Clear();
ot.Neighbors.Clear();
if (delaunayTriangle != null)
{
ot.MarkNeighbor(delaunayTriangle);
}
if (delaunayTriangle2 != null)
{
t.MarkNeighbor(delaunayTriangle2);
}
if (delaunayTriangle3 != null)
{
t.MarkNeighbor(delaunayTriangle3);
}
if (delaunayTriangle4 != null)
{
ot.MarkNeighbor(delaunayTriangle4);
}
t.MarkNeighbor(ot);
}
// Token: 0x04000017 RID: 23
private const double PI_div2 = 1.5707963267948966;
// Token: 0x04000018 RID: 24
private const double PI_3div4 = 2.356194490192345;
}
}