mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-12-28 13:43: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
|
||||
|
||||
val earClip = new EarClip
|
||||
var earClipResults: Array[Triangle] = null
|
||||
var earClipResults: Array[poly2tri.earClip.Triangle] = null
|
||||
|
||||
var polyX: ArrayBuffer[Float] = null
|
||||
var polyY: ArrayBuffer[Float] = null
|
||||
@ -376,9 +376,9 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
|
||||
// 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 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 polyY = Array(472f, 392f, 272f, 232f, 212f, 152f, 172f, 52f, 112f, 32f, 92f, 72f, 272f, 212f, 352f, 312f)
|
||||
|
||||
val earClipResults = new Array[Triangle](14)
|
||||
for(i <- 0 until earClipResults.size) earClipResults(i) = new Triangle
|
||||
val earClipResults = new Array[poly2tri.earClip.Triangle](14)
|
||||
for(i <- 0 until earClipResults.size) earClipResults(i) = new poly2tri.earClip.Triangle
|
||||
val t1 = System.nanoTime
|
||||
earClip.triangulatePolygon(polyX, polyY, polyX.size, earClipResults)
|
||||
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 polyY = Array(110f, 200f, 110f, 200f, 110f, 200f, 300f, 200f, 300f, 200f, 300f, 200f)
|
||||
|
||||
val earClipResults = new Array[Triangle](14)
|
||||
for(i <- 0 until earClipResults.size) earClipResults(i) = new Triangle
|
||||
val earClipResults = new Array[poly2tri.earClip.Triangle](14)
|
||||
for(i <- 0 until earClipResults.size) earClipResults(i) = new poly2tri.earClip.Triangle
|
||||
val t1 = System.nanoTime
|
||||
earClip.triangulatePolygon(polyX, polyY, polyX.size, earClipResults)
|
||||
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 polyY = Array(75f, 161f, 161f, 215f, 301f, 250f, 301f,215f, 161f, 161f)
|
||||
|
||||
val earClipResults = new Array[Triangle](14)
|
||||
for(i <- 0 until earClipResults.size) earClipResults(i) = new Triangle
|
||||
val earClipResults = new Array[poly2tri.earClip.Triangle](14)
|
||||
for(i <- 0 until earClipResults.size) earClipResults(i) = new poly2tri.earClip.Triangle
|
||||
val t1 = System.nanoTime
|
||||
earClip.triangulatePolygon(polyX, polyY, polyX.size, earClipResults)
|
||||
val t2 = System.nanoTime
|
||||
|
@ -32,7 +32,7 @@ package org.poly2tri.cdt
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
import shapes.{Segment, Point}
|
||||
import shapes.{Segment, Point, Triangle}
|
||||
import utils.Util
|
||||
|
||||
/**
|
||||
@ -42,10 +42,15 @@ import utils.Util
|
||||
*/
|
||||
class CDT(segments: ArrayBuffer[Segment]) {
|
||||
|
||||
// The initial triangle
|
||||
var initialTriangle: Triangle = null
|
||||
// The point list
|
||||
val points = init
|
||||
// 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
|
||||
@ -55,8 +60,8 @@ class CDT(segments: ArrayBuffer[Segment]) {
|
||||
// Initialize and sort point list
|
||||
private def init: List[Point] = {
|
||||
|
||||
var xmax, xmin = 0f
|
||||
var ymax, ymin = 0f
|
||||
var xmax, xmin = segments(0).p.x
|
||||
var ymax, ymin = segments(0).p.y
|
||||
val pts = new ArrayBuffer[Point]
|
||||
|
||||
for(i <- 0 until segments.size) {
|
||||
@ -74,18 +79,28 @@ class CDT(segments: ArrayBuffer[Segment]) {
|
||||
if(p.y < ymin) ymin = p.x
|
||||
if(q.y < ymin) ymin = q.x
|
||||
|
||||
|
||||
pts += shearTransform(p)
|
||||
pts += shearTransform(q)
|
||||
}
|
||||
|
||||
var points: List[Point] = null
|
||||
|
||||
if(pts.size < 10)
|
||||
// Insertion sort is one of the fastest algorithms for sorting arrays containing
|
||||
// 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
|
||||
// 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
|
||||
|
@ -34,8 +34,8 @@ import scala.collection.mutable.HashSet
|
||||
|
||||
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
|
||||
|
||||
import shapes.{Point, Triangle}
|
||||
import shapes.Point
|
||||
|
||||
class EarClip {
|
||||
|
||||
@ -313,3 +313,56 @@ class Poly(var x: Array[Float], var y: Array[Float], var nVertices: Int) {
|
||||
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
|
||||
|
||||
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
|
||||
import shapes.Point
|
||||
|
||||
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;
|
||||
}
|
||||
// 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]) {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
// Flags to determine if an edge is the final Delauney edge
|
||||
val edges = new Array[Boolean](3)
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user