changed Seidel init and process

This commit is contained in:
zzzzrrr 2009-08-16 16:47:41 -04:00
parent e0f1c4facd
commit b530419280
5 changed files with 1084 additions and 43 deletions

View File

@ -580,7 +580,6 @@
82.9798 3.14365 82.9798 3.14365
81.8622 3.11751 81.8622 3.11751
80.976 2.96988 80.976 2.96988
80.0621 2.84425
81.0885 3.47024 81.0885 3.47024
81.9378 3.6489 81.9378 3.6489
82.4922 3.83974 82.4922 3.83974

1037
data/nazca_heron_old.dat Normal file

File diff suppressed because it is too large Load Diff

View File

@ -87,7 +87,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
val i18 = "data/i.18" val i18 = "data/i.18"
val tank = "data/tank.dat" val tank = "data/tank.dat"
var currentModel = tank var currentModel = nazcaHeron
var doCDT = true var doCDT = true
var mouseButton = 0 var mouseButton = 0
@ -378,11 +378,9 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
if(!drawEarClip) { if(!drawEarClip) {
// Sediel triangulation // Sediel triangulation
seidel = new Triangulator(segments) val t1 = System.nanoTime
seidel = new Triangulator(points)
val t1 = System.nanoTime val runTime = System.nanoTime - t1
seidel.process
val runTime = System.nanoTime - t1
println("Poly2Tri average (ms) = " + runTime*1e-6) println("Poly2Tri average (ms) = " + runTime*1e-6)
println("Number of triangles = " + seidel.polygons.size) println("Number of triangles = " + seidel.polygons.size)

View File

@ -75,7 +75,7 @@ object CDT {
new CDT(sortedPoints, segments, iTriangle) new CDT(sortedPoints, segments, iTriangle)
} }
// Create segments and connect end points; update edge event pointer // Create segments and connect end points; update edge event pointer
private def initSegments(points: ArrayBuffer[Point]): List[Segment] = { private def initSegments(points: ArrayBuffer[Point]): List[Segment] = {
var segments = List[Segment]() var segments = List[Segment]()
for(i <- 0 until points.size-1) { for(i <- 0 until points.size-1) {
@ -127,20 +127,14 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
private def sweep { private def sweep {
for(i <- 1 until points.size) { for(i <- 1 until points.size) {
try {
val point = points(i) val point = points(i)
// Process Point event // Process Point event
val node = pointEvent(point) val node = pointEvent(point)
if(i == CDT.clearPoint) {cleanTri = node.triangle; mesh.debug += cleanTri} if(i == CDT.clearPoint) {cleanTri = node.triangle; mesh.debug += cleanTri}
// Process edge events // Process edge events
point.edges.foreach(e => edgeEvent(e, node)) point.edges.foreach(e => edgeEvent(e, node))
} catch {
case e: Exception =>
throw new Exception("Suspect point = " + i)
}
} }
} }
// Final step in the sweep-line CDT algo // Final step in the sweep-line CDT algo
@ -176,7 +170,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
// Locate the first intersected triangle // Locate the first intersected triangle
val firstTriangle = node.triangle.locateFirst(edge) val firstTriangle = node.triangle.locateFirst(edge)
//if(firstTriangle != null)mesh.debug += firstTriangle
// Remove intersected triangles // Remove intersected triangles
if(firstTriangle != null && !firstTriangle.contains(edge)) { if(firstTriangle != null && !firstTriangle.contains(edge)) {
@ -342,27 +336,28 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
} }
// Scan left and right along AFront to fill holes // Scan left and right along AFront to fill holes
private def scanAFront(n: Node) { private def scanAFront(n: Node) = {
var node = n.next var node1 = n.next
// Update right // Update right
if(node.next != null) { if(node1.next != null) {
var angle = 0.0 var angle = 0.0
do { do {
angle = fill(node) angle = fill(node1)
node = node.next node1 = node1.next
} while(angle <= PI_2 && node.next != null) } while(angle <= PI_2 && node1.next != null)
} }
node = n.prev var node2 = n.prev
// Update left // Update left
if(node.prev != null) { if(node2.prev != null) {
var angle = 0.0 var angle = 0.0
do { do {
angle = fill(node) angle = fill(node2)
node = node.prev node2 = node2.prev
} while(angle <= PI_2 && node.prev != null) } while(angle <= PI_2 && node2.prev != null)
} }
} }
// Fill empty space with a triangle // Fill empty space with a triangle

View File

@ -39,15 +39,28 @@ import shapes.{Point, Segment, Trapezoid}
// algorithm for computing trapezoidal decompositions and for triangulating polygons" // algorithm for computing trapezoidal decompositions and for triangulating polygons"
// See also: "Computational Geometry", 3rd edition, by Mark de Berg et al, Chapter 6.2 // See also: "Computational Geometry", 3rd edition, by Mark de Berg et al, Chapter 6.2
// "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(points: ArrayBuffer[Point]) {
// Convex polygon list // Convex polygon list
var polygons = new ArrayBuffer[Array[Point]] var polygons = new ArrayBuffer[Array[Point]]
// Order and randomize the segments // Order and randomize the segments
val segmentList = orderSegments val segmentList = initSegments
// The trapezoidal map
def trapezoidMap = trapezoidalMap.map
// Trapezoid decomposition list
var trapezoids = new ArrayBuffer[Trapezoid]
// Initialize trapezoidal map and query structure
private val trapezoidalMap = new TrapezoidalMap
private val boundingBox = trapezoidalMap.boundingBox(segmentList)
private val queryGraph = new QueryGraph(Sink.init(boundingBox))
private val xMonoPoly = new ArrayBuffer[MonotoneMountain]
process
// Build the trapezoidal map and query graph // Build the trapezoidal map and query graph
def process { private def process {
var i = 0 var i = 0
while(i < segmentList.size) { while(i < segmentList.size) {
@ -117,11 +130,6 @@ class Triangulator(segments: ArrayBuffer[Segment]) {
//println("# triangles = " + triangles.size) //println("# triangles = " + triangles.size)
} }
// The trapezoidal map
def trapezoidMap = trapezoidalMap.map
// Trapezoid decomposition list
var trapezoids = new ArrayBuffer[Trapezoid]
// Monotone polygons - these are monotone mountains // Monotone polygons - these are monotone mountains
def monoPolies: ArrayBuffer[ArrayBuffer[Point]] = { def monoPolies: ArrayBuffer[ArrayBuffer[Point]] = {
val polies = new ArrayBuffer[ArrayBuffer[Point]] val polies = new ArrayBuffer[ArrayBuffer[Point]]
@ -130,12 +138,6 @@ class Triangulator(segments: ArrayBuffer[Segment]) {
return polies return polies
} }
// Initialize trapezoidal map and query structure
private val trapezoidalMap = new TrapezoidalMap
private val boundingBox = trapezoidalMap.boundingBox(segmentList)
private val queryGraph = new QueryGraph(Sink.init(boundingBox))
private val xMonoPoly = new ArrayBuffer[MonotoneMountain]
// Build a list of x-monotone mountains // Build a list of x-monotone mountains
private def createMountains { private def createMountains {
@ -190,7 +192,17 @@ class Triangulator(segments: ArrayBuffer[Segment]) {
} }
} }
private def orderSegments = { // Create segments and connect end points; update edge event pointer
private def initSegments: ArrayBuffer[Segment] = {
var segments = List[Segment]()
for(i <- 0 until points.size-1)
segments = new Segment(points(i), points(i+1)) :: segments
segments = new Segment(points.first, points.last) :: segments
orderSegments(segments)
}
private def orderSegments(segments: List[Segment]) = {
// Ignore vertical segments! // Ignore vertical segments!
val segs = new ArrayBuffer[Segment] val segs = new ArrayBuffer[Segment]
for(s <- segments) { for(s <- segments) {