feat: Initial commit

This commit is contained in:
2025-02-14 16:06:00 +08:00
commit da75a84e02
1056 changed files with 163517 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 24f46f7445d706343b6a44b48a6504cf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,447 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// Changes from the Java version
/// attributification
/// Future possibilities
/// Flattening out the number of indirections
/// Replacing arrays of 3 with fixed-length arrays?
/// Replacing bool[3] with a bit array of some sort?
/// Bundling everything into an AoS mess?
/// Hardcode them all as ABC ?
using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace Poly2Tri
{
public class DelaunayTriangle
{
public FixedArray3<TriangulationPoint> Points;
public FixedArray3<DelaunayTriangle> Neighbors;
private FixedBitArray3 mEdgeIsConstrained;
public FixedBitArray3 EdgeIsConstrained { get { return mEdgeIsConstrained; } }
public FixedBitArray3 EdgeIsDelaunay;
public bool IsInterior { get; set; }
public DelaunayTriangle(TriangulationPoint p1, TriangulationPoint p2, TriangulationPoint p3)
{
Points[0] = p1;
Points[1] = p2;
Points[2] = p3;
}
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 int IndexCWFrom(TriangulationPoint p)
{
return (IndexOf(p) + 2) % 3;
}
public int IndexCCWFrom(TriangulationPoint p)
{
return (IndexOf(p) + 1) % 3;
}
public bool Contains(TriangulationPoint p)
{
return Points.Contains(p);
}
/// <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;
}
/// <summary>
/// Exhaustive search to update neighbor pointers
/// </summary>
public void MarkNeighbor(DelaunayTriangle t)
{
// Points of this triangle also belonging to t
bool a = t.Contains(Points[0]);
bool b = t.Contains(Points[1]);
bool c = t.Contains(Points[2]);
if (b && c)
{
Neighbors[0] = t;
t.MarkNeighbor(Points[1], Points[2], this);
}
else if (a && c)
{
Neighbors[1] = t;
t.MarkNeighbor(Points[0], Points[2], this);
}
else if (a && b)
{
Neighbors[2] = t;
t.MarkNeighbor(Points[0], Points[1], this);
}
else
{
throw new Exception("Failed to mark neighbor, doesn't share an edge!");
}
}
public void ClearNeighbors()
{
Neighbors[0] = Neighbors[1] = Neighbors[2] = null;
}
public void ClearNeighbor(DelaunayTriangle triangle)
{
if (Neighbors[0] == triangle)
{
Neighbors[0] = null;
}
else if (Neighbors[1] == triangle)
{
Neighbors[1] = null;
}
else if( Neighbors[2] == triangle)
{
Neighbors[2] = null;
}
}
/// <summary>
/// Clears all references to all other triangles and points
/// </summary>
public void Clear()
{
DelaunayTriangle t;
for (int i = 0; i < 3; i++)
{
t = Neighbors[i];
if (t != null)
{
t.ClearNeighbor(this);
}
}
ClearNeighbors();
Points[0] = Points[1] = Points[2] = null;
}
/// <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 DelaunayTriangle NeighborCWFrom(TriangulationPoint point)
{
return Neighbors[(Points.IndexOf(point) + 1) % 3];
}
public DelaunayTriangle NeighborCCWFrom(TriangulationPoint point)
{
return Neighbors[(Points.IndexOf(point) + 2) % 3];
}
public DelaunayTriangle NeighborAcrossFrom(TriangulationPoint point)
{
return Neighbors[Points.IndexOf(point)];
}
public TriangulationPoint PointCCWFrom(TriangulationPoint point)
{
return Points[(IndexOf(point) + 1) % 3];
}
public TriangulationPoint PointCWFrom(TriangulationPoint point)
{
return Points[(IndexOf(point) + 2) % 3];
}
private void RotateCW()
{
var t = Points[2];
Points[2] = Points[1];
Points[1] = Points[0];
Points[0] = t;
}
/// <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;
}
public override string ToString()
{
return Points[0] + "," + Points[1] + "," + Points[2];
}
/// <summary>
/// Finalize edge marking
/// </summary>
public void MarkNeighborEdges()
{
for (int i = 0; i < 3; i++)
{
if (EdgeIsConstrained[i] && Neighbors[i] != null)
{
Neighbors[i].MarkConstrainedEdge(Points[(i + 1) % 3], Points[(i + 2) % 3]);
}
}
}
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]);
}
}
public void MarkEdge(List<DelaunayTriangle> tList)
{
foreach (DelaunayTriangle t in tList)
{
for (int i = 0; i < 3; i++)
{
if (t.EdgeIsConstrained[i])
{
MarkConstrainedEdge(t.Points[(i + 1) % 3], t.Points[(i + 2) % 3]);
}
}
}
}
public void MarkConstrainedEdge(int index)
{
mEdgeIsConstrained[index] = true;
}
public void MarkConstrainedEdge(DTSweepConstraint edge)
{
MarkConstrainedEdge(edge.P, edge.Q);
}
/// <summary>
/// Mark edge as constrained
/// </summary>
public void MarkConstrainedEdge(TriangulationPoint p, TriangulationPoint q)
{
int i = EdgeIndex(p, q);
if (i != -1)
{
mEdgeIsConstrained[i] = true;
}
}
public double Area()
{
double b = Points[0].X - Points[1].X;
double h = Points[2].Y - Points[1].Y;
return Math.Abs((b * h * 0.5f));
}
public TriangulationPoint Centroid()
{
double cx = (Points[0].X + Points[1].X + Points[2].X) / 3f;
double cy = (Points[0].Y + Points[1].Y + Points[2].Y) / 3f;
return new TriangulationPoint(cx, cy);
}
/// <summary>
/// Get the index of the neighbor that shares this edge (or -1 if it isn't shared)
/// </summary>
/// <returns>index of the shared edge or -1 if edge isn't shared</returns>
public int EdgeIndex(TriangulationPoint p1, TriangulationPoint p2)
{
int i1 = Points.IndexOf(p1);
int i2 = Points.IndexOf(p2);
// Points of this triangle in the edge p1-p2
bool a = (i1 == 0 || i2 == 0);
bool b = (i1 == 1 || i2 == 1);
bool c = (i1 == 2 || i2 == 2);
if (b && c)
{
return 0;
}
if (a && c)
{
return 1;
}
if (a && b)
{
return 2;
}
return -1;
}
public bool GetConstrainedEdgeCCW(TriangulationPoint p) { return EdgeIsConstrained[(IndexOf(p) + 2) % 3]; }
public bool GetConstrainedEdgeCW(TriangulationPoint p) { return EdgeIsConstrained[(IndexOf(p) + 1) % 3]; }
public bool GetConstrainedEdgeAcross(TriangulationPoint p) { return EdgeIsConstrained[IndexOf(p)]; }
protected void SetConstrainedEdge(int idx, bool ce)
{
//if (ce == false && EdgeIsConstrained[idx])
//{
// DTSweepConstraint edge = null;
// if (GetEdge(idx, out edge))
// {
// Console.WriteLine("Removing pre-defined constraint from edge " + edge.ToString());
// }
//}
mEdgeIsConstrained[idx] = ce;
}
public void SetConstrainedEdgeCCW(TriangulationPoint p, bool ce)
{
int idx = (IndexOf(p) + 2) % 3;
SetConstrainedEdge(idx, ce);
}
public void SetConstrainedEdgeCW(TriangulationPoint p, bool ce)
{
int idx = (IndexOf(p) + 1) % 3;
SetConstrainedEdge(idx, ce);
}
public void SetConstrainedEdgeAcross(TriangulationPoint p, bool ce)
{
int idx = IndexOf(p);
SetConstrainedEdge(idx, ce);
}
public bool GetDelaunayEdgeCCW(TriangulationPoint p) { return EdgeIsDelaunay[(IndexOf(p) + 2) % 3]; }
public bool GetDelaunayEdgeCW(TriangulationPoint p) { return EdgeIsDelaunay[(IndexOf(p) + 1) % 3]; }
public bool GetDelaunayEdgeAcross(TriangulationPoint p) { return EdgeIsDelaunay[IndexOf(p)]; }
public void SetDelaunayEdgeCCW(TriangulationPoint p, bool ce) { EdgeIsDelaunay[(IndexOf(p) + 2) % 3] = ce; }
public void SetDelaunayEdgeCW(TriangulationPoint p, bool ce) { EdgeIsDelaunay[(IndexOf(p) + 1) % 3] = ce; }
public void SetDelaunayEdgeAcross(TriangulationPoint p, bool ce) { EdgeIsDelaunay[IndexOf(p)] = ce; }
public bool GetEdge(int idx, out DTSweepConstraint edge)
{
edge = null;
if (idx < 0 || idx > 2)
{
return false;
}
TriangulationPoint p1 = Points[(idx + 1) % 3];
TriangulationPoint p2 = Points[(idx + 2) % 3];
if (p1.GetEdge(p2, out edge))
{
return true;
}
else if (p2.GetEdge(p1, out edge))
{
return true;
}
return false;
}
public bool GetEdgeCCW(TriangulationPoint p, out DTSweepConstraint edge)
{
int pointIndex = IndexOf(p);
int edgeIdx = (pointIndex + 2)%3;
return GetEdge(edgeIdx, out edge);
}
public bool GetEdgeCW(TriangulationPoint p, out DTSweepConstraint edge)
{
int pointIndex = IndexOf(p);
int edgeIdx = (pointIndex + 1) % 3;
return GetEdge(edgeIdx, out edge);
}
public bool GetEdgeAcross(TriangulationPoint p, out DTSweepConstraint edge)
{
int pointIndex = IndexOf(p);
int edgeIdx = pointIndex;
return GetEdge(edgeIdx, out edge);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8b61ca8480a824b4eab0f5a7c6587932
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ca0c831d398dcf043875b7e514c4f9ee
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,177 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// Changes from the Java version
/// Removed BST code, but not all artifacts of it
/// Future possibilities
/// Eliminate Add/RemoveNode ?
/// Comments comments and more comments!
using System.Text;
using System;
namespace Poly2Tri
{
/**
* @author Thomas Åhlen (thahlen@gmail.com)
*/
public class AdvancingFront
{
public AdvancingFrontNode Head;
public AdvancingFrontNode Tail;
protected AdvancingFrontNode Search;
public AdvancingFront(AdvancingFrontNode head, AdvancingFrontNode tail)
{
this.Head = head;
this.Tail = tail;
this.Search = head;
AddNode(head);
AddNode(tail);
}
public void AddNode(AdvancingFrontNode node) { }
public void RemoveNode(AdvancingFrontNode node) { }
public override string ToString()
{
StringBuilder sb = new StringBuilder();
AdvancingFrontNode node = Head;
while (node != Tail)
{
sb.Append(node.Point.X).Append("->");
node = node.Next;
}
sb.Append(Tail.Point.X);
return sb.ToString();
}
/// <summary>
/// MM: This seems to be used by LocateNode to guess a position in the implicit linked list of AdvancingFrontNodes near x
/// Removed an overload that depended on this being exact
/// </summary>
private AdvancingFrontNode FindSearchNode(double x)
{
return Search;
}
/// <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);
}
private AdvancingFrontNode LocateNode(double x)
{
AdvancingFrontNode node = FindSearchNode(x);
if (x < node.Value)
{
while ((node = node.Prev) != null)
{
if (x >= node.Value)
{
Search = node;
return node;
}
}
}
else
{
while ((node = node.Next) != null)
{
if (x < node.Value)
{
Search = node.Prev;
return node.Prev;
}
}
}
return null;
}
/// <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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bba5ad2e582edd14a9b9f4c2269e83e2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,57 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// Changes from the Java version
/// Removed getters
/// Has* turned into attributes
/// Future possibilities
/// Comments!
namespace Poly2Tri
{
public class AdvancingFrontNode
{
public AdvancingFrontNode Next;
public AdvancingFrontNode Prev;
public double Value;
public TriangulationPoint Point;
public DelaunayTriangle Triangle;
public AdvancingFrontNode(TriangulationPoint point)
{
this.Point = point;
Value = point.X;
}
public bool HasNext { get { return Next != null; } }
public bool HasPrev { get { return Prev != null; } }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0f50404d2892ffc42b70043a773f577f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 18835840dca416041bff74eaaf5dcc47
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Poly2Tri
{
public class DTSweepBasin
{
public AdvancingFrontNode leftNode;
public AdvancingFrontNode bottomNode;
public AdvancingFrontNode rightNode;
public double width;
public bool leftHighest;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 295b5899a6bed9d4187f6a49c293fc2f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
//using System.Collections.Generic;
using System.Diagnostics;
//using System.Linq;
namespace Poly2Tri
{
public class DTSweepConstraint : TriangulationConstraint
{
/// <summary>
/// Give two points in any order. Will always be ordered so
/// that q.y > p.y and q.x > p.x if same y value
/// </summary>
public DTSweepConstraint(TriangulationPoint p1, TriangulationPoint p2)
: base(p1, p2)
{
Q.AddEdge(this);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 24c139533abc53242a5fda851aed1f90
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,252 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Poly2Tri
{
/**
*
* @author Thomas Åhlén, thahlen@gmail.com
*
*/
public class DTSweepContext : TriangulationContext
{
// Inital triangle factor, seed triangle will extend 30% of
// PointSet width to both left and right.
private readonly float ALPHA = 0.3f;
public AdvancingFront Front;
public TriangulationPoint Head { get; set; }
public TriangulationPoint Tail { get; set; }
public DTSweepBasin Basin = new DTSweepBasin();
public DTSweepEdgeEvent EdgeEvent = new DTSweepEdgeEvent();
private DTSweepPointComparator _comparator = new DTSweepPointComparator();
public override TriangulationAlgorithm Algorithm { get { return TriangulationAlgorithm.DTSweep; } }
public DTSweepContext()
{
Clear();
}
public override bool IsDebugEnabled
{
get
{
return base.IsDebugEnabled;
}
protected set
{
if (value && DebugContext == null)
{
DebugContext = new DTSweepDebugContext(this);
}
base.IsDebugEnabled = value;
}
}
public void RemoveFromList(DelaunayTriangle triangle)
{
Triangles.Remove(triangle);
// TODO: remove all neighbor pointers to this triangle
// for( int i=0; i<3; i++ )
// {
// if( triangle.neighbors[i] != null )
// {
// triangle.neighbors[i].clearNeighbor( triangle );
// }
// }
// triangle.clearNeighbors();
}
public void MeshClean(DelaunayTriangle triangle)
{
MeshCleanReq(triangle);
}
private void MeshCleanReq(DelaunayTriangle triangle)
{
if (triangle != null && !triangle.IsInterior)
{
triangle.IsInterior = true;
Triangulatable.AddTriangle(triangle);
for (int i = 0; i < 3; i++)
{
if (!triangle.EdgeIsConstrained[i])
{
MeshCleanReq(triangle.Neighbors[i]);
}
}
}
}
public override void Clear()
{
base.Clear();
Triangles.Clear();
}
public void AddNode(AdvancingFrontNode node)
{
// Console.WriteLine( "add:" + node.key + ":" + System.identityHashCode(node.key));
// m_nodeTree.put( node.getKey(), node );
Front.AddNode(node);
}
public void RemoveNode(AdvancingFrontNode node)
{
// Console.WriteLine( "remove:" + node.key + ":" + System.identityHashCode(node.key));
// m_nodeTree.delete( node.getKey() );
Front.RemoveNode(node);
}
public AdvancingFrontNode LocateNode(TriangulationPoint point)
{
return Front.LocateNode(point);
}
public void CreateAdvancingFront()
{
AdvancingFrontNode head, tail, middle;
// Initial triangle
DelaunayTriangle iTriangle = new DelaunayTriangle(Points[0], Tail, Head);
Triangles.Add(iTriangle);
head = new AdvancingFrontNode(iTriangle.Points[1]);
head.Triangle = iTriangle;
middle = new AdvancingFrontNode(iTriangle.Points[0]);
middle.Triangle = iTriangle;
tail = new AdvancingFrontNode(iTriangle.Points[2]);
Front = new AdvancingFront(head, tail);
Front.AddNode(middle);
// TODO: I think it would be more intuitive if head is middles next and not previous
// so swap head and tail
Front.Head.Next = middle;
middle.Next = Front.Tail;
middle.Prev = Front.Head;
Front.Tail.Prev = middle;
}
/// <summary>
/// Try to map a node to all sides of this triangle that don't have
/// a neighbor.
/// </summary>
public void MapTriangleToNodes(DelaunayTriangle t)
{
for (int i = 0; i < 3; i++)
{
if (t.Neighbors[i] == null)
{
AdvancingFrontNode n = Front.LocatePoint(t.PointCWFrom(t.Points[i]));
if (n != null)
{
n.Triangle = t;
}
}
}
}
public override void PrepareTriangulation(ITriangulatable t)
{
base.PrepareTriangulation(t);
double xmax, xmin;
double ymax, ymin;
xmax = xmin = Points[0].X;
ymax = ymin = Points[0].Y;
// Calculate bounds. Should be combined with the sorting
foreach (TriangulationPoint p in Points)
{
if (p.X > xmax)
{
xmax = p.X;
}
if (p.X < xmin)
{
xmin = p.X;
}
if (p.Y > ymax)
{
ymax = p.Y;
}
if (p.Y < ymin)
{
ymin = p.Y;
}
}
double deltaX = ALPHA * (xmax - xmin);
double deltaY = ALPHA * (ymax - ymin);
TriangulationPoint p1 = new TriangulationPoint(xmax + deltaX, ymin - deltaY);
TriangulationPoint p2 = new TriangulationPoint(xmin - deltaX, ymin - deltaY);
Head = p1;
Tail = p2;
// long time = System.nanoTime();
// Sort the points along y-axis
Points.Sort(_comparator);
// logger.info( "Triangulation setup [{}ms]", ( System.nanoTime() - time ) / 1e6 );
}
public void FinalizeTriangulation()
{
Triangulatable.AddTriangles(Triangles);
Triangles.Clear();
}
public override TriangulationConstraint NewConstraint(TriangulationPoint a, TriangulationPoint b)
{
return new DTSweepConstraint(a, b);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5ee2e0932fff59f429c452bba590cf83
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Poly2Tri
{
public class DTSweepDebugContext : TriangulationDebugContext
{
/*
* Fields used for visual representation of current triangulation
*/
public DelaunayTriangle PrimaryTriangle { get { return _primaryTriangle; } set { _primaryTriangle = value; _tcx.Update("set PrimaryTriangle"); } }
public DelaunayTriangle SecondaryTriangle { get { return _secondaryTriangle; } set { _secondaryTriangle = value; _tcx.Update("set SecondaryTriangle"); } }
public TriangulationPoint ActivePoint { get { return _activePoint; } set { _activePoint = value; _tcx.Update("set ActivePoint"); } }
public AdvancingFrontNode ActiveNode { get { return _activeNode; } set { _activeNode = value; _tcx.Update("set ActiveNode"); } }
public DTSweepConstraint ActiveConstraint { get { return _activeConstraint; } set { _activeConstraint = value; _tcx.Update("set ActiveConstraint"); } }
public DTSweepDebugContext(DTSweepContext tcx) : base(tcx) { }
public bool IsDebugContext { get { return true; } }
public override void Clear()
{
PrimaryTriangle = null;
SecondaryTriangle = null;
ActivePoint = null;
ActiveNode = null;
ActiveConstraint = null;
}
private DelaunayTriangle _primaryTriangle;
private DelaunayTriangle _secondaryTriangle;
private TriangulationPoint _activePoint;
private AdvancingFrontNode _activeNode;
private DTSweepConstraint _activeConstraint;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c80776e6f580608498870e9ba0c7fdca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// Changes from the Java version
/// Turned DTSweepEdgeEvent into a value type
namespace Poly2Tri
{
public class DTSweepEdgeEvent
{
public DTSweepConstraint ConstrainedEdge;
public bool Right;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3c7810b370713bb4985dfa014259efbc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
namespace Poly2Tri
{
public class DTSweepPointComparator : IComparer<TriangulationPoint>
{
public int Compare(TriangulationPoint p1, TriangulationPoint p2)
{
if (p1.Y < p2.Y)
{
return -1;
}
else if (p1.Y > p2.Y)
{
return 1;
}
else
{
if (p1.X < p2.X)
{
return -1;
}
else if (p1.X > p2.X)
{
return 1;
}
else
{
return 0;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dfb17679c246e5f4fa5a535f717d47d5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
namespace Poly2Tri
{
public class PointOnEdgeException : NotImplementedException
{
public readonly TriangulationPoint A, B, C;
public PointOnEdgeException(string message, TriangulationPoint a, TriangulationPoint b, TriangulationPoint c)
: base(message)
{
A = a;
B = b;
C = c;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a6f5e106faca1c442a1def9a56695eac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,57 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
namespace Poly2Tri
{
public interface ITriangulatable
{
//IList<TriangulationPoint> Points { get; } // MM: Neither of these are used via interface (yet?)
IList<DelaunayTriangle> Triangles { get; }
TriangulationMode TriangulationMode { get; }
string FileName { get; set; }
bool DisplayFlipX { get; set; }
bool DisplayFlipY { get; set; }
float DisplayRotate { get; set; }
double Precision { get; set; }
double MinX { get; }
double MaxX { get; }
double MinY { get; }
double MaxY { get; }
Rect2D Bounds { get; }
void Prepare(TriangulationContext tcx);
void AddTriangle(DelaunayTriangle t);
void AddTriangles(IEnumerable<DelaunayTriangle> list);
void ClearTriangles();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 75ea7f139cb97ce4c8150e06934491d7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Poly2Tri
{
public enum Orientation
{
CW,
CCW,
Collinear
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f53cc2457ddb3dd4c82e5b3eb98327c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 30e3877e8ca306440ac44dfc20462e1d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,577 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Poly2Tri
{
/// <summary>
/// This is basically a light-weight version of the Polygon class, but with limited functionality and
/// used for different purposes. Nonetheless, for all intents and purposes, this should actually be
/// a polygon (though not a Polygon..)
/// </summary>
public class Contour : Point2DList, ITriangulatable, IEnumerable<TriangulationPoint>, IList<TriangulationPoint>
{
private List<Contour> mHoles = new List<Contour>();
private ITriangulatable mParent = null;
private string mName = "";
public new TriangulationPoint this[int index]
{
get { return mPoints[index] as TriangulationPoint; }
set { mPoints[index] = value; }
}
public string Name { get { return mName; } set { mName = value; } }
public IList<DelaunayTriangle> Triangles
{
get
{
throw new NotImplementedException("PolyHole.Triangles should never get called");
}
private set { }
}
public TriangulationMode TriangulationMode { get { return mParent.TriangulationMode; } }
public string FileName { get { return mParent.FileName; } set { } }
public bool DisplayFlipX { get { return mParent.DisplayFlipX; } set { } }
public bool DisplayFlipY { get { return mParent.DisplayFlipY; } set { } }
public float DisplayRotate { get { return mParent.DisplayRotate; } set { } }
public double Precision { get { return mParent.Precision; } set { } }
public double MinX { get { return mBoundingBox.MinX; } }
public double MaxX { get { return mBoundingBox.MaxX; } }
public double MinY { get { return mBoundingBox.MinY; } }
public double MaxY { get { return mBoundingBox.MaxY; } }
public Rect2D Bounds { get { return mBoundingBox; } }
public Contour(ITriangulatable parent)
{
mParent = parent;
}
public Contour(ITriangulatable parent, IList<TriangulationPoint> points, Point2DList.WindingOrderType windingOrder)
{
// Currently assumes that input is pre-checked for validity
mParent = parent;
AddRange(points, windingOrder);
}
public override string ToString()
{
return mName + " : " + base.ToString();
}
IEnumerator<TriangulationPoint> IEnumerable<TriangulationPoint>.GetEnumerator()
{
return new TriangulationPointEnumerator(mPoints);
}
public int IndexOf(TriangulationPoint p)
{
return mPoints.IndexOf(p);
}
public void Add(TriangulationPoint p)
{
Add(p, -1, true);
}
protected override void Add(Point2D p, int idx, bool bCalcWindingOrderAndEpsilon)
{
TriangulationPoint pt = null;
if (p is TriangulationPoint)
{
pt = p as TriangulationPoint;
}
else
{
pt = new TriangulationPoint(p.X, p.Y);
}
if (idx < 0)
{
mPoints.Add(pt);
}
else
{
mPoints.Insert(idx, pt);
}
mBoundingBox.AddPoint(pt);
if (bCalcWindingOrderAndEpsilon)
{
if (mWindingOrder == WindingOrderType.Unknown)
{
mWindingOrder = CalculateWindingOrder();
}
mEpsilon = CalculateEpsilon();
}
}
public override void AddRange(IEnumerator<Point2D> iter, WindingOrderType windingOrder)
{
if (iter == null)
{
return;
}
if (mWindingOrder == WindingOrderType.Unknown && Count == 0)
{
mWindingOrder = windingOrder;
}
bool bReverseReadOrder = (WindingOrder != WindingOrderType.Unknown) && (windingOrder != WindingOrderType.Unknown) && (WindingOrder != windingOrder);
bool bAddedFirst = true;
int startCount = mPoints.Count;
iter.Reset();
while (iter.MoveNext())
{
TriangulationPoint pt = null;
if (iter.Current is TriangulationPoint)
{
pt = iter.Current as TriangulationPoint;
}
else
{
pt = new TriangulationPoint(iter.Current.X, iter.Current.Y);
}
if (!bAddedFirst)
{
bAddedFirst = true;
mPoints.Add(pt);
}
else if (bReverseReadOrder)
{
mPoints.Insert(startCount, pt);
}
else
{
mPoints.Add(pt);
}
mBoundingBox.AddPoint(iter.Current);
}
if (mWindingOrder == WindingOrderType.Unknown && windingOrder == WindingOrderType.Unknown)
{
mWindingOrder = CalculateWindingOrder();
}
mEpsilon = CalculateEpsilon();
}
public void AddRange(IList<TriangulationPoint> points, Point2DList.WindingOrderType windingOrder)
{
if (points == null || points.Count < 1)
{
return;
}
if (mWindingOrder == Point2DList.WindingOrderType.Unknown && Count == 0)
{
mWindingOrder = windingOrder;
}
int numPoints = points.Count;
bool bReverseReadOrder = (WindingOrder != WindingOrderType.Unknown) && (windingOrder != WindingOrderType.Unknown) && (WindingOrder != windingOrder);
for (int i = 0; i < numPoints; ++i)
{
int idx = i;
if (bReverseReadOrder)
{
idx = points.Count - i - 1;
}
Add(points[idx], -1, false);
}
if (mWindingOrder == WindingOrderType.Unknown)
{
mWindingOrder = CalculateWindingOrder();
}
mEpsilon = CalculateEpsilon();
}
public void Insert(int idx, TriangulationPoint p)
{
Add(p, idx, true);
}
public bool Remove(TriangulationPoint p)
{
return Remove(p as Point2D);
}
public bool Contains(TriangulationPoint p)
{
return mPoints.Contains(p);
}
public void CopyTo(TriangulationPoint[] array, int arrayIndex)
{
int numElementsToCopy = Math.Min(Count, array.Length - arrayIndex);
for (int i = 0; i < numElementsToCopy; ++i)
{
array[arrayIndex + i] = mPoints[i] as TriangulationPoint;
}
}
protected void AddHole(Contour c)
{
// no checking is done here as we rely on InitializeHoles for that
c.mParent = this;
mHoles.Add(c);
}
/// <summary>
/// returns number of holes that are actually holes, including all children of children, etc. Does NOT
/// include holes that are not actually holes. For example, if the parent is not a hole and this contour has
/// a hole that contains a hole, then the number of holes returned would be 2 - one for the current hole (because
/// the parent is NOT a hole and thus this hole IS a hole), and 1 for the child of the child.
/// </summary>
/// <param name="parentIsHole"></param>
/// <returns></returns>
public int GetNumHoles(bool parentIsHole)
{
int numHoles = parentIsHole ? 0 : 1;
foreach (Contour c in mHoles)
{
numHoles += c.GetNumHoles(!parentIsHole);
}
return numHoles;
}
/// <summary>
/// returns the basic number of child holes of THIS contour, not including any children of children, etc nor
/// examining whether any children are actual holes.
/// </summary>
/// <returns></returns>
public int GetNumHoles()
{
return mHoles.Count;
}
public Contour GetHole(int idx)
{
if (idx < 0 || idx >= mHoles.Count)
{
return null;
}
return mHoles[idx];
}
public void GetActualHoles(bool parentIsHole, ref List<Contour> holes)
{
if (parentIsHole)
{
holes.Add(this);
}
foreach (Contour c in mHoles)
{
c.GetActualHoles(!parentIsHole, ref holes);
}
}
public List<Contour>.Enumerator GetHoleEnumerator()
{
return mHoles.GetEnumerator();
}
public void InitializeHoles(ConstrainedPointSet cps)
{
Contour.InitializeHoles(mHoles, this, cps);
foreach (Contour c in mHoles)
{
c.InitializeHoles(cps);
}
}
public static void InitializeHoles(List<Contour> holes, ITriangulatable parent, ConstrainedPointSet cps)
{
int numHoles = holes.Count;
int holeIdx = 0;
// pass 1 - remove duplicates
while (holeIdx < numHoles)
{
int hole2Idx = holeIdx + 1;
while (hole2Idx < numHoles)
{
bool bSamePolygon = PolygonUtil.PolygonsAreSame2D(holes[holeIdx], holes[hole2Idx]);
if (bSamePolygon)
{
// remove one of them
holes.RemoveAt(hole2Idx);
--numHoles;
}
else
{
++hole2Idx;
}
}
++holeIdx;
}
// pass 2: Intersections and Containment
holeIdx = 0;
while (holeIdx < numHoles)
{
bool bIncrementHoleIdx = true;
int hole2Idx = holeIdx + 1;
while (hole2Idx < numHoles)
{
if (PolygonUtil.PolygonContainsPolygon(holes[holeIdx], holes[holeIdx].Bounds, holes[hole2Idx], holes[hole2Idx].Bounds, false))
{
holes[holeIdx].AddHole(holes[hole2Idx]);
holes.RemoveAt(hole2Idx);
--numHoles;
}
else if (PolygonUtil.PolygonContainsPolygon(holes[hole2Idx], holes[hole2Idx].Bounds, holes[holeIdx], holes[holeIdx].Bounds, false))
{
holes[hole2Idx].AddHole(holes[holeIdx]);
holes.RemoveAt(holeIdx);
--numHoles;
bIncrementHoleIdx = false;
break;
}
else
{
bool bIntersect = PolygonUtil.PolygonsIntersect2D(holes[holeIdx], holes[holeIdx].Bounds, holes[hole2Idx], holes[hole2Idx].Bounds);
if (bIntersect)
{
// this is actually an error condition
// fix by merging hole1 and hole2 into hole1 (including the holes inside hole2!) and delete hole2
// Then, because hole1 is now changed, restart it's check.
PolygonOperationContext ctx = new PolygonOperationContext();
if (!ctx.Init(PolygonUtil.PolyOperation.Union | PolygonUtil.PolyOperation.Intersect, holes[holeIdx], holes[hole2Idx]))
{
if (ctx.mError == PolygonUtil.PolyUnionError.Poly1InsidePoly2)
{
holes[hole2Idx].AddHole(holes[holeIdx]);
holes.RemoveAt(holeIdx);
--numHoles;
bIncrementHoleIdx = false;
break;
}
else
{
throw new Exception("PolygonOperationContext.Init had an error during initialization");
}
}
PolygonUtil.PolyUnionError pue = PolygonUtil.PolygonOperation(ctx);
if (pue == PolygonUtil.PolyUnionError.None)
{
Point2DList union = ctx.Union;
Point2DList intersection = ctx.Intersect;
// create a new contour for the union
Contour c = new Contour(parent);
c.AddRange(union);
c.Name = "(" + holes[holeIdx].Name + " UNION " + holes[hole2Idx].Name + ")";
c.WindingOrder = Point2DList.WindingOrderType.Default;
// add children from both of the merged contours
int numChildHoles = holes[holeIdx].GetNumHoles();
for(int i = 0; i < numChildHoles; ++i)
{
c.AddHole(holes[holeIdx].GetHole(i));
}
numChildHoles = holes[hole2Idx].GetNumHoles();
for (int i = 0; i < numChildHoles; ++i)
{
c.AddHole(holes[hole2Idx].GetHole(i));
}
// make sure we preserve the contours of the intersection
Contour cInt = new Contour(c);
cInt.AddRange(intersection);
cInt.Name = "(" + holes[holeIdx].Name + " INTERSECT " + holes[hole2Idx].Name + ")";
cInt.WindingOrder = Point2DList.WindingOrderType.Default;
c.AddHole(cInt);
// replace the current contour with the merged contour
holes[holeIdx] = c;
// toss the second contour
holes.RemoveAt(hole2Idx);
--numHoles;
// current hole is "examined", so move to the next one
hole2Idx = holeIdx + 1;
}
else
{
throw new Exception("PolygonOperation had an error!");
}
}
else
{
++hole2Idx;
}
}
}
if (bIncrementHoleIdx)
{
++holeIdx;
}
}
numHoles = holes.Count;
holeIdx = 0;
while (holeIdx < numHoles)
{
int numPoints = holes[holeIdx].Count;
for (int i = 0; i < numPoints; ++i)
{
int j = holes[holeIdx].NextIndex(i);
uint constraintCode = TriangulationConstraint.CalculateContraintCode(holes[holeIdx][i], holes[holeIdx][j]);
TriangulationConstraint tc = null;
if (!cps.TryGetConstraint(constraintCode, out tc))
{
tc = new TriangulationConstraint(holes[holeIdx][i], holes[holeIdx][j]);
cps.AddConstraint(tc);
}
// replace the points in the holes with valid points
if (holes[holeIdx][i].VertexCode == tc.P.VertexCode)
{
holes[holeIdx][i] = tc.P;
}
else if (holes[holeIdx][j].VertexCode == tc.P.VertexCode)
{
holes[holeIdx][j] = tc.P;
}
if (holes[holeIdx][i].VertexCode == tc.Q.VertexCode)
{
holes[holeIdx][i] = tc.Q;
}
else if (holes[holeIdx][j].VertexCode == tc.Q.VertexCode)
{
holes[holeIdx][j] = tc.Q;
}
}
++holeIdx;
}
}
public void Prepare(TriangulationContext tcx)
{
throw new NotImplementedException("PolyHole.Prepare should never get called");
}
public void AddTriangle(DelaunayTriangle t)
{
throw new NotImplementedException("PolyHole.AddTriangle should never get called");
}
public void AddTriangles(IEnumerable<DelaunayTriangle> list)
{
throw new NotImplementedException("PolyHole.AddTriangles should never get called");
}
public void ClearTriangles()
{
throw new NotImplementedException("PolyHole.ClearTriangles should never get called");
}
public Point2D FindPointInContour()
{
if (Count < 3)
{
return null;
}
// first try the simple approach:
Point2D p = GetCentroid();
if (IsPointInsideContour(p))
{
return p;
}
// brute force it...
Random random = new Random();
while (true)
{
p.X = (random.NextDouble() * (MaxX - MinX)) + MinX;
p.Y = (random.NextDouble() * (MaxY - MinY)) + MinY;
if (IsPointInsideContour(p))
{
return p;
}
}
}
public bool IsPointInsideContour(Point2D p)
{
if (PolygonUtil.PointInPolygon2D(this, p))
{
foreach (Contour c in mHoles)
{
if (c.IsPointInsideContour(p))
{
return false;
}
}
return true;
}
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5dfd11dff63cdeb4f8543c5ee276d3f9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,409 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// Changes from the Java version
/// Polygon constructors sprused up, checks for 3+ polys
/// Naming of everything
/// getTriangulationMode() -> TriangulationMode { get; }
/// Exceptions replaced
/// Future possibilities
/// We have a lot of Add/Clear methods -- we may prefer to just expose the container
/// Some self-explanatory methods may deserve commenting anyways
using System;
using System.Collections.Generic;
using System.Linq;
namespace Poly2Tri
{
public class Polygon : Point2DList, ITriangulatable, IEnumerable<TriangulationPoint>, IList<TriangulationPoint>
{
// ITriangulatable Implementation
protected Dictionary<uint, TriangulationPoint> mPointMap = new Dictionary<uint, TriangulationPoint>();
public IList<TriangulationPoint> Points { get { return this; } }
protected List<DelaunayTriangle> mTriangles;
public IList<DelaunayTriangle> Triangles { get { return mTriangles; } }
public TriangulationMode TriangulationMode { get { return TriangulationMode.Polygon; } }
public string FileName { get; set; }
public bool DisplayFlipX { get; set; }
public bool DisplayFlipY { get; set; }
public float DisplayRotate { get; set; }
private double mPrecision = TriangulationPoint.kVertexCodeDefaultPrecision;
public double Precision { get { return mPrecision; } set { mPrecision = value; } }
public double MinX { get { return mBoundingBox.MinX; } }
public double MaxX { get { return mBoundingBox.MaxX; } }
public double MinY { get { return mBoundingBox.MinY; } }
public double MaxY { get { return mBoundingBox.MaxY; } }
public Rect2D Bounds { get { return mBoundingBox; } }
// Point2DList overrides
public new TriangulationPoint this[int index]
{
get { return mPoints[index] as TriangulationPoint; }
set { mPoints[index] = value; }
}
// Polygon Implementation
protected List<Polygon> mHoles;
public IList<Polygon> Holes { get { return mHoles; } }
protected List<TriangulationPoint> mSteinerPoints;
protected PolygonPoint _last;
/// <summary>
/// Create a polygon from a list of at least 3 points with no duplicates.
/// </summary>
/// <param name="points">A list of unique points</param>
public Polygon(IList<PolygonPoint> points)
{
if (points.Count < 3)
{
throw new ArgumentException("List has fewer than 3 points", "points");
}
AddRange(points, WindingOrderType.Unknown);
}
/// <summary>
/// Create a polygon from a list of at least 3 points with no duplicates.
/// </summary>
/// <param name="points">A list of unique points.</param>
public Polygon(IEnumerable<PolygonPoint> points)
: this((points as IList<PolygonPoint>) ?? points.ToArray())
{}
/// <summary>
/// Create a polygon from a list of at least 3 points with no duplicates.
/// </summary>
/// <param name="points">A list of unique points.</param>
public Polygon(params PolygonPoint[] points)
: this((IList<PolygonPoint>)points)
{}
IEnumerator<TriangulationPoint> IEnumerable<TriangulationPoint>.GetEnumerator()
{
return new TriangulationPointEnumerator(mPoints);
}
public int IndexOf(TriangulationPoint p)
{
return mPoints.IndexOf(p);
}
public override void Add(Point2D p)
{
Add(p, -1, true);
}
public void Add(TriangulationPoint p)
{
Add(p, -1, true);
}
public void Add(PolygonPoint p)
{
Add(p, -1, true);
}
protected override void Add(Point2D p, int idx, bool bCalcWindingOrderAndEpsilon)
{
TriangulationPoint pt = p as TriangulationPoint;
if (pt == null)
{
// we only store TriangulationPoints and PolygonPoints in this class
return;
}
// do not insert duplicate points
if (mPointMap.ContainsKey(pt.VertexCode))
{
return;
}
mPointMap.Add(pt.VertexCode, pt);
base.Add(p, idx, bCalcWindingOrderAndEpsilon);
PolygonPoint pp = p as PolygonPoint;
if (pp != null)
{
pp.Previous = _last;
if (_last != null)
{
pp.Next = _last.Next;
_last.Next = pp;
}
_last = pp;
}
return;
}
public void AddRange(IList<PolygonPoint> points, Point2DList.WindingOrderType windingOrder)
{
if (points == null || points.Count < 1)
{
return;
}
if (mWindingOrder == Point2DList.WindingOrderType.Unknown && Count == 0)
{
mWindingOrder = windingOrder;
}
int numPoints = points.Count;
bool bReverseReadOrder = (WindingOrder != WindingOrderType.Unknown) && (windingOrder != WindingOrderType.Unknown) && (WindingOrder != windingOrder);
for (int i = 0; i < numPoints; ++i)
{
int idx = i;
if (bReverseReadOrder)
{
idx = points.Count - i - 1;
}
Add(points[idx], -1, false);
}
if (mWindingOrder == WindingOrderType.Unknown)
{
mWindingOrder = CalculateWindingOrder();
}
mEpsilon = CalculateEpsilon();
}
public void AddRange(IList<TriangulationPoint> points, Point2DList.WindingOrderType windingOrder)
{
if (points == null || points.Count < 1)
{
return;
}
if (mWindingOrder == Point2DList.WindingOrderType.Unknown && Count == 0)
{
mWindingOrder = windingOrder;
}
int numPoints = points.Count;
bool bReverseReadOrder = (WindingOrder != WindingOrderType.Unknown) && (windingOrder != WindingOrderType.Unknown) && (WindingOrder != windingOrder);
for (int i = 0; i < numPoints; ++i)
{
int idx = i;
if (bReverseReadOrder)
{
idx = points.Count - i - 1;
}
Add(points[idx], -1, false);
}
if (mWindingOrder == WindingOrderType.Unknown)
{
mWindingOrder = CalculateWindingOrder();
}
mEpsilon = CalculateEpsilon();
}
public void Insert(int idx, TriangulationPoint p)
{
Add(p, idx, true);
}
public bool Remove(TriangulationPoint p)
{
return base.Remove(p);
}
/// <summary>
/// Removes a point from the polygon. Note this can be a somewhat expensive operation
/// as it must recalculate the bounding area from scratch.
/// </summary>
/// <param name="p"></param>
public void RemovePoint(PolygonPoint p)
{
PolygonPoint next, prev;
next = p.Next;
prev = p.Previous;
prev.Next = next;
next.Previous = prev;
mPoints.Remove(p);
mBoundingBox.Clear();
foreach (PolygonPoint tmp in mPoints)
{
mBoundingBox.AddPoint(tmp);
}
}
public bool Contains(TriangulationPoint p)
{
return mPoints.Contains(p);
}
public void CopyTo(TriangulationPoint[] array, int arrayIndex)
{
int numElementsToCopy = Math.Min(Count, array.Length - arrayIndex);
for (int i = 0; i < numElementsToCopy; ++i)
{
array[arrayIndex + i] = mPoints[i] as TriangulationPoint;
}
}
public void AddSteinerPoint(TriangulationPoint point)
{
if (mSteinerPoints == null)
{
mSteinerPoints = new List<TriangulationPoint>();
}
mSteinerPoints.Add(point);
}
public void AddSteinerPoints(List<TriangulationPoint> points)
{
if (mSteinerPoints == null)
{
mSteinerPoints = new List<TriangulationPoint>();
}
mSteinerPoints.AddRange(points);
}
public void ClearSteinerPoints()
{
if (mSteinerPoints != null)
{
mSteinerPoints.Clear();
}
}
/// <summary>
/// Add a hole to the polygon.
/// </summary>
/// <param name="poly">A subtraction polygon fully contained inside this polygon.</param>
public void AddHole(Polygon poly)
{
if (mHoles == null)
{
mHoles = new List<Polygon>();
}
mHoles.Add(poly);
// XXX: tests could be made here to be sure it is fully inside
// addSubtraction( poly.getPoints() );
}
public void AddTriangle(DelaunayTriangle t)
{
mTriangles.Add(t);
}
public void AddTriangles(IEnumerable<DelaunayTriangle> list)
{
mTriangles.AddRange(list);
}
public void ClearTriangles()
{
if (mTriangles != null)
{
mTriangles.Clear();
}
}
public bool IsPointInside(TriangulationPoint p)
{
return PolygonUtil.PointInPolygon2D(this, p);
}
/// <summary>
/// Creates constraints and populates the context with points
/// </summary>
/// <param name="tcx">The context</param>
public void Prepare(TriangulationContext tcx)
{
if (mTriangles == null)
{
mTriangles = new List<DelaunayTriangle>(mPoints.Count);
}
else
{
mTriangles.Clear();
}
// Outer constraints
for (int i = 0; i < mPoints.Count - 1; i++)
{
//tcx.NewConstraint(mPoints[i], mPoints[i + 1]);
tcx.NewConstraint(this[i], this[i + 1]);
}
tcx.NewConstraint(this[0], this[Count - 1]);
tcx.Points.AddRange(this);
// Hole constraints
if (mHoles != null)
{
foreach (Polygon p in mHoles)
{
for (int i = 0; i < p.mPoints.Count - 1; i++)
{
tcx.NewConstraint(p[i], p[i + 1]);
}
tcx.NewConstraint(p[0], p[p.Count - 1]);
tcx.Points.AddRange(p);
}
}
if (mSteinerPoints != null)
{
tcx.Points.AddRange(mSteinerPoints);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 98daeea2e71d727429a84a799a9b1706
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// Changes from the Java version
/// Replaced get/set Next/Previous with attributes
/// Future possibilities
/// Documentation!
namespace Poly2Tri
{
public class PolygonPoint : TriangulationPoint
{
public PolygonPoint(double x, double y) : base(x, y) { }
public PolygonPoint Next { get; set; }
public PolygonPoint Previous { get; set; }
public static Point2D ToBasePoint(PolygonPoint p)
{
return (Point2D)p;
}
public static TriangulationPoint ToTriangulationPoint(PolygonPoint p)
{
return (TriangulationPoint)p;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 55fd89ec8383d3b48b01e6abebf915c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// Changes from the Java version
/// Replaced getPolygons with attribute
/// Future possibilities
/// Replace Add(Polygon) with exposed container?
/// Replace entire class with HashSet<Polygon> ?
using System.Collections.Generic;
namespace Poly2Tri
{
public class PolygonSet
{
protected List<Polygon> _polygons = new List<Polygon>();
public PolygonSet() { }
public PolygonSet(Polygon poly)
{
_polygons.Add(poly);
}
public void Add(Polygon p)
{
_polygons.Add(p);
}
public IEnumerable<Polygon> Polygons { get { return _polygons; } }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8b9b966d2e3f8d543beed734daa9b289
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3c2b8bdeed61807438a69bc54de1a423
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0fe19f49cb73334418d2abe53ddbe747
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,444 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Poly2Tri
{
/*
* Extends the PointSet by adding some Constraints on how it will be triangulated<br>
* A constraint defines an edge between two points in the set, these edges can not
* be crossed. They will be enforced triangle edges after a triangulation.
* <p>
*
*
* @author Thomas Åhlén, thahlen@gmail.com
* @author Lee Wilson, lwilson@ea.com
*/
public class ConstrainedPointSet : PointSet
{
protected Dictionary<uint, TriangulationConstraint> mConstraintMap = new Dictionary<uint, TriangulationConstraint>();
protected List<Contour> mHoles = new List<Contour>();
public override TriangulationMode TriangulationMode { get { return TriangulationMode.Constrained; } }
public ConstrainedPointSet(List<TriangulationPoint> bounds)
: base(bounds)
{
AddBoundaryConstraints();
}
public ConstrainedPointSet(List<TriangulationPoint> bounds, List<TriangulationConstraint> constraints)
: base(bounds)
{
AddBoundaryConstraints();
AddConstraints(constraints);
}
public ConstrainedPointSet(List<TriangulationPoint> bounds, int[] indices)
: base(bounds)
{
AddBoundaryConstraints();
List<TriangulationConstraint> l = new List<TriangulationConstraint>();
for (int i = 0; i < indices.Length; i += 2)
{
TriangulationConstraint tc = new TriangulationConstraint(bounds[i], bounds[i + 1]);
l.Add(tc);
}
AddConstraints(l);
}
protected void AddBoundaryConstraints()
{
TriangulationPoint ptLL = null;
TriangulationPoint ptLR = null;
TriangulationPoint ptUR = null;
TriangulationPoint ptUL = null;
if (!TryGetPoint(MinX, MinY, out ptLL))
{
ptLL = new TriangulationPoint(MinX, MinY);
Add(ptLL);
}
if (!TryGetPoint(MaxX, MinY, out ptLR))
{
ptLR = new TriangulationPoint(MaxX, MinY);
Add(ptLR);
}
if (!TryGetPoint(MaxX, MaxY, out ptUR))
{
ptUR = new TriangulationPoint(MaxX, MaxY);
Add(ptUR);
}
if (!TryGetPoint(MinX, MaxY, out ptUL))
{
ptUL = new TriangulationPoint(MinX, MaxY);
Add(ptUL);
}
TriangulationConstraint tcLLtoLR = new TriangulationConstraint(ptLL, ptLR);
AddConstraint(tcLLtoLR);
TriangulationConstraint tcLRtoUR = new TriangulationConstraint(ptLR, ptUR);
AddConstraint(tcLRtoUR);
TriangulationConstraint tcURtoUL = new TriangulationConstraint(ptUR, ptUL);
AddConstraint(tcURtoUL);
TriangulationConstraint tcULtoLL = new TriangulationConstraint(ptUL, ptLL);
AddConstraint(tcULtoLL);
}
public override void Add(Point2D p)
{
Add(p as TriangulationPoint, -1, true);
}
public override void Add(TriangulationPoint p)
{
Add(p, -1, true);
}
public override bool AddRange(List<TriangulationPoint> points)
{
bool bOK = true;
foreach (TriangulationPoint p in points)
{
bOK = Add(p, -1, true) && bOK;
}
return bOK;
}
// Assumes that points being passed in the list are connected and form a polygon.
// Note that some error checking is done for robustness, but for the most part,
// we have to rely on the user to feed us "correct" data
public bool AddHole(List<TriangulationPoint> points, string name)
{
if (points == null)
{
return false;
}
//// split our self-intersection sections into their own lists
List<Contour> pts = new List<Contour>();
int listIdx = 0;
{
Contour c = new Contour(this, points, WindingOrderType.Unknown);
pts.Add(c);
// only constrain the points if we actually HAVE a bounding rect
if (mPoints.Count > 1)
{
// constrain the points to bounding rect
int numPoints = pts[listIdx].Count;
for (int i = 0; i < numPoints; ++i)
{
ConstrainPointToBounds(pts[listIdx][i]);
}
}
}
while (listIdx < pts.Count)
{
// simple sanity checking - remove duplicate coincident points before
// we check the polygon: fast, simple algorithm that eliminate lots of problems
// that only more expensive checks will find
pts[listIdx].RemoveDuplicateNeighborPoints();
pts[listIdx].WindingOrder = Point2DList.WindingOrderType.Default;
bool bListOK = true;
Point2DList.PolygonError err = pts[listIdx].CheckPolygon();
while (bListOK && err != PolygonError.None)
{
if ((err & PolygonError.NotEnoughVertices) == PolygonError.NotEnoughVertices)
{
bListOK = false;
continue;
}
if ((err & PolygonError.NotSimple) == PolygonError.NotSimple)
{
// split the polygons, remove the current list and add the resulting list to the end
//List<Point2DList> l = TriangulationUtil.SplitSelfIntersectingPolygon(pts[listIdx], pts[listIdx].Epsilon);
List<Point2DList> l = PolygonUtil.SplitComplexPolygon(pts[listIdx], pts[listIdx].Epsilon);
pts.RemoveAt(listIdx);
foreach (Point2DList newList in l)
{
Contour c = new Contour(this);
c.AddRange(newList);
pts.Add(c);
}
err = pts[listIdx].CheckPolygon();
continue;
}
if ((err & PolygonError.Degenerate) == PolygonError.Degenerate)
{
pts[listIdx].Simplify(this.Epsilon);
err = pts[listIdx].CheckPolygon();
continue;
//err &= ~(PolygonError.Degenerate);
//if (pts[listIdx].Count < 3)
//{
// err |= PolygonError.NotEnoughVertices;
// bListOK = false;
// continue;
//}
}
if ((err & PolygonError.AreaTooSmall) == PolygonError.AreaTooSmall ||
(err & PolygonError.SidesTooCloseToParallel) == PolygonError.SidesTooCloseToParallel ||
(err & PolygonError.TooThin) == PolygonError.TooThin ||
(err & PolygonError.Unknown) == PolygonError.Unknown)
{
bListOK = false;
continue;
}
// non-convex polygons are ok
//if ((err & PolygonError.NotConvex) == PolygonError.NotConvex)
//{
//}
}
if (!bListOK && pts[listIdx].Count != 2)
{
pts.RemoveAt(listIdx);
}
else
{
++listIdx;
}
}
bool bOK = true;
listIdx = 0;
while (listIdx < pts.Count)
{
int numPoints = pts[listIdx].Count;
if (numPoints < 2)
{
// should not be possible by this point...
++listIdx;
bOK = false;
continue;
}
else if (numPoints == 2)
{
uint constraintCode = TriangulationConstraint.CalculateContraintCode(pts[listIdx][0], pts[listIdx][1]);
TriangulationConstraint tc = null;
if (!mConstraintMap.TryGetValue(constraintCode, out tc))
{
tc = new TriangulationConstraint(pts[listIdx][0], pts[listIdx][1]);
AddConstraint(tc);
}
}
else
{
Contour ph = new Contour(this, pts[listIdx], Point2DList.WindingOrderType.Unknown);
ph.WindingOrder = Point2DList.WindingOrderType.Default;
ph.Name = name + ":" + listIdx.ToString();
mHoles.Add(ph);
}
++listIdx;
}
return bOK;
}
// this method adds constraints singly and does not assume that they form a contour
// If you are trying to add a "series" or edges (or "contour"), use AddHole instead.
public bool AddConstraints(List<TriangulationConstraint> constraints)
{
if (constraints == null || constraints.Count < 1)
{
return false;
}
bool bOK = true;
foreach (TriangulationConstraint tc in constraints)
{
if (ConstrainPointToBounds(tc.P) || ConstrainPointToBounds(tc.Q))
{
tc.CalculateContraintCode();
}
TriangulationConstraint tcTmp = null;
if (!mConstraintMap.TryGetValue(tc.ConstraintCode, out tcTmp))
{
tcTmp = tc;
bOK = AddConstraint(tcTmp) && bOK;
}
}
return bOK;
}
public bool AddConstraint(TriangulationConstraint tc)
{
if (tc == null || tc.P == null || tc.Q == null)
{
return false;
}
// If we already have this constraint, then there's nothing to do. Since we already have
// a valid constraint in the map with the same ConstraintCode, then we're guaranteed that
// the points are also valid (and have the same coordinates as the ones being passed in with
// this constrain). Return true to indicate that we successfully "added" the constraint
if (mConstraintMap.ContainsKey(tc.ConstraintCode))
{
return true;
}
// Make sure the constraint is not using points that are duplicates of ones already stored
// If it is, replace the Constraint Points with the points already stored.
TriangulationPoint p;
if (TryGetPoint(tc.P.X, tc.P.Y, out p))
{
tc.P = p;
}
else
{
Add(tc.P);
}
if (TryGetPoint(tc.Q.X, tc.Q.Y, out p))
{
tc.Q = p;
}
else
{
Add(tc.Q);
}
mConstraintMap.Add(tc.ConstraintCode, tc);
return true;
}
public bool TryGetConstraint(uint constraintCode, out TriangulationConstraint tc)
{
return mConstraintMap.TryGetValue(constraintCode, out tc);
}
public int GetNumConstraints()
{
return mConstraintMap.Count;
}
public Dictionary<uint, TriangulationConstraint>.Enumerator GetConstraintEnumerator()
{
return mConstraintMap.GetEnumerator();
}
public int GetNumHoles()
{
int numHoles = 0;
foreach (Contour c in mHoles)
{
numHoles += c.GetNumHoles(false);
}
return numHoles;
}
public Contour GetHole(int idx)
{
if (idx < 0 || idx >= mHoles.Count)
{
return null;
}
return mHoles[idx];
}
public int GetActualHoles(out List<Contour> holes)
{
holes = new List<Contour>();
foreach (Contour c in mHoles)
{
c.GetActualHoles(false, ref holes);
}
return holes.Count;
}
protected void InitializeHoles()
{
Contour.InitializeHoles(mHoles, this, this);
foreach (Contour c in mHoles)
{
c.InitializeHoles(this);
}
}
public override bool Initialize()
{
InitializeHoles();
return base.Initialize();
}
public override void Prepare(TriangulationContext tcx)
{
if (!Initialize())
{
return;
}
base.Prepare(tcx);
Dictionary<uint, TriangulationConstraint>.Enumerator it = mConstraintMap.GetEnumerator();
while (it.MoveNext())
{
TriangulationConstraint tc = it.Current.Value;
tcx.NewConstraint(tc.P, tc.Q);
}
}
public override void AddTriangle(DelaunayTriangle t)
{
Triangles.Add(t);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 916d5f1fd714de84cbff36c5f382d155
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,303 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Poly2Tri
{
public class PointSet : Point2DList, ITriangulatable, IEnumerable<TriangulationPoint>, IList<TriangulationPoint>
{
protected Dictionary<uint, TriangulationPoint> mPointMap = new Dictionary<uint, TriangulationPoint>();
public IList<TriangulationPoint> Points { get { return this; } private set { } }
public IList<DelaunayTriangle> Triangles { get; private set; }
public string FileName { get; set; }
public bool DisplayFlipX { get; set; }
public bool DisplayFlipY { get; set; }
public float DisplayRotate { get; set; }
protected double mPrecision = TriangulationPoint.kVertexCodeDefaultPrecision;
public double Precision { get { return mPrecision; } set { mPrecision = value; } }
public double MinX { get { return mBoundingBox.MinX; } }
public double MaxX { get { return mBoundingBox.MaxX; } }
public double MinY { get { return mBoundingBox.MinY; } }
public double MaxY { get { return mBoundingBox.MaxY; } }
public Rect2D Bounds { get { return mBoundingBox; } }
public virtual TriangulationMode TriangulationMode { get { return TriangulationMode.Unconstrained; } }
public new TriangulationPoint this[int index]
{
get { return mPoints[index] as TriangulationPoint; }
set { mPoints[index] = value; }
}
public PointSet(List<TriangulationPoint> bounds)
{
//Points = new List<TriangulationPoint>();
foreach (TriangulationPoint p in bounds)
{
Add(p, -1, false);
// Only the initial points are counted toward min/max x/y as they
// are considered to be the boundaries of the point-set
mBoundingBox.AddPoint(p);
}
mEpsilon = CalculateEpsilon();
mWindingOrder = WindingOrderType.Unknown; // not valid for a point-set
}
IEnumerator<TriangulationPoint> IEnumerable<TriangulationPoint>.GetEnumerator()
{
return new TriangulationPointEnumerator(mPoints);
}
public int IndexOf(TriangulationPoint p)
{
return mPoints.IndexOf(p);
}
public override void Add(Point2D p)
{
Add(p as TriangulationPoint, -1, false);
}
public virtual void Add(TriangulationPoint p)
{
Add(p, -1, false);
}
protected override void Add(Point2D p, int idx, bool constrainToBounds)
{
Add(p as TriangulationPoint, idx, constrainToBounds);
}
protected bool Add(TriangulationPoint p, int idx, bool constrainToBounds)
{
if (p == null)
{
return false;
}
if (constrainToBounds)
{
ConstrainPointToBounds(p);
}
// if we already have an instance of the point, then don't bother inserting it again as duplicate points
// will actually cause some real problems later on. Still return true though to indicate that the point
// is successfully "added"
if (mPointMap.ContainsKey(p.VertexCode))
{
return true;
}
mPointMap.Add(p.VertexCode, p);
if (idx < 0)
{
mPoints.Add(p);
}
else
{
mPoints.Insert(idx, p);
}
return true;
}
public override void AddRange(IEnumerator<Point2D> iter, WindingOrderType windingOrder)
{
if (iter == null)
{
return;
}
iter.Reset();
while (iter.MoveNext())
{
Add(iter.Current);
}
}
public virtual bool AddRange(List<TriangulationPoint> points)
{
bool bOK = true;
foreach (TriangulationPoint p in points)
{
bOK = Add(p, -1, false) && bOK;
}
return bOK;
}
public bool TryGetPoint(double x, double y, out TriangulationPoint p)
{
uint vc = TriangulationPoint.CreateVertexCode(x, y, Precision);
if (mPointMap.TryGetValue(vc, out p))
{
return true;
}
return false;
}
//public override void Insert(int idx, Point2D item)
//{
// Add(item, idx, true);
//}
public void Insert(int idx, TriangulationPoint item)
{
mPoints.Insert(idx, item);
}
public override bool Remove(Point2D p)
{
return mPoints.Remove(p);
}
public bool Remove(TriangulationPoint p)
{
return mPoints.Remove(p);
}
public override void RemoveAt(int idx)
{
if (idx < 0 || idx >= Count)
{
return;
}
mPoints.RemoveAt(idx);
}
public bool Contains(TriangulationPoint p)
{
return mPoints.Contains(p);
}
public void CopyTo(TriangulationPoint[] array, int arrayIndex)
{
int numElementsToCopy = Math.Min(Count, array.Length - arrayIndex);
for (int i = 0; i < numElementsToCopy; ++i)
{
array[arrayIndex + i] = mPoints[i] as TriangulationPoint;
}
}
// returns true if the point is changed, false if the point is unchanged
protected bool ConstrainPointToBounds(Point2D p)
{
double oldX = p.X;
double oldY = p.Y;
p.X = Math.Max(MinX, p.X);
p.X = Math.Min(MaxX, p.X);
p.Y = Math.Max(MinY, p.Y);
p.Y = Math.Min(MaxY, p.Y);
return (p.X != oldX) || (p.Y != oldY);
}
protected bool ConstrainPointToBounds(TriangulationPoint p)
{
double oldX = p.X;
double oldY = p.Y;
p.X = Math.Max(MinX, p.X);
p.X = Math.Min(MaxX, p.X);
p.Y = Math.Max(MinY, p.Y);
p.Y = Math.Min(MaxY, p.Y);
return (p.X != oldX) || (p.Y != oldY);
}
public virtual void AddTriangle(DelaunayTriangle t)
{
Triangles.Add(t);
}
public void AddTriangles(IEnumerable<DelaunayTriangle> list)
{
foreach (var tri in list)
{
AddTriangle(tri);
}
}
public void ClearTriangles()
{
Triangles.Clear();
}
public virtual bool Initialize()
{
return true;
}
public virtual void Prepare(TriangulationContext tcx)
{
if (Triangles == null)
{
Triangles = new List<DelaunayTriangle>(Points.Count);
}
else
{
Triangles.Clear();
}
tcx.Points.AddRange(Points);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 268d5ee20b0e0264ba2e0fb6a609f767
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace Poly2Tri
{
public enum TriangulationAlgorithm
{
DTSweep
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: abc66d7b94e2899478944d8ff73c7130
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,153 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Forces a triangle edge between two points p and q
* when triangulating. For example used to enforce
* Polygon Edges during a polygon triangulation.
*
* @author Thomas Åhlén, thahlen@gmail.com
*/
using System;
namespace Poly2Tri
{
public class Edge
{
protected Point2D mP = null;
protected Point2D mQ = null;
public Point2D EdgeStart { get { return mP; } set { mP= value;} }
public Point2D EdgeEnd { get { return mQ; } set { mQ = value; } }
public Edge() { mP = null; mQ = null; }
public Edge(Point2D edgeStart, Point2D edgeEnd)
{
mP = edgeStart;
mQ = edgeEnd;
}
}
public class TriangulationConstraint : Edge
{
private uint mContraintCode = 0;
public TriangulationPoint P
{
get { return mP as TriangulationPoint; }
set
{
// Note: intentionally use != instead of !Equals() because we
// WANT to compare pointer values here rather than VertexCode values
if (value != null && mP != value)
{
mP = value;
CalculateContraintCode();
}
}
}
public TriangulationPoint Q
{
get { return mQ as TriangulationPoint; }
set
{
// Note: intentionally use != instead of !Equals() because we
// WANT to compare pointer values here rather than VertexCode values
if (value != null && mQ != value)
{
mQ = value;
CalculateContraintCode();
}
}
}
public uint ConstraintCode { get { return mContraintCode; } }
/// <summary>
/// Give two points in any order. Will always be ordered so
/// that q.y > p.y and q.x > p.x if same y value
/// </summary>
public TriangulationConstraint(TriangulationPoint p1, TriangulationPoint p2)
{
mP = p1;
mQ = p2;
if (p1.Y > p2.Y)
{
mQ = p1;
mP = p2;
}
else if (p1.Y == p2.Y)
{
if (p1.X > p2.X)
{
mQ = p1;
mP = p2;
}
else if (p1.X == p2.X)
{
// logger.info( "Failed to create constraint {}={}", p1, p2 );
// throw new DuplicatePointException( p1 + "=" + p2 );
// return;
}
}
CalculateContraintCode();
}
public override string ToString()
{
return "[P=" + P.ToString() + ", Q=" + Q.ToString() + " : {" + mContraintCode.ToString() + "}]";
}
public void CalculateContraintCode()
{
mContraintCode = TriangulationConstraint.CalculateContraintCode(P, Q);
}
public static uint CalculateContraintCode(TriangulationPoint p, TriangulationPoint q)
{
if (p == null || p == null)
{
throw new ArgumentNullException();
}
uint constraintCode = MathUtil.Jenkins32Hash(BitConverter.GetBytes(p.VertexCode), 0);
constraintCode = MathUtil.Jenkins32Hash(BitConverter.GetBytes(q.VertexCode), constraintCode);
return constraintCode;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 83093633ca35eae438bb30032fb94cc7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,149 @@
/* Poly2Tri
* Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Poly2Tri
{
public abstract class TriangulationContext
{
public TriangulationDebugContext DebugContext { get; protected set; }
public readonly List<DelaunayTriangle> Triangles = new List<DelaunayTriangle>();
public readonly List<TriangulationPoint> Points = new List<TriangulationPoint>(200);
public TriangulationMode TriangulationMode { get; protected set; }
public ITriangulatable Triangulatable { get; private set; }
public int StepCount { get; private set; }
public void Done()
{
StepCount++;
}
public abstract TriangulationAlgorithm Algorithm { get; }
public virtual void PrepareTriangulation(ITriangulatable t)
{
Triangulatable = t;
TriangulationMode = t.TriangulationMode;
t.Prepare(this);
//List<TriangulationConstraint> constraints = new List<TriangulationConstraint>();
//Console.WriteLine("Points for " + t.FileName + ":");
//Console.WriteLine("Idx,X,Y,VC,Edges");
//int numPoints = Points.Count;
//for (int i = 0; i < numPoints; ++i)
//{
// StringBuilder sb = new StringBuilder(128);
// sb.Append(i.ToString());
// sb.Append(",");
// sb.Append(Points[i].X.ToString());
// sb.Append(",");
// sb.Append(Points[i].Y.ToString());
// sb.Append(",");
// sb.Append(Points[i].VertexCode.ToString());
// int numEdges = (Points[i].Edges != null) ? Points[i].Edges.Count : 0;
// for (int j = 0; j < numEdges; ++j)
// {
// TriangulationConstraint tc = Points[i].Edges[j];
// sb.Append(",");
// sb.Append(tc.ConstraintCode.ToString());
// constraints.Add(tc);
// }
// Console.WriteLine(sb.ToString());
//}
//int idx = 0;
//Console.WriteLine("Constraints " + t.FileName + ":");
//Console.WriteLine("EdgeIdx,Px,Py,PVC,Qx,Qy,QVC,ConstraintCode,Owner");
//foreach (TriangulationConstraint tc in constraints)
//{
// StringBuilder sb = new StringBuilder(128);
// sb.Append(idx.ToString());
// sb.Append(",");
// sb.Append(tc.P.X.ToString());
// sb.Append(",");
// sb.Append(tc.P.Y.ToString());
// sb.Append(",");
// sb.Append(tc.P.VertexCode.ToString());
// sb.Append(",");
// sb.Append(tc.Q.X.ToString());
// sb.Append(",");
// sb.Append(tc.Q.Y.ToString());
// sb.Append(",");
// sb.Append(tc.Q.VertexCode.ToString());
// sb.Append(",");
// sb.Append(tc.ConstraintCode.ToString());
// sb.Append(",");
// if (tc.Q.HasEdge(tc.P))
// {
// sb.Append("Q");
// }
// else
// {
// sb.Append("P");
// }
// Console.WriteLine(sb.ToString());
// ++idx;
//}
}
public abstract TriangulationConstraint NewConstraint(TriangulationPoint a, TriangulationPoint b);
public void Update(string message) { }
public virtual void Clear()
{
Points.Clear();
if (DebugContext != null)
{
DebugContext.Clear();
}
StepCount = 0;
}
public virtual bool IsDebugEnabled { get; protected set; }
public DTSweepDebugContext DTDebugContext { get { return DebugContext as DTSweepDebugContext; } }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a4a56fa5d3520ee40b011ac6f4741f62
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More