setup triangle, mesh, and advancing front classes

This commit is contained in:
zzzzrrr 2009-07-28 11:09:19 -04:00
parent 3576da476a
commit f75a0a2974
7 changed files with 192 additions and 22 deletions

View File

@ -69,6 +69,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
var drawSegs = true
var hiLighter = 0
var drawEarClip = false
var hertelMehlhorn = false
val nazcaMonkey = "data/nazca_monkey.dat"
val bird = "data/bird.dat"
@ -114,11 +115,11 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
if(!debug && !drawEarClip) {
var i = 0
for(t <- tesselator.triangles) {
val triangle = new Polygon
t.foreach(p => triangle.addPoint(p.x, p.y))
for(t <- tesselator.polygons) {
val poly = new Polygon
t.foreach(p => poly.addPoint(p.x, p.y))
g.setColor(red)
g.draw(triangle)
g.draw(poly)
}
} else if (debug && drawMap && !drawEarClip){
for(mp <- tesselator.monoPolies) {
@ -158,14 +159,14 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
// UP
if(key == 200) {
hiLighter += 1
if (hiLighter == tesselator.triangles.size)
if (hiLighter == tesselator.polygons.size)
hiLighter = 0
}
// DOWN
if(key == 208) {
hiLighter -= 1
if (hiLighter == -1)
hiLighter = tesselator.triangles.size-1
hiLighter = tesselator.polygons.size-1
}
if(c == 'm') drawMap = !drawMap
if(c == '1') {currentModel = nazcaMonkey; selectModel}
@ -175,6 +176,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
if(c == '5') star
if(c == 's') drawSegs = !drawSegs
if(c == 'e') {drawEarClip = !drawEarClip; selectModel}
if(c == 'h') {hertelMehlhorn = !hertelMehlhorn; selectModel}
}
def selectModel {
@ -227,6 +229,8 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
segments += new Segment(p6, p7)
tesselator = new Triangulator(segments)
tesselator.buildTriangles = hertelMehlhorn
val t1 = System.nanoTime
tesselator process
val t2 = System.nanoTime
@ -260,7 +264,9 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
segments += new Segment(p8, p9)
segments += new Segment(p9, p10)
segments += new Segment(p10, p1)
tesselator = new Triangulator(segments)
tesselator.buildTriangles = hertelMehlhorn
val t1 = System.nanoTime
tesselator process
@ -301,7 +307,9 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
segments += new Segment(p10, p11)
segments += new Segment(p11, p12)
segments += new Segment(p12, p1)
tesselator = new Triangulator(segments)
tesselator.buildTriangles = hertelMehlhorn
val t1 = System.nanoTime
tesselator process
@ -355,12 +363,14 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
// Sediel triangulation
tesselator = new Triangulator(segments)
tesselator.buildTriangles = hertelMehlhorn
val t1 = System.nanoTime
tesselator.process
val runTime = System.nanoTime - t1
println("Poly2Tri average (ms) = " + runTime*1e-6)
println("Number of triangles = " + tesselator.triangles.size)
println("Number of triangles = " + tesselator.polygons.size)
} else {

View File

@ -0,0 +1,36 @@
/* 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
// Advancing front
class AFront {
}

View File

@ -0,0 +1,39 @@
/* 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 scala.collection.mutable.HashSet
class Mesh {
val map = HashSet.empty[Triangle]
}

View File

@ -0,0 +1,40 @@
/* 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]) {
}

View File

@ -35,7 +35,7 @@ import scala.collection.mutable.{ArrayBuffer, Queue}
import shapes.Point
// Doubly linked list
class MonotoneMountain {
class MonotoneMountain(buildTriangles: Boolean) {
var tail, head: Point = null
var size = 0
@ -45,6 +45,8 @@ class MonotoneMountain {
val monoPoly = new ArrayBuffer[Point]
// Triangles that constitute the mountain
val triangles = new ArrayBuffer[Array[Point]]
// Convex polygons that constitute the mountain
val convexPolies = new ArrayBuffer[Array[Point]]
// Used to track which side of the line we are on
private var positive = false
// Almost Pi!
@ -86,7 +88,7 @@ class MonotoneMountain {
// Partition a x-monotone mountain into triangles O(n)
// See "Computational Geometry in C", 2nd edition, by Joseph O'Rourke, page 52
def triangulate {
def process {
// Establish the proper sign
positive = angleSign
@ -105,7 +107,16 @@ class MonotoneMountain {
if(convex(p)) convexPoints += p
p = p.next
}
if(buildTriangles)
triangulate
else
hertelMehlhorn
}
private def triangulate {
while(!convexPoints.isEmpty) {
val ear = convexPoints.remove(0)
@ -123,7 +134,30 @@ class MonotoneMountain {
}
assert(size <= 3, "Triangulation bug, please report")
}
}
private def hertelMehlhorn {
while(!convexPoints.isEmpty) {
val ear = convexPoints.remove(0)
val a = ear.prev
val b = ear
val c = ear.next
val triangle = Array(a, b, c)
convexPolies += triangle
// Remove ear, update angles and convex list
remove(ear)
}
val polygon = new Array[Point](size)
var p = head
for(i <- 0 until size) {
polygon(i) = p
p = p.next
}
convexPolies += polygon
}
private def valid(p: Point) = (p != head && p != tail && convex(p))

View File

@ -38,7 +38,7 @@ import shapes.{Point, Segment, Trapezoid}
class TrapezoidalMap {
// Trapezoid associated array
// Trapezoid container
val map = HashSet.empty[Trapezoid]
// AABB margin
var margin = 50f

View File

@ -41,9 +41,11 @@ import shapes.{Point, Segment, Trapezoid}
// "Computational Geometry in C", 2nd edition, by Joseph O'Rourke
class Triangulator(segments: ArrayBuffer[Segment]) {
// Triangle decomposition list
var triangles = new ArrayBuffer[Array[Point]]
// Convex polygon list
var polygons = new ArrayBuffer[Array[Point]]
// Generate triangles vs non-convex polygons
// On by default
var buildTriangles = true
// Order and randomize the segments
val segmentList = orderSegments
@ -147,7 +149,7 @@ class Triangulator(segments: ArrayBuffer[Segment]) {
if(s.mPoints.size > 0) {
val mountain = new MonotoneMountain
val mountain = new MonotoneMountain(buildTriangles)
var k: List[Point] = null
// Sorting is a perfromance hit. Literature says this can be accomplised in
@ -169,13 +171,22 @@ class Triangulator(segments: ArrayBuffer[Segment]) {
}
// Triangulate monotone mountain
mountain.triangulate
mountain process
// Extract the triangles into a single list
j = 0
while(j < mountain.triangles.size) {
triangles += mountain.triangles(j)
j += 1
if(buildTriangles) {
// Extract the triangles into a single list
j = 0
while(j < mountain.triangles.size) {
polygons += mountain.triangles(j)
j += 1
}
} else {
// Extract the convex polygons into a single list
j = 0
while(j < mountain.convexPolies.size) {
polygons += mountain.convexPolies(j)
j += 1
}
}
xMonoPoly += mountain