feat: Initial commit
This commit is contained in:
8
Assets/Plugins/Poly2Tri/Triangulation/Delaunay.meta
Normal file
8
Assets/Plugins/Poly2Tri/Triangulation/Delaunay.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24f46f7445d706343b6a44b48a6504cf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b61ca8480a824b4eab0f5a7c6587932
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca0c831d398dcf043875b7e514c4f9ee
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bba5ad2e582edd14a9b9f4c2269e83e2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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; } }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f50404d2892ffc42b70043a773f577f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1301
Assets/Plugins/Poly2Tri/Triangulation/Delaunay/Sweep/DTSweep.cs
Normal file
1301
Assets/Plugins/Poly2Tri/Triangulation/Delaunay/Sweep/DTSweep.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18835840dca416041bff74eaaf5dcc47
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 295b5899a6bed9d4187f6a49c293fc2f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24c139533abc53242a5fda851aed1f90
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ee2e0932fff59f429c452bba590cf83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c80776e6f580608498870e9ba0c7fdca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c7810b370713bb4985dfa014259efbc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dfb17679c246e5f4fa5a535f717d47d5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6f5e106faca1c442a1def9a56695eac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
57
Assets/Plugins/Poly2Tri/Triangulation/ITriangulatable.cs
Normal file
57
Assets/Plugins/Poly2Tri/Triangulation/ITriangulatable.cs
Normal 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();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75ea7f139cb97ce4c8150e06934491d7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
40
Assets/Plugins/Poly2Tri/Triangulation/Orientation.cs
Normal file
40
Assets/Plugins/Poly2Tri/Triangulation/Orientation.cs
Normal 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
|
||||
}
|
||||
}
|
11
Assets/Plugins/Poly2Tri/Triangulation/Orientation.cs.meta
Normal file
11
Assets/Plugins/Poly2Tri/Triangulation/Orientation.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f53cc2457ddb3dd4c82e5b3eb98327c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Plugins/Poly2Tri/Triangulation/Polygon.meta
Normal file
8
Assets/Plugins/Poly2Tri/Triangulation/Polygon.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30e3877e8ca306440ac44dfc20462e1d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
577
Assets/Plugins/Poly2Tri/Triangulation/Polygon/Contour.cs
Normal file
577
Assets/Plugins/Poly2Tri/Triangulation/Polygon/Contour.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dfd11dff63cdeb4f8543c5ee276d3f9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
409
Assets/Plugins/Poly2Tri/Triangulation/Polygon/Polygon.cs
Normal file
409
Assets/Plugins/Poly2Tri/Triangulation/Polygon/Polygon.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98daeea2e71d727429a84a799a9b1706
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55fd89ec8383d3b48b01e6abebf915c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
60
Assets/Plugins/Poly2Tri/Triangulation/Polygon/PolygonSet.cs
Normal file
60
Assets/Plugins/Poly2Tri/Triangulation/Polygon/PolygonSet.cs
Normal 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; } }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b9b966d2e3f8d543beed734daa9b289
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
1876
Assets/Plugins/Poly2Tri/Triangulation/Polygon/PolygonUtil.cs
Normal file
1876
Assets/Plugins/Poly2Tri/Triangulation/Polygon/PolygonUtil.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c2b8bdeed61807438a69bc54de1a423
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Plugins/Poly2Tri/Triangulation/Sets.meta
Normal file
8
Assets/Plugins/Poly2Tri/Triangulation/Sets.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0fe19f49cb73334418d2abe53ddbe747
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 916d5f1fd714de84cbff36c5f382d155
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
303
Assets/Plugins/Poly2Tri/Triangulation/Sets/PointSet.cs
Normal file
303
Assets/Plugins/Poly2Tri/Triangulation/Sets/PointSet.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Plugins/Poly2Tri/Triangulation/Sets/PointSet.cs.meta
Normal file
11
Assets/Plugins/Poly2Tri/Triangulation/Sets/PointSet.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 268d5ee20b0e0264ba2e0fb6a609f767
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abc66d7b94e2899478944d8ff73c7130
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
153
Assets/Plugins/Poly2Tri/Triangulation/TriangulationConstraint.cs
Normal file
153
Assets/Plugins/Poly2Tri/Triangulation/TriangulationConstraint.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83093633ca35eae438bb30032fb94cc7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
149
Assets/Plugins/Poly2Tri/Triangulation/TriangulationContext.cs
Normal file
149
Assets/Plugins/Poly2Tri/Triangulation/TriangulationContext.cs
Normal 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; } }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4a56fa5d3520ee40b011ac6f4741f62
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90234b8ef08f44743bae557c23b08fb5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
40
Assets/Plugins/Poly2Tri/Triangulation/TriangulationMode.cs
Normal file
40
Assets/Plugins/Poly2Tri/Triangulation/TriangulationMode.cs
Normal 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
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38eec52c05bc87545aa65be96865e8f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
244
Assets/Plugins/Poly2Tri/Triangulation/TriangulationPoint.cs
Normal file
244
Assets/Plugins/Poly2Tri/Triangulation/TriangulationPoint.cs
Normal 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
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d759c8fa408c9344ab9f1e8a4de1001d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Plugins/Poly2Tri/Triangulation/Util.meta
Normal file
8
Assets/Plugins/Poly2Tri/Triangulation/Util.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26805279e83c13546a2544ddbbfa3a01
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
73
Assets/Plugins/Poly2Tri/Triangulation/Util/PointGenerator.cs
Normal file
73
Assets/Plugins/Poly2Tri/Triangulation/Util/PointGenerator.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30b228dc7fbacd740a8ee42d783fcd5f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de075d11f8eef4d4c8f1e7053057e893
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
395
Assets/Plugins/Poly2Tri/Triangulation/Util/TriangulationUtil.cs
Normal file
395
Assets/Plugins/Poly2Tri/Triangulation/Util/TriangulationUtil.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9973d31339415d74185f362976b190e2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user