mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-30 01:03:30 +01:00
refactored Triangle
This commit is contained in:
parent
3ededbd3d0
commit
b31d115774
@ -58,7 +58,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
var segments: ArrayBuffer[Segment] = null
|
var segments: ArrayBuffer[Segment] = null
|
||||||
|
|
||||||
val earClip = new EarClip
|
val earClip = new EarClip
|
||||||
var earClipResults: Array[Triangle] = null
|
var earClipResults: Array[poly2tri.earClip.Triangle] = null
|
||||||
|
|
||||||
var polyX: ArrayBuffer[Float] = null
|
var polyX: ArrayBuffer[Float] = null
|
||||||
var polyY: ArrayBuffer[Float] = null
|
var polyY: ArrayBuffer[Float] = null
|
||||||
@ -376,9 +376,9 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
|
|
||||||
// Earclip
|
// Earclip
|
||||||
|
|
||||||
earClipResults = new Array[Triangle](maxTriangles)
|
earClipResults = new Array[poly2tri.earClip.Triangle](maxTriangles)
|
||||||
|
|
||||||
for(i <- 0 until earClipResults.size) earClipResults(i) = new Triangle
|
for(i <- 0 until earClipResults.size) earClipResults(i) = new poly2tri.earClip.Triangle
|
||||||
val xVerts = polyX.toArray.reverse
|
val xVerts = polyX.toArray.reverse
|
||||||
val yVerts = polyY.toArray.reverse
|
val yVerts = polyY.toArray.reverse
|
||||||
|
|
||||||
@ -397,8 +397,8 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
val polyX = Array(400f, 500f, 520f, 460f, 580f, 480f, 360f, 360f, 300f, 200f, 120f, 200f, 340f, 208f, 180f, 300f)
|
val polyX = Array(400f, 500f, 520f, 460f, 580f, 480f, 360f, 360f, 300f, 200f, 120f, 200f, 340f, 208f, 180f, 300f)
|
||||||
val polyY = Array(472f, 392f, 272f, 232f, 212f, 152f, 172f, 52f, 112f, 32f, 92f, 72f, 272f, 212f, 352f, 312f)
|
val polyY = Array(472f, 392f, 272f, 232f, 212f, 152f, 172f, 52f, 112f, 32f, 92f, 72f, 272f, 212f, 352f, 312f)
|
||||||
|
|
||||||
val earClipResults = new Array[Triangle](14)
|
val earClipResults = new Array[poly2tri.earClip.Triangle](14)
|
||||||
for(i <- 0 until earClipResults.size) earClipResults(i) = new Triangle
|
for(i <- 0 until earClipResults.size) earClipResults(i) = new poly2tri.earClip.Triangle
|
||||||
val t1 = System.nanoTime
|
val t1 = System.nanoTime
|
||||||
earClip.triangulatePolygon(polyX, polyY, polyX.size, earClipResults)
|
earClip.triangulatePolygon(polyX, polyY, polyX.size, earClipResults)
|
||||||
val t2 = System.nanoTime
|
val t2 = System.nanoTime
|
||||||
@ -410,8 +410,8 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
val polyX = Array(200f, 300f, 400f, 500f, 600f, 600f, 500f, 400f, 300f, 200f, 110f, 110f)
|
val polyX = Array(200f, 300f, 400f, 500f, 600f, 600f, 500f, 400f, 300f, 200f, 110f, 110f)
|
||||||
val polyY = Array(110f, 200f, 110f, 200f, 110f, 200f, 300f, 200f, 300f, 200f, 300f, 200f)
|
val polyY = Array(110f, 200f, 110f, 200f, 110f, 200f, 300f, 200f, 300f, 200f, 300f, 200f)
|
||||||
|
|
||||||
val earClipResults = new Array[Triangle](14)
|
val earClipResults = new Array[poly2tri.earClip.Triangle](14)
|
||||||
for(i <- 0 until earClipResults.size) earClipResults(i) = new Triangle
|
for(i <- 0 until earClipResults.size) earClipResults(i) = new poly2tri.earClip.Triangle
|
||||||
val t1 = System.nanoTime
|
val t1 = System.nanoTime
|
||||||
earClip.triangulatePolygon(polyX, polyY, polyX.size, earClipResults)
|
earClip.triangulatePolygon(polyX, polyY, polyX.size, earClipResults)
|
||||||
val t2 = System.nanoTime
|
val t2 = System.nanoTime
|
||||||
@ -434,8 +434,8 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
val polyX = Array(350f, 379f, 469f, 397f, 423f, 350f, 277f, 303f, 231f, 321f)
|
val polyX = Array(350f, 379f, 469f, 397f, 423f, 350f, 277f, 303f, 231f, 321f)
|
||||||
val polyY = Array(75f, 161f, 161f, 215f, 301f, 250f, 301f,215f, 161f, 161f)
|
val polyY = Array(75f, 161f, 161f, 215f, 301f, 250f, 301f,215f, 161f, 161f)
|
||||||
|
|
||||||
val earClipResults = new Array[Triangle](14)
|
val earClipResults = new Array[poly2tri.earClip.Triangle](14)
|
||||||
for(i <- 0 until earClipResults.size) earClipResults(i) = new Triangle
|
for(i <- 0 until earClipResults.size) earClipResults(i) = new poly2tri.earClip.Triangle
|
||||||
val t1 = System.nanoTime
|
val t1 = System.nanoTime
|
||||||
earClip.triangulatePolygon(polyX, polyY, polyX.size, earClipResults)
|
earClip.triangulatePolygon(polyX, polyY, polyX.size, earClipResults)
|
||||||
val t2 = System.nanoTime
|
val t2 = System.nanoTime
|
||||||
|
@ -32,7 +32,7 @@ package org.poly2tri.cdt
|
|||||||
|
|
||||||
import scala.collection.mutable.ArrayBuffer
|
import scala.collection.mutable.ArrayBuffer
|
||||||
|
|
||||||
import shapes.{Segment, Point}
|
import shapes.{Segment, Point, Triangle}
|
||||||
import utils.Util
|
import utils.Util
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,10 +42,15 @@ import utils.Util
|
|||||||
*/
|
*/
|
||||||
class CDT(segments: ArrayBuffer[Segment]) {
|
class CDT(segments: ArrayBuffer[Segment]) {
|
||||||
|
|
||||||
|
// The initial triangle
|
||||||
|
var initialTriangle: Triangle = null
|
||||||
// The point list
|
// The point list
|
||||||
val points = init
|
val points = init
|
||||||
// The triangle mesh
|
// The triangle mesh
|
||||||
val mesh = new Mesh
|
val mesh = new Mesh(initialTriangle)
|
||||||
|
|
||||||
|
// Used to compute inital triangle
|
||||||
|
private val ALPHA = 0.3f
|
||||||
|
|
||||||
// Sweep points; build mesh
|
// Sweep points; build mesh
|
||||||
sweep
|
sweep
|
||||||
@ -55,8 +60,8 @@ class CDT(segments: ArrayBuffer[Segment]) {
|
|||||||
// Initialize and sort point list
|
// Initialize and sort point list
|
||||||
private def init: List[Point] = {
|
private def init: List[Point] = {
|
||||||
|
|
||||||
var xmax, xmin = 0f
|
var xmax, xmin = segments(0).p.x
|
||||||
var ymax, ymin = 0f
|
var ymax, ymin = segments(0).p.y
|
||||||
val pts = new ArrayBuffer[Point]
|
val pts = new ArrayBuffer[Point]
|
||||||
|
|
||||||
for(i <- 0 until segments.size) {
|
for(i <- 0 until segments.size) {
|
||||||
@ -74,18 +79,28 @@ class CDT(segments: ArrayBuffer[Segment]) {
|
|||||||
if(p.y < ymin) ymin = p.x
|
if(p.y < ymin) ymin = p.x
|
||||||
if(q.y < ymin) ymin = q.x
|
if(q.y < ymin) ymin = q.x
|
||||||
|
|
||||||
|
|
||||||
pts += shearTransform(p)
|
pts += shearTransform(p)
|
||||||
pts += shearTransform(q)
|
pts += shearTransform(q)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var points: List[Point] = null
|
||||||
|
|
||||||
if(pts.size < 10)
|
if(pts.size < 10)
|
||||||
// Insertion sort is one of the fastest algorithms for sorting arrays containing
|
// Insertion sort is one of the fastest algorithms for sorting arrays containing
|
||||||
// fewer than ten elements, or for lists that are already mostly sorted.
|
// fewer than ten elements, or for lists that are already mostly sorted.
|
||||||
Util.insertSort((p1: Point, p2: Point) => p1 > p2)(pts).toList
|
points = Util.insertSort((p1: Point, p2: Point) => p1 > p2)(pts).toList
|
||||||
else
|
else
|
||||||
// Merge sort: O(n log n)
|
// Merge sort: O(n log n)
|
||||||
Util.msort((p1: Point, p2: Point) => p1 > p2)(pts.toList)
|
points = Util.msort((p1: Point, p2: Point) => p1 > p2)(pts.toList)
|
||||||
|
|
||||||
|
val deltaX = ALPHA * (xmax - xmin)
|
||||||
|
val deltaY = ALPHA * (ymax - ymin)
|
||||||
|
|
||||||
|
val p1 = Point(xmin - deltaX, ymin - deltaY)
|
||||||
|
val p2 = Point(xmax - deltaX, ymin - deltaY)
|
||||||
|
|
||||||
|
initialTriangle = new Triangle(Array(p2, points(0), p1), null)
|
||||||
|
points
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement sweep-line paradigm
|
// Implement sweep-line paradigm
|
||||||
|
@ -34,8 +34,8 @@ import scala.collection.mutable.HashSet
|
|||||||
|
|
||||||
import shapes.Point
|
import shapes.Point
|
||||||
|
|
||||||
class Mesh {
|
class Mesh(initialTriangle: Triangle) {
|
||||||
|
|
||||||
val map = HashSet.empty[Triangle]
|
val map = HashSet(initialTriangle)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
/* Poly2Tri
|
|
||||||
* Copyright (c) 2009, Mason Green
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
package org.poly2tri.cdt
|
|
||||||
|
|
||||||
import shapes.Point
|
|
||||||
|
|
||||||
// Triangle-based data structures have better performance than quad-edge structures
|
|
||||||
// See: Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator"
|
|
||||||
// "Triangulations in CGAL"
|
|
||||||
class Triangle(points: Array[Point], neighbors: Array[Triangle]) {
|
|
||||||
|
|
||||||
}
|
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.poly2tri.earClip
|
package org.poly2tri.earClip
|
||||||
|
|
||||||
import shapes.{Point, Triangle}
|
import shapes.Point
|
||||||
|
|
||||||
class EarClip {
|
class EarClip {
|
||||||
|
|
||||||
@ -313,3 +313,56 @@ class Poly(var x: Array[Float], var y: Array[Float], var nVertices: Int) {
|
|||||||
areaIsSet = false
|
areaIsSet = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Triangle(var x1: Float, var y1: Float, var x2: Float, var y2: Float, var x3: Float, var y3: Float) {
|
||||||
|
|
||||||
|
def this() = this(0,0,0,0,0,0)
|
||||||
|
|
||||||
|
val x = new Array[Float](3)
|
||||||
|
val y = new Array[Float](3)
|
||||||
|
|
||||||
|
// Automatically fixes orientation to ccw
|
||||||
|
|
||||||
|
val dx1 = x2-x1
|
||||||
|
val dx2 = x3-x1
|
||||||
|
val dy1 = y2-y1
|
||||||
|
val dy2 = y3-y1
|
||||||
|
val cross = dx1*dy2-dx2*dy1
|
||||||
|
val ccw = (cross>0)
|
||||||
|
if (ccw){
|
||||||
|
x(0) = x1; x(1) = x2; x(2) = x3;
|
||||||
|
y(0) = y1; y(1) = y2; y(2) = y3;
|
||||||
|
} else{
|
||||||
|
x(0) = x1; x(1) = x3; x(2) = x2;
|
||||||
|
y(0) = y1; y(1) = y3; y(2) = y2;
|
||||||
|
}
|
||||||
|
|
||||||
|
def set(t: Triangle) {
|
||||||
|
x(0) = t.x(0)
|
||||||
|
x(1) = t.x(1)
|
||||||
|
x(2) = t.x(2)
|
||||||
|
y(0) = t.y(0)
|
||||||
|
y(1) = t.y(1)
|
||||||
|
y(2) = t.y(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def containsPoint(_x: Float, _y: Float): Boolean = {
|
||||||
|
|
||||||
|
val vx2 = _x-x(0); val vy2 = _y-y(0);
|
||||||
|
val vx1 = x(1)-x(0); val vy1 = y(1)-y(0);
|
||||||
|
val vx0 = x(2)-x(0); val vy0 = y(2)-y(0);
|
||||||
|
|
||||||
|
val dot00 = vx0*vx0+vy0*vy0;
|
||||||
|
val dot01 = vx0*vx1+vy0*vy1;
|
||||||
|
val dot02 = vx0*vx2+vy0*vy2;
|
||||||
|
val dot11 = vx1*vx1+vy1*vy1;
|
||||||
|
val dot12 = vx1*vx2+vy1*vy2;
|
||||||
|
val invDenom = 1.0f / (dot00*dot11 - dot01*dot01);
|
||||||
|
val u = (dot11*dot02 - dot01*dot12)*invDenom;
|
||||||
|
val v = (dot00*dot12 - dot01*dot02)*invDenom;
|
||||||
|
|
||||||
|
return ((u>=0)&&(v>=0)&&(u+v<=1));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,54 +1,43 @@
|
|||||||
|
/* Poly2Tri
|
||||||
|
* Copyright (c) 2009, Mason Green
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package org.poly2tri.shapes
|
package org.poly2tri.shapes
|
||||||
|
|
||||||
class Triangle(var x1: Float, var y1: Float, var x2: Float, var y2: Float, var x3: Float, var y3: Float) {
|
import shapes.Point
|
||||||
|
|
||||||
def this() = this(0,0,0,0,0,0)
|
// Triangle-based data structures are know to have better performance than quad-edge structures
|
||||||
|
// See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator"
|
||||||
|
// "Triangulations in CGAL"
|
||||||
|
class Triangle(points: Array[Point], neighbors: Array[Triangle]) {
|
||||||
|
|
||||||
val x = new Array[Float](3)
|
// Flags to determine if an edge is the final Delauney edge
|
||||||
val y = new Array[Float](3)
|
val edges = new Array[Boolean](3)
|
||||||
|
|
||||||
// Automatically fixes orientation to ccw
|
|
||||||
|
|
||||||
val dx1 = x2-x1
|
|
||||||
val dx2 = x3-x1
|
|
||||||
val dy1 = y2-y1
|
|
||||||
val dy2 = y3-y1
|
|
||||||
val cross = dx1*dy2-dx2*dy1
|
|
||||||
val ccw = (cross>0)
|
|
||||||
if (ccw){
|
|
||||||
x(0) = x1; x(1) = x2; x(2) = x3;
|
|
||||||
y(0) = y1; y(1) = y2; y(2) = y3;
|
|
||||||
} else{
|
|
||||||
x(0) = x1; x(1) = x3; x(2) = x2;
|
|
||||||
y(0) = y1; y(1) = y3; y(2) = y2;
|
|
||||||
}
|
|
||||||
|
|
||||||
def set(t: Triangle) {
|
|
||||||
x(0) = t.x(0)
|
|
||||||
x(1) = t.x(1)
|
|
||||||
x(2) = t.x(2)
|
|
||||||
y(0) = t.y(0)
|
|
||||||
y(1) = t.y(1)
|
|
||||||
y(2) = t.y(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def containsPoint(_x: Float, _y: Float): Boolean = {
|
|
||||||
|
|
||||||
val vx2 = _x-x(0); val vy2 = _y-y(0);
|
|
||||||
val vx1 = x(1)-x(0); val vy1 = y(1)-y(0);
|
|
||||||
val vx0 = x(2)-x(0); val vy0 = y(2)-y(0);
|
|
||||||
|
|
||||||
val dot00 = vx0*vx0+vy0*vy0;
|
|
||||||
val dot01 = vx0*vx1+vy0*vy1;
|
|
||||||
val dot02 = vx0*vx2+vy0*vy2;
|
|
||||||
val dot11 = vx1*vx1+vy1*vy1;
|
|
||||||
val dot12 = vx1*vx2+vy1*vy2;
|
|
||||||
val invDenom = 1.0f / (dot00*dot11 - dot01*dot01);
|
|
||||||
val u = (dot11*dot02 - dot01*dot12)*invDenom;
|
|
||||||
val v = (dot00*dot12 - dot01*dot02)*invDenom;
|
|
||||||
|
|
||||||
return ((u>=0)&&(v>=0)&&(u+v<=1));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user