From 735fe986b9dbb82ca945a1a343eb61f4848cb777 Mon Sep 17 00:00:00 2001 From: zzzrrr Date: Wed, 15 Jul 2009 17:35:10 -0400 Subject: [PATCH] fixed pointer bug --- src/org/poly2tri/MonoToneMountain.scala | 17 ++++----- src/org/poly2tri/Poly2Tri.scala | 49 +++++++++++++++++-------- src/org/poly2tri/QueryGraph.scala | 2 +- src/org/poly2tri/Trapezoid.scala | 13 ++++--- src/org/poly2tri/TrapezoidalMap.scala | 18 +++------ src/org/poly2tri/Triangulator.scala | 18 +++++---- 6 files changed, 65 insertions(+), 52 deletions(-) diff --git a/src/org/poly2tri/MonoToneMountain.scala b/src/org/poly2tri/MonoToneMountain.scala index 2aec0b8..e6176ce 100644 --- a/src/org/poly2tri/MonoToneMountain.scala +++ b/src/org/poly2tri/MonoToneMountain.scala @@ -43,8 +43,6 @@ class MonotoneMountain { val monoPoly = new ArrayBuffer[Point] // Triangles that constitute the mountain val triangles = new ArrayBuffer[Array[Point]] - - var angle = 0f // Append a point to the list def +=(point: Point) { @@ -123,16 +121,17 @@ class MonotoneMountain { private def convex(p: Point) = { val a = (p.next - p) val b = (p.prev - p) - angle = Math.atan2(b.y,b.x).toFloat - Math.atan2(a.y,a.x).toFloat - if(angle < 0) while(angle < -Math.Pi) angle += Math.Pi.toFloat - if(angle > 0) while(angle > Math.Pi) angle -= Math.Pi.toFloat + var angle = Math.atan2(b.y,b.x) - Math.atan2(a.y,a.x) + if(angle < 0) while(angle < -Math.Pi) angle += Math.Pi + if(angle > 0) while(angle > Math.Pi) angle -= Math.Pi // For numerical robustness.... - angle = 0.01f * Math.round( angle * 10.0f) + angle = 0.1 * Math.round( angle * 10.0) + val cvx = (angle < 0) if(p.y >= head.y) { - (angle < 0) + cvx } else { - !(angle < 0) - } + !cvx + } } private def lastTriangle { diff --git a/src/org/poly2tri/Poly2Tri.scala b/src/org/poly2tri/Poly2Tri.scala index 3cef552..3daaba3 100644 --- a/src/org/poly2tri/Poly2Tri.scala +++ b/src/org/poly2tri/Poly2Tri.scala @@ -59,6 +59,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { var quit = false var debug = false var drawMap = false + var hiLighter = 0 def init(container: GameContainer) { snake @@ -92,11 +93,14 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { } if(!debug) { + var i = 0 for(t <- tesselator.triangles) { val triangle = new Polygon t.foreach(p => triangle.addPoint(p.x, p.y)) - g.setColor(red) + val color = if(i == hiLighter) blue else red + g.setColor(color) g.draw(triangle) + i += 1 } } else { for(mp <- tesselator.monoPolies) { @@ -110,12 +114,27 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { } override def keyPressed(key:Int, c:Char) { + // ESC if(key == 1) quit = true + // SPACE if(key == 57) debug = !debug + // UP + if(key == 200) { + hiLighter += 1 + if (hiLighter == tesselator.triangles.size) + hiLighter = 0 + } + // DOWN + if(key == 208) { + hiLighter -= 1 + if (hiLighter == -1) + hiLighter = tesselator.triangles.size-1 + } if(c == 'm') drawMap = !drawMap - if(c == '1') poly - if(c == '2') snake - if(c == '3') star + if(c == '1') {poly; hiLighter = 0} + if(c == '2') {snake; hiLighter = 0} + if(c == '3') {star; hiLighter = 0} + } // Test #1 @@ -143,18 +162,16 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { def star { - val scale = 1.0f - val displace = 0f - val p1 = new Point(350,75)*scale+displace - val p2 = new Point(379,161)*scale+displace - val p3 = new Point(469,161)*scale+displace - val p4 = new Point(397,215)*scale+displace - val p5 = new Point(423,301)*scale+displace - val p6 = new Point(350,250)*scale+displace - val p7 = new Point(277,301)*scale+displace - val p8 = new Point(303,215)*scale+displace - val p9 = new Point(231,161)*scale+displace - val p10 = new Point(321,161)*scale+displace + val p1 = new Point(350,75) + val p2 = new Point(379,161) + val p3 = new Point(469,161) + val p4 = new Point(397,215) + val p5 = new Point(423,301) + val p6 = new Point(350,250) + val p7 = new Point(277,301) + val p8 = new Point(303,215) + val p9 = new Point(231,161) + val p10 = new Point(321,161) val segments = new ArrayBuffer[Segment] segments += new Segment(p1, p2) diff --git a/src/org/poly2tri/QueryGraph.scala b/src/org/poly2tri/QueryGraph.scala index dd2e127..f950b5c 100644 --- a/src/org/poly2tri/QueryGraph.scala +++ b/src/org/poly2tri/QueryGraph.scala @@ -48,7 +48,7 @@ class QueryGraph(var head: Node) { if(s > trapezoids(j).rightPoint) { trapezoids += trapezoids(j).upperRight } else { - trapezoids += trapezoids(j).lowerRight + trapezoids += trapezoids(j).lowerRight } j += 1 } diff --git a/src/org/poly2tri/Trapezoid.scala b/src/org/poly2tri/Trapezoid.scala index c179d28..5e6b1b8 100644 --- a/src/org/poly2tri/Trapezoid.scala +++ b/src/org/poly2tri/Trapezoid.scala @@ -41,18 +41,21 @@ class Trapezoid(val leftPoint: Point, var rightPoint: Point, val top: Segment, v var upperRight: Trapezoid = null var lowerRight: Trapezoid = null - def updateNeighbors(ul: Trapezoid, ll: Trapezoid, ur: Trapezoid, lr: Trapezoid) { + def updateLeftNeighbors(ul: Trapezoid, ll: Trapezoid) { if(upperLeft != null && upperLeft.top == top) upperLeft.upperRight = ul if(lowerLeft != null && lowerLeft.bottom == bottom) lowerLeft.lowerRight = ll + } + + def updateRightNeighbors(ur: Trapezoid, lr: Trapezoid) { if(upperRight != null && upperRight.top == top) upperRight.upperLeft = ur if(lowerRight != null && lowerRight.bottom == bottom) lowerRight.lowerLeft = lr } def update(ul: Trapezoid, ll: Trapezoid, ur: Trapezoid, lr: Trapezoid) { - upperLeft = ul - lowerLeft = ll - upperRight = ur - lowerRight = lr + upperLeft = ul; if(ul != null) ul.upperRight = this + lowerLeft = ll; if(ll != null) ll.lowerRight = this + upperRight = ur; if(ur != null) ur.upperLeft = this + lowerRight = lr; if(lr != null) lr.lowerLeft = this } def markNeighbors { diff --git a/src/org/poly2tri/TrapezoidalMap.scala b/src/org/poly2tri/TrapezoidalMap.scala index 7af7bb3..e74686c 100644 --- a/src/org/poly2tri/TrapezoidalMap.scala +++ b/src/org/poly2tri/TrapezoidalMap.scala @@ -81,7 +81,6 @@ class TrapezoidalMap { s.above = trapezoids(1) s.below = trapezoids(2) - t.updateNeighbors(trapezoids(0), trapezoids(0), trapezoids(3), trapezoids(3)) trapezoids } @@ -105,7 +104,6 @@ class TrapezoidalMap { s.above = trapezoids(1) s.below = trapezoids(2) - t.updateNeighbors(trapezoids(0), trapezoids(0), trapezoids(1), trapezoids(2)) trapezoids } @@ -126,18 +124,18 @@ class TrapezoidalMap { if(topCross) { trapezoids(0).upperRight = t.upperRight - trapezoids(0).rightPoint = t.rightPoint + if(t.upperRight != null) t.upperRight.upperLeft = trapezoids(0) + trapezoids(0).rightPoint = rp } else { trapezoids(0).update(t.upperLeft, s.above, t.upperRight, null) - if(s.above != null) s.above.lowerRight = trapezoids(0) } if(bottomCross) { trapezoids(1).lowerRight = t.lowerRight - trapezoids(1).rightPoint = t.rightPoint + if(t.lowerRight != null) t.lowerRight.lowerLeft = trapezoids(1) + trapezoids(1).rightPoint = rp } else { trapezoids(1).update(s.below, t.lowerLeft, null, t.lowerRight) - if(s.below != null) s.below.upperRight = trapezoids(1) } bCross = t.bottom @@ -145,7 +143,6 @@ class TrapezoidalMap { s.above = trapezoids(0) s.below = trapezoids(1) - t.updateNeighbors(trapezoids(0), trapezoids(1), trapezoids(0), trapezoids(1)) trapezoids } @@ -168,7 +165,6 @@ class TrapezoidalMap { trapezoids(0).rightPoint = s.q } else { trapezoids(0).update(t.upperLeft, s.above, trapezoids(2), null) - if(s.above != null) s.above.lowerRight = trapezoids(0) } if(bottomCross) { @@ -176,14 +172,10 @@ class TrapezoidalMap { trapezoids(1).rightPoint = s.q } else { trapezoids(1).update(s.below, t.lowerLeft, null, trapezoids(2)) - if(s.below != null) s.below.upperRight = trapezoids(1) } + trapezoids(2).update(trapezoids(0), trapezoids(1), t.upperRight, t.lowerRight) - s.above = trapezoids(0) - s.below = trapezoids(1) - - t.updateNeighbors(trapezoids(0), trapezoids(1), trapezoids(2), trapezoids(2)) trapezoids } diff --git a/src/org/poly2tri/Triangulator.scala b/src/org/poly2tri/Triangulator.scala index 5715de8..07248fc 100644 --- a/src/org/poly2tri/Triangulator.scala +++ b/src/org/poly2tri/Triangulator.scala @@ -36,11 +36,12 @@ import scala.collection.mutable.ArrayBuffer // algorithm for computing trapezoidal decompositions and for triangulating polygons" class Triangulator(var segments: ArrayBuffer[Segment]) { - // Trapezoid decomposition list - var trapezoids : ArrayBuffer[Trapezoid] = null // Triangle decomposition list var triangles = new ArrayBuffer[Array[Point]] + // Order and randomize the segments + segments = orderSegments + // Build the trapezoidal map and query graph def process { @@ -81,10 +82,14 @@ class Triangulator(var segments: ArrayBuffer[Segment]) { for(i <- 0 until xMonoPoly.size) for(t <- xMonoPoly(i).triangles) triangles += t + + println("# triangles = " + triangles.size) } - // For debugging + // The trapezoidal map def trapezoidMap = trapezoidalMap.map + // Trapezoid decomposition list + var trapezoids : ArrayBuffer[Trapezoid] = null // Monotone polygons - these are monotone mountains def monoPolies: ArrayBuffer[ArrayBuffer[Point]] = { val polies = new ArrayBuffer[ArrayBuffer[Point]] @@ -99,8 +104,6 @@ class Triangulator(var segments: ArrayBuffer[Segment]) { private val queryGraph = new QueryGraph(new Sink(boundingBox)) private val xMonoPoly = new ArrayBuffer[MonotoneMountain] - segments = orderSegments - // Build a list of x-monotone mountains private def createMountains { for(s <- segments) { @@ -143,9 +146,8 @@ class Triangulator(var segments: ArrayBuffer[Segment]) { s.p = s.q s.q = tmp segs += s - } else if(s.p.x < s.q.x) { - segs += s - } + } else if(s.p.x < s.q.x) + segs += s } // This is actually important: See Seidel's paper Random.shuffle(segs)