mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-12-31 23:23:30 +01:00
setup triangle, mesh, and advancing front classes
This commit is contained in:
parent
3576da476a
commit
f75a0a2974
@ -69,6 +69,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
var drawSegs = true
|
var drawSegs = true
|
||||||
var hiLighter = 0
|
var hiLighter = 0
|
||||||
var drawEarClip = false
|
var drawEarClip = false
|
||||||
|
var hertelMehlhorn = false
|
||||||
|
|
||||||
val nazcaMonkey = "data/nazca_monkey.dat"
|
val nazcaMonkey = "data/nazca_monkey.dat"
|
||||||
val bird = "data/bird.dat"
|
val bird = "data/bird.dat"
|
||||||
@ -114,11 +115,11 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
|
|
||||||
if(!debug && !drawEarClip) {
|
if(!debug && !drawEarClip) {
|
||||||
var i = 0
|
var i = 0
|
||||||
for(t <- tesselator.triangles) {
|
for(t <- tesselator.polygons) {
|
||||||
val triangle = new Polygon
|
val poly = new Polygon
|
||||||
t.foreach(p => triangle.addPoint(p.x, p.y))
|
t.foreach(p => poly.addPoint(p.x, p.y))
|
||||||
g.setColor(red)
|
g.setColor(red)
|
||||||
g.draw(triangle)
|
g.draw(poly)
|
||||||
}
|
}
|
||||||
} else if (debug && drawMap && !drawEarClip){
|
} else if (debug && drawMap && !drawEarClip){
|
||||||
for(mp <- tesselator.monoPolies) {
|
for(mp <- tesselator.monoPolies) {
|
||||||
@ -158,14 +159,14 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
// UP
|
// UP
|
||||||
if(key == 200) {
|
if(key == 200) {
|
||||||
hiLighter += 1
|
hiLighter += 1
|
||||||
if (hiLighter == tesselator.triangles.size)
|
if (hiLighter == tesselator.polygons.size)
|
||||||
hiLighter = 0
|
hiLighter = 0
|
||||||
}
|
}
|
||||||
// DOWN
|
// DOWN
|
||||||
if(key == 208) {
|
if(key == 208) {
|
||||||
hiLighter -= 1
|
hiLighter -= 1
|
||||||
if (hiLighter == -1)
|
if (hiLighter == -1)
|
||||||
hiLighter = tesselator.triangles.size-1
|
hiLighter = tesselator.polygons.size-1
|
||||||
}
|
}
|
||||||
if(c == 'm') drawMap = !drawMap
|
if(c == 'm') drawMap = !drawMap
|
||||||
if(c == '1') {currentModel = nazcaMonkey; selectModel}
|
if(c == '1') {currentModel = nazcaMonkey; selectModel}
|
||||||
@ -175,6 +176,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
if(c == '5') star
|
if(c == '5') star
|
||||||
if(c == 's') drawSegs = !drawSegs
|
if(c == 's') drawSegs = !drawSegs
|
||||||
if(c == 'e') {drawEarClip = !drawEarClip; selectModel}
|
if(c == 'e') {drawEarClip = !drawEarClip; selectModel}
|
||||||
|
if(c == 'h') {hertelMehlhorn = !hertelMehlhorn; selectModel}
|
||||||
}
|
}
|
||||||
|
|
||||||
def selectModel {
|
def selectModel {
|
||||||
@ -227,6 +229,8 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
segments += new Segment(p6, p7)
|
segments += new Segment(p6, p7)
|
||||||
|
|
||||||
tesselator = new Triangulator(segments)
|
tesselator = new Triangulator(segments)
|
||||||
|
tesselator.buildTriangles = hertelMehlhorn
|
||||||
|
|
||||||
val t1 = System.nanoTime
|
val t1 = System.nanoTime
|
||||||
tesselator process
|
tesselator process
|
||||||
val t2 = System.nanoTime
|
val t2 = System.nanoTime
|
||||||
@ -260,7 +264,9 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
segments += new Segment(p8, p9)
|
segments += new Segment(p8, p9)
|
||||||
segments += new Segment(p9, p10)
|
segments += new Segment(p9, p10)
|
||||||
segments += new Segment(p10, p1)
|
segments += new Segment(p10, p1)
|
||||||
|
|
||||||
tesselator = new Triangulator(segments)
|
tesselator = new Triangulator(segments)
|
||||||
|
tesselator.buildTriangles = hertelMehlhorn
|
||||||
|
|
||||||
val t1 = System.nanoTime
|
val t1 = System.nanoTime
|
||||||
tesselator process
|
tesselator process
|
||||||
@ -301,7 +307,9 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
segments += new Segment(p10, p11)
|
segments += new Segment(p10, p11)
|
||||||
segments += new Segment(p11, p12)
|
segments += new Segment(p11, p12)
|
||||||
segments += new Segment(p12, p1)
|
segments += new Segment(p12, p1)
|
||||||
|
|
||||||
tesselator = new Triangulator(segments)
|
tesselator = new Triangulator(segments)
|
||||||
|
tesselator.buildTriangles = hertelMehlhorn
|
||||||
|
|
||||||
val t1 = System.nanoTime
|
val t1 = System.nanoTime
|
||||||
tesselator process
|
tesselator process
|
||||||
@ -355,12 +363,14 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
|
|
||||||
// Sediel triangulation
|
// Sediel triangulation
|
||||||
tesselator = new Triangulator(segments)
|
tesselator = new Triangulator(segments)
|
||||||
|
tesselator.buildTriangles = hertelMehlhorn
|
||||||
|
|
||||||
val t1 = System.nanoTime
|
val t1 = System.nanoTime
|
||||||
tesselator.process
|
tesselator.process
|
||||||
val runTime = System.nanoTime - t1
|
val runTime = System.nanoTime - t1
|
||||||
|
|
||||||
println("Poly2Tri average (ms) = " + runTime*1e-6)
|
println("Poly2Tri average (ms) = " + runTime*1e-6)
|
||||||
println("Number of triangles = " + tesselator.triangles.size)
|
println("Number of triangles = " + tesselator.polygons.size)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
36
src/org/poly2tri/cdt/AFront.scala
Normal file
36
src/org/poly2tri/cdt/AFront.scala
Normal 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 {
|
||||||
|
|
||||||
|
}
|
39
src/org/poly2tri/cdt/Mesh.scala
Normal file
39
src/org/poly2tri/cdt/Mesh.scala
Normal 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]
|
||||||
|
|
||||||
|
}
|
40
src/org/poly2tri/cdt/Triangle.scala
Normal file
40
src/org/poly2tri/cdt/Triangle.scala
Normal 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]) {
|
||||||
|
|
||||||
|
}
|
@ -35,7 +35,7 @@ import scala.collection.mutable.{ArrayBuffer, Queue}
|
|||||||
import shapes.Point
|
import shapes.Point
|
||||||
|
|
||||||
// Doubly linked list
|
// Doubly linked list
|
||||||
class MonotoneMountain {
|
class MonotoneMountain(buildTriangles: Boolean) {
|
||||||
|
|
||||||
var tail, head: Point = null
|
var tail, head: Point = null
|
||||||
var size = 0
|
var size = 0
|
||||||
@ -45,6 +45,8 @@ class MonotoneMountain {
|
|||||||
val monoPoly = new ArrayBuffer[Point]
|
val monoPoly = new ArrayBuffer[Point]
|
||||||
// Triangles that constitute the mountain
|
// Triangles that constitute the mountain
|
||||||
val triangles = new ArrayBuffer[Array[Point]]
|
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
|
// Used to track which side of the line we are on
|
||||||
private var positive = false
|
private var positive = false
|
||||||
// Almost Pi!
|
// Almost Pi!
|
||||||
@ -86,7 +88,7 @@ class MonotoneMountain {
|
|||||||
|
|
||||||
// Partition a x-monotone mountain into triangles O(n)
|
// Partition a x-monotone mountain into triangles O(n)
|
||||||
// See "Computational Geometry in C", 2nd edition, by Joseph O'Rourke, page 52
|
// See "Computational Geometry in C", 2nd edition, by Joseph O'Rourke, page 52
|
||||||
def triangulate {
|
def process {
|
||||||
|
|
||||||
// Establish the proper sign
|
// Establish the proper sign
|
||||||
positive = angleSign
|
positive = angleSign
|
||||||
@ -106,6 +108,15 @@ class MonotoneMountain {
|
|||||||
p = p.next
|
p = p.next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(buildTriangles)
|
||||||
|
triangulate
|
||||||
|
else
|
||||||
|
hertelMehlhorn
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private def triangulate {
|
||||||
|
|
||||||
while(!convexPoints.isEmpty) {
|
while(!convexPoints.isEmpty) {
|
||||||
|
|
||||||
val ear = convexPoints.remove(0)
|
val ear = convexPoints.remove(0)
|
||||||
@ -123,7 +134,30 @@ class MonotoneMountain {
|
|||||||
}
|
}
|
||||||
assert(size <= 3, "Triangulation bug, please report")
|
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))
|
private def valid(p: Point) = (p != head && p != tail && convex(p))
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ import shapes.{Point, Segment, Trapezoid}
|
|||||||
|
|
||||||
class TrapezoidalMap {
|
class TrapezoidalMap {
|
||||||
|
|
||||||
// Trapezoid associated array
|
// Trapezoid container
|
||||||
val map = HashSet.empty[Trapezoid]
|
val map = HashSet.empty[Trapezoid]
|
||||||
// AABB margin
|
// AABB margin
|
||||||
var margin = 50f
|
var margin = 50f
|
||||||
|
@ -41,9 +41,11 @@ import shapes.{Point, Segment, Trapezoid}
|
|||||||
// "Computational Geometry in C", 2nd edition, by Joseph O'Rourke
|
// "Computational Geometry in C", 2nd edition, by Joseph O'Rourke
|
||||||
class Triangulator(segments: ArrayBuffer[Segment]) {
|
class Triangulator(segments: ArrayBuffer[Segment]) {
|
||||||
|
|
||||||
// Triangle decomposition list
|
// Convex polygon list
|
||||||
var triangles = new ArrayBuffer[Array[Point]]
|
var polygons = new ArrayBuffer[Array[Point]]
|
||||||
|
// Generate triangles vs non-convex polygons
|
||||||
|
// On by default
|
||||||
|
var buildTriangles = true
|
||||||
// Order and randomize the segments
|
// Order and randomize the segments
|
||||||
val segmentList = orderSegments
|
val segmentList = orderSegments
|
||||||
|
|
||||||
@ -147,7 +149,7 @@ class Triangulator(segments: ArrayBuffer[Segment]) {
|
|||||||
|
|
||||||
if(s.mPoints.size > 0) {
|
if(s.mPoints.size > 0) {
|
||||||
|
|
||||||
val mountain = new MonotoneMountain
|
val mountain = new MonotoneMountain(buildTriangles)
|
||||||
var k: List[Point] = null
|
var k: List[Point] = null
|
||||||
|
|
||||||
// Sorting is a perfromance hit. Literature says this can be accomplised in
|
// Sorting is a perfromance hit. Literature says this can be accomplised in
|
||||||
@ -169,13 +171,22 @@ class Triangulator(segments: ArrayBuffer[Segment]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Triangulate monotone mountain
|
// Triangulate monotone mountain
|
||||||
mountain.triangulate
|
mountain process
|
||||||
|
|
||||||
// Extract the triangles into a single list
|
if(buildTriangles) {
|
||||||
j = 0
|
// Extract the triangles into a single list
|
||||||
while(j < mountain.triangles.size) {
|
j = 0
|
||||||
triangles += mountain.triangles(j)
|
while(j < mountain.triangles.size) {
|
||||||
j += 1
|
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
|
xMonoPoly += mountain
|
||||||
|
Loading…
Reference in New Issue
Block a user