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:

View File

@@ -0,0 +1,45 @@
/* 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 abstract class TriangulationDebugContext
{
protected TriangulationContext _tcx;
public TriangulationDebugContext(TriangulationContext tcx)
{
_tcx = tcx;
}
public abstract void Clear();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 90234b8ef08f44743bae557c23b08fb5
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 TriangulationMode
{
Unconstrained,
Constrained,
Polygon
}
}

View File

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

View File

@@ -0,0 +1,244 @@
/* 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;
using System.Collections.Generic;
namespace Poly2Tri
{
public class TriangulationPoint : Point2D
{
public static readonly double kVertexCodeDefaultPrecision = 8.0;
public override double X
{
get { return mX; }
set
{
if (value != mX)
{
mX = value;
mVertexCode = TriangulationPoint.CreateVertexCode(mX, mY, kVertexCodeDefaultPrecision);
// Technically, we should change the ConstraintCodes of any edges that contain this point.
// We don't for 2 reasons:
// 1) Currently the only time we care about Vertex/Constraint Codes is when entering data in the point-set.
// Once the data is being used by the algorithm, the point locations are (currently) not modified.
// 2) Since this Point's Edge list will only contain SOME of the edges that this point is a part of,
// there currently isn't a way to (easily) get any edges that contain this point but are not in this
// point's edge list.
}
}
}
public override double Y
{
get { return mY; }
set
{
if (value != mY)
{
mY = value;
mVertexCode = TriangulationPoint.CreateVertexCode(mX, mY, kVertexCodeDefaultPrecision);
// Technically, we should change the ConstraintCodes of any edges that contain this point.
// We don't for 2 reasons:
// 1) Currently the only time we care about Vertex/Constraint Codes is when entering data in the point-set.
// Once the data is being used by the algorithm, the point locations are (currently) not modified.
// 2) Since this Point's Edge list will only contain SOME of the edges that this point is a part of,
// there currently isn't a way to (easily) get any edges that contain this point but are not in this
// point's edge list.
}
}
}
protected uint mVertexCode = 0;
public uint VertexCode { get { return mVertexCode; } }
// List of edges this point constitutes an upper ending point (CDT)
public List<DTSweepConstraint> Edges { get; private set; }
public bool HasEdges { get { return Edges != null; } }
public TriangulationPoint(double x, double y)
: this(x, y, kVertexCodeDefaultPrecision)
{
}
public TriangulationPoint(double x, double y, double precision)
: base(x,y)
{
mVertexCode = TriangulationPoint.CreateVertexCode(x, y, precision);
}
public override string ToString()
{
return base.ToString() + ":{" + mVertexCode.ToString() + "}";
}
public override int GetHashCode()
{
return (int)mVertexCode;
}
public override bool Equals(object obj)
{
TriangulationPoint p2 = obj as TriangulationPoint;
if (p2 != null)
{
return mVertexCode == p2.VertexCode;
}
else
{
return base.Equals(obj);
}
}
public override void Set(double x, double y)
{
if (x != mX || y != mY)
{
mX = x;
mY = y;
mVertexCode = TriangulationPoint.CreateVertexCode(mX, mY, kVertexCodeDefaultPrecision);
}
}
public static uint CreateVertexCode(double x, double y, double precision)
{
float fx = (float)MathUtil.RoundWithPrecision(x, precision);
float fy = (float)MathUtil.RoundWithPrecision(y, precision);
uint vc = MathUtil.Jenkins32Hash(BitConverter.GetBytes(fx), 0);
vc = MathUtil.Jenkins32Hash(BitConverter.GetBytes(fy), vc);
return vc;
}
public void AddEdge(DTSweepConstraint e)
{
if (Edges == null)
{
Edges = new List<DTSweepConstraint>();
}
Edges.Add(e);
}
public bool HasEdge(TriangulationPoint p)
{
DTSweepConstraint tmp = null;
return GetEdge(p, out tmp);
}
public bool GetEdge(TriangulationPoint p, out DTSweepConstraint edge)
{
edge = null;
if (Edges == null || Edges.Count < 1 || p == null || p.Equals(this))
{
return false;
}
foreach (DTSweepConstraint sc in Edges)
{
if ((sc.P.Equals(this) && sc.Q.Equals(p)) || (sc.P.Equals(p) && sc.Q.Equals(this)))
{
edge = sc;
return true;
}
}
return false;
}
public static Point2D ToPoint2D(TriangulationPoint p)
{
return p as Point2D;
}
}
public class TriangulationPointEnumerator : IEnumerator<TriangulationPoint>
{
protected IList<Point2D> mPoints;
protected int position = -1; // Enumerators are positioned before the first element until the first MoveNext() call.
public TriangulationPointEnumerator(IList<Point2D> points)
{
mPoints = points;
}
public bool MoveNext()
{
position++;
return (position < mPoints.Count);
}
public void Reset()
{
position = -1;
}
void IDisposable.Dispose() { }
Object IEnumerator.Current { get { return Current; } }
public TriangulationPoint Current
{
get
{
if (position < 0 || position >= mPoints.Count)
{
return null;
}
return mPoints[position] as TriangulationPoint;
}
}
}
public class TriangulationPointList : Point2DList
{
}
}

View File

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

View File

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

View File

@@ -0,0 +1,73 @@
/* 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;
namespace Poly2Tri
{
public class PointGenerator
{
static readonly Random RNG = new Random();
public static List<TriangulationPoint> UniformDistribution(int n, double scale)
{
List<TriangulationPoint> points = new List<TriangulationPoint>();
for (int i = 0; i < n; i++)
{
points.Add(new TriangulationPoint(scale * (0.5 - RNG.NextDouble()), scale * (0.5 - RNG.NextDouble())));
}
return points;
}
public static List<TriangulationPoint> UniformGrid(int n, double scale)
{
double x = 0;
double size = scale / n;
double halfScale = 0.5 * scale;
List<TriangulationPoint> points = new List<TriangulationPoint>();
for (int i = 0; i < n + 1; i++)
{
x = halfScale - i * size;
for (int j = 0; j < n + 1; j++)
{
points.Add(new TriangulationPoint(x, halfScale - j * size));
}
}
return points;
}
}
}

View File

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

View File

@@ -0,0 +1,95 @@
/* 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 PolygonGenerator
{
static readonly Random RNG = new Random();
private static double PI_2 = 2.0 * Math.PI;
public static Polygon RandomCircleSweep(double scale, int vertexCount)
{
PolygonPoint point;
PolygonPoint[] points;
double radius = scale / 4;
points = new PolygonPoint[vertexCount];
for (int i = 0; i < vertexCount; i++)
{
do
{
if (i % 250 == 0)
{
radius += scale / 2 * (0.5 - RNG.NextDouble());
}
else if (i % 50 == 0)
{
radius += scale / 5 * (0.5 - RNG.NextDouble());
}
else
{
radius += 25 * scale / vertexCount * (0.5 - RNG.NextDouble());
}
radius = radius > scale / 2 ? scale / 2 : radius;
radius = radius < scale / 10 ? scale / 10 : radius;
} while (radius < scale / 10 || radius > scale / 2);
point = new PolygonPoint(radius * Math.Cos((PI_2 * i) / vertexCount), radius * Math.Sin((PI_2 * i) / vertexCount));
points[i] = point;
}
return new Polygon(points);
}
public static Polygon RandomCircleSweep2(double scale, int vertexCount)
{
PolygonPoint point;
PolygonPoint[] points;
double radius = scale / 4;
points = new PolygonPoint[vertexCount];
for (int i = 0; i < vertexCount; i++)
{
do
{
radius += scale / 5 * (0.5 - RNG.NextDouble());
radius = radius > scale / 2 ? scale / 2 : radius;
radius = radius < scale / 10 ? scale / 10 : radius;
} while (radius < scale / 10 || radius > scale / 2);
point = new PolygonPoint(radius * Math.Cos((PI_2 * i) / vertexCount), radius * Math.Sin((PI_2 * i) / vertexCount));
points[i] = point;
}
return new Polygon(points);
}
}
}

View File

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

View File

@@ -0,0 +1,395 @@
/* 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
{
/**
* @author Thomas Åhlén, thahlen@gmail.com
*/
public class TriangulationUtil
{
/// <summary>
/// Requirements:
/// 1. a,b and c form a triangle.
/// 2. a and d is know to be on opposite side of bc
/// <code>
/// a
/// +
/// / \
/// / \
/// b/ \c
/// +-------+
/// / B \
/// / \
/// </code>
/// Facts:
/// d has to be in area B to have a chance to be inside the circle formed by a,b and c
/// d is outside B if orient2d(a,b,d) or orient2d(c,a,d) is CW
/// This preknowledge gives us a way to optimize the incircle test
/// </summary>
/// <param name="pa">triangle point, opposite d</param>
/// <param name="pb">triangle point</param>
/// <param name="pc">triangle point</param>
/// <param name="pd">point opposite a</param>
/// <returns>true if d is inside circle, false if on circle edge</returns>
public static bool SmartIncircle(Point2D pa, Point2D pb, Point2D pc, Point2D pd)
{
double pdx = pd.X;
double pdy = pd.Y;
double adx = pa.X - pdx;
double ady = pa.Y - pdy;
double bdx = pb.X - pdx;
double bdy = pb.Y - pdy;
double adxbdy = adx * bdy;
double bdxady = bdx * ady;
double oabd = adxbdy - bdxady;
// oabd = orient2d(pa,pb,pd);
if (oabd <= 0)
{
return false;
}
double cdx = pc.X - pdx;
double cdy = pc.Y - pdy;
double cdxady = cdx * ady;
double adxcdy = adx * cdy;
double ocad = cdxady - adxcdy;
// ocad = orient2d(pc,pa,pd);
if (ocad <= 0)
{
return false;
}
double bdxcdy = bdx * cdy;
double cdxbdy = cdx * bdy;
double alift = adx * adx + ady * ady;
double blift = bdx * bdx + bdy * bdy;
double clift = cdx * cdx + cdy * cdy;
double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
return det > 0;
}
public static bool InScanArea(Point2D pa, Point2D pb, Point2D pc, Point2D pd)
{
double pdx = pd.X;
double pdy = pd.Y;
double adx = pa.X - pdx;
double ady = pa.Y - pdy;
double bdx = pb.X - pdx;
double bdy = pb.Y - pdy;
double adxbdy = adx * bdy;
double bdxady = bdx * ady;
double oabd = adxbdy - bdxady;
// oabd = orient2d(pa,pb,pd);
if (oabd <= 0)
{
return false;
}
double cdx = pc.X - pdx;
double cdy = pc.Y - pdy;
double cdxady = cdx * ady;
double adxcdy = adx * cdy;
double ocad = cdxady - adxcdy;
// ocad = orient2d(pc,pa,pd);
if (ocad <= 0)
{
return false;
}
return true;
}
/// Forumla to calculate signed area
/// Positive if CCW
/// Negative if CW
/// 0 if collinear
/// A[P1,P2,P3] = (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
/// = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
public static Orientation Orient2d(Point2D pa, Point2D pb, Point2D pc)
{
double detleft = (pa.X - pc.X) * (pb.Y - pc.Y);
double detright = (pa.Y - pc.Y) * (pb.X - pc.X);
double val = detleft - detright;
if (val > -MathUtil.EPSILON && val < MathUtil.EPSILON)
{
return Orientation.Collinear;
}
else if (val > 0)
{
return Orientation.CCW;
}
return Orientation.CW;
}
///////////////////////////////////////////////////////////////////////////////
// PointRelativeToLine2D
//
// Returns -1 if point is on left of line, 0 if point is on line, and 1 if
// the point is to the right of the line. This assumes a coordinate system
// whereby the y axis goes upward when the x axis goes rightward. This is how
// 3D systems (both right and left-handed) and PostScript works, but is not
// how the Win32 GUI works. If you are using a 'y goes downward' coordinate
// system, simply negate the return value from this function.
//
// Given a point (a,b) and a line from (x1,y1) to (x2,y2), we calculate the
// following equation:
// (y2-y1)*(a-x1)-(x2-x1)*(b-y1) (left)
// If the result is > 0, the point is on 1 --------------> 2
// the right, else left. (right)
//
// For example, with a point at (1,1) and a
// line going from (0,0) to (2,0), we get:
// (0-0)*(1-0)-(2-0)*(1-0)
// which equals:
// -2
// Which indicates the point is (correctly)
// on the left of the directed line.
//
// This function has been checked to a good degree.
//
/////////////////////////////////////////////////////////////////////////////
//public static double PointRelativeToLine2D(Point2D ptPoint, Point2D ptLineBegin, Point2D ptLineEnd)
//{
// return (ptLineEnd.Y - ptLineBegin.Y) * (ptPoint.X - ptLineBegin.X) - (ptLineEnd.X - ptLineBegin.X) * (ptPoint.Y - ptLineBegin.Y);
//}
///////////////////////////////////////////////////////////////////////////
// PointInBoundingBox - checks if a point is completely inside an
// axis-aligned bounding box defined by xmin, xmax, ymin, and ymax.
// Note that the point must be fully inside for this method to return
// true - it cannot lie on the border of the bounding box.
///////////////////////////////////////////////////////////////////////////
public static bool PointInBoundingBox(double xmin, double xmax, double ymin, double ymax, Point2D p)
{
return (p.X > xmin && p.X < xmax && p.Y > ymin && p.Y < ymax);
}
public static bool PointOnLineSegment2D(Point2D lineStart, Point2D lineEnd, Point2D p, double epsilon)
{
return TriangulationUtil.PointOnLineSegment2D(lineStart.X, lineStart.Y, lineEnd.X, lineEnd.Y, p.X, p.Y, epsilon);
}
public static bool PointOnLineSegment2D(double x1, double y1, double x2, double y2, double x, double y, double epsilon)
{
// First checking if (x, z) is in the range of the line segment's end points.
if (MathUtil.IsValueBetween(x, x1, x2, epsilon) && MathUtil.IsValueBetween(y, y1, y2, epsilon))
{
if (MathUtil.AreValuesEqual(x2 - x1, 0.0f, epsilon))
{
// Vertical line.
return true;
}
double slope = (y2 - y1) / (x2 - x1);
double yIntercept = -(slope * x1) + y1;
// Checking if (x, y) is on the line passing through the end points.
double t = y - ((slope * x) + yIntercept);
return MathUtil.AreValuesEqual(t, 0.0f, epsilon);
}
return false;
}
public static bool RectsIntersect(Rect2D r1, Rect2D r2)
{
return (r1.Right > r2.Left) &&
(r1.Left < r2.Right) &&
(r1.Bottom > r2.Top) &&
(r1.Top < r2.Bottom);
}
/// <summary>
/// This method detects if two line segments (or lines) intersect,
/// and, if so, the point of intersection. Use the <paramref name="firstIsSegment"/> and
/// <paramref name="secondIsSegment"/> parameters to set whether the intersection point
/// must be on the first and second line segments. Setting these
/// both to true means you are doing a line-segment to line-segment
/// intersection. Setting one of them to true means you are doing a
/// line to line-segment intersection test, and so on.
/// Note: If two line segments are coincident, then
/// no intersection is detected (there are actually
/// infinite intersection points).
/// </summary>
/// <param name="ptStart0">The first point of the first line segment.</param>
/// <param name="ptEnd0">The second point of the first line segment.</param>
/// <param name="ptStart1">The first point of the second line segment.</param>
/// <param name="ptEnd1">The second point of the second line segment.</param>
/// <param name="firstIsSegment">Set this to true to require that the
/// intersection point be on the first line segment.</param>
/// <param name="secondIsSegment">Set this to true to require that the
/// intersection point be on the second line segment.</param>
/// <param name="coincidentEndPointCollisions">Set this to true to enable collisions if the line segments share
/// an endpoint</param>
/// <param name="pIntersectionPt">This is set to the intersection
/// point if an intersection is detected.</param>
/// <returns>True if an intersection is detected, false otherwise.</returns>
public static bool LinesIntersect2D( Point2D ptStart0, Point2D ptEnd0,
Point2D ptStart1, Point2D ptEnd1,
bool firstIsSegment, bool secondIsSegment, bool coincidentEndPointCollisions,
ref Point2D pIntersectionPt,
double epsilon)
{
double d = (ptEnd0.X - ptStart0.X) * (ptStart1.Y - ptEnd1.Y) - (ptStart1.X - ptEnd1.X) * (ptEnd0.Y - ptStart0.Y);
if (Math.Abs(d) < epsilon)
{
//The lines are parallel.
return false;
}
double d0 = (ptStart1.X - ptStart0.X) * (ptStart1.Y - ptEnd1.Y) - (ptStart1.X - ptEnd1.X) * (ptStart1.Y - ptStart0.Y);
double d1 = (ptEnd0.X - ptStart0.X) * (ptStart1.Y - ptStart0.Y) - (ptStart1.X - ptStart0.X) * (ptEnd0.Y - ptStart0.Y);
double kOneOverD = 1 / d;
double t0 = d0 * kOneOverD;
double t1 = d1 * kOneOverD;
if ((!firstIsSegment || ((t0 >= 0.0) && (t0 <= 1.0))) &&
(!secondIsSegment || ((t1 >= 0.0) && (t1 <= 1.0))) &&
(coincidentEndPointCollisions || (!MathUtil.AreValuesEqual(0.0, t0, epsilon) && !MathUtil.AreValuesEqual(0.0, t1, epsilon))))
{
if (pIntersectionPt != null)
{
pIntersectionPt.X = ptStart0.X + t0 * (ptEnd0.X - ptStart0.X);
pIntersectionPt.Y = ptStart0.Y + t0 * (ptEnd0.Y - ptStart0.Y);
}
return true;
}
return false;
}
public static bool LinesIntersect2D( Point2D ptStart0, Point2D ptEnd0,
Point2D ptStart1, Point2D ptEnd1,
ref Point2D pIntersectionPt,
double epsilon)
{
return TriangulationUtil.LinesIntersect2D(ptStart0, ptEnd0, ptStart1, ptEnd1, true, true, false, ref pIntersectionPt, epsilon);
}
///////////////////////////////////////////////////////////////////////////
// RaysIntersect2D
//
// Given two lines defined by (sorry about the lame notation):
// x0 = x00 + vector_x0*s;
// y0 = y00 + vector_y0*s;
//
// x1 = x10 + vector_x1*t;
// y1 = y10 + vector_y1*t;
//
// This function determines the intersection between them, if there is any.
//
// This function assumes the lines to have no endpoints and will intersect
// them anywhere in 2D space.
//
// This algorithm taken from "Realtime-Rendering" section 10.12.
//
// This function has been checked to a good degree.
//
///////////////////////////////////////////////////////////////////////////
public static double LI2DDotProduct(Point2D v0, Point2D v1)
{
return ((v0.X * v1.X) + (v0.Y * v1.Y));
}
public static bool RaysIntersect2D( Point2D ptRayOrigin0, Point2D ptRayVector0,
Point2D ptRayOrigin1, Point2D ptRayVector1,
ref Point2D ptIntersection)
{
double kEpsilon = 0.01;
if (ptIntersection != null)
{
//If the user wants an actual intersection result...
//This is a vector from pLineOrigin0 to ptLineOrigin1.
Point2D ptTemp1 = new Point2D(ptRayOrigin1.X - ptRayOrigin0.X, ptRayOrigin1.Y - ptRayOrigin0.Y);
//This is a vector perpendicular to ptVector1.
Point2D ptTemp2 = new Point2D(-ptRayVector1.Y, ptRayVector1.X);
double fDot1 = TriangulationUtil.LI2DDotProduct(ptRayVector0, ptTemp2);
if (Math.Abs(fDot1) < kEpsilon)
{
return false; //The lines are essentially parallel.
}
double fDot2 = TriangulationUtil.LI2DDotProduct(ptTemp1, ptTemp2);
double s = fDot2 / fDot1;
ptIntersection.X = ptRayOrigin0.X + ptRayVector0.X * s;
ptIntersection.Y = ptRayOrigin0.Y + ptRayVector0.Y * s;
return true;
}
//Else the user just wants to know if there is an intersection...
//In this case we need only compare the slopes of the lines.
double delta = ptRayVector1.X - ptRayVector0.X;
if (Math.Abs(delta) > kEpsilon)
{
delta = ptRayVector1.Y - ptRayVector0.Y;
if (Math.Abs(delta) > kEpsilon)
{
return true; //The lines are not parallel.
}
}
return false;
}
}
}

View File

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