fixed pointer bug

This commit is contained in:
zzzrrr 2009-07-15 17:35:10 -04:00
parent e484852d39
commit 735fe986b9
6 changed files with 65 additions and 52 deletions

View File

@ -43,8 +43,6 @@ 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]]
var angle = 0f
// Append a point to the list // Append a point to the list
def +=(point: Point) { def +=(point: Point) {
@ -123,16 +121,17 @@ class MonotoneMountain {
private def convex(p: Point) = { private def convex(p: Point) = {
val a = (p.next - p) val a = (p.next - p)
val b = (p.prev - p) val b = (p.prev - p)
angle = Math.atan2(b.y,b.x).toFloat - Math.atan2(a.y,a.x).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.toFloat if(angle < 0) while(angle < -Math.Pi) angle += Math.Pi
if(angle > 0) while(angle > Math.Pi) angle -= Math.Pi.toFloat if(angle > 0) while(angle > Math.Pi) angle -= Math.Pi
// For numerical robustness.... // 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) { if(p.y >= head.y) {
(angle < 0) cvx
} else { } else {
!(angle < 0) !cvx
} }
} }
private def lastTriangle { private def lastTriangle {

View File

@ -59,6 +59,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
var quit = false var quit = false
var debug = false var debug = false
var drawMap = false var drawMap = false
var hiLighter = 0
def init(container: GameContainer) { def init(container: GameContainer) {
snake snake
@ -92,11 +93,14 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
} }
if(!debug) { if(!debug) {
var i = 0
for(t <- tesselator.triangles) { for(t <- tesselator.triangles) {
val triangle = new Polygon val triangle = new Polygon
t.foreach(p => triangle.addPoint(p.x, p.y)) 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) g.draw(triangle)
i += 1
} }
} else { } else {
for(mp <- tesselator.monoPolies) { for(mp <- tesselator.monoPolies) {
@ -110,12 +114,27 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
} }
override def keyPressed(key:Int, c:Char) { override def keyPressed(key:Int, c:Char) {
// ESC
if(key == 1) quit = true if(key == 1) quit = true
// SPACE
if(key == 57) debug = !debug 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 == 'm') drawMap = !drawMap
if(c == '1') poly if(c == '1') {poly; hiLighter = 0}
if(c == '2') snake if(c == '2') {snake; hiLighter = 0}
if(c == '3') star if(c == '3') {star; hiLighter = 0}
} }
// Test #1 // Test #1
@ -143,18 +162,16 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
def star { def star {
val scale = 1.0f val p1 = new Point(350,75)
val displace = 0f val p2 = new Point(379,161)
val p1 = new Point(350,75)*scale+displace val p3 = new Point(469,161)
val p2 = new Point(379,161)*scale+displace val p4 = new Point(397,215)
val p3 = new Point(469,161)*scale+displace val p5 = new Point(423,301)
val p4 = new Point(397,215)*scale+displace val p6 = new Point(350,250)
val p5 = new Point(423,301)*scale+displace val p7 = new Point(277,301)
val p6 = new Point(350,250)*scale+displace val p8 = new Point(303,215)
val p7 = new Point(277,301)*scale+displace val p9 = new Point(231,161)
val p8 = new Point(303,215)*scale+displace val p10 = new Point(321,161)
val p9 = new Point(231,161)*scale+displace
val p10 = new Point(321,161)*scale+displace
val segments = new ArrayBuffer[Segment] val segments = new ArrayBuffer[Segment]
segments += new Segment(p1, p2) segments += new Segment(p1, p2)

View File

@ -48,7 +48,7 @@ class QueryGraph(var head: Node) {
if(s > trapezoids(j).rightPoint) { if(s > trapezoids(j).rightPoint) {
trapezoids += trapezoids(j).upperRight trapezoids += trapezoids(j).upperRight
} else { } else {
trapezoids += trapezoids(j).lowerRight trapezoids += trapezoids(j).lowerRight
} }
j += 1 j += 1
} }

View File

@ -41,18 +41,21 @@ class Trapezoid(val leftPoint: Point, var rightPoint: Point, val top: Segment, v
var upperRight: Trapezoid = null var upperRight: Trapezoid = null
var lowerRight: 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(upperLeft != null && upperLeft.top == top) upperLeft.upperRight = ul
if(lowerLeft != null && lowerLeft.bottom == bottom) lowerLeft.lowerRight = ll 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(upperRight != null && upperRight.top == top) upperRight.upperLeft = ur
if(lowerRight != null && lowerRight.bottom == bottom) lowerRight.lowerLeft = lr if(lowerRight != null && lowerRight.bottom == bottom) lowerRight.lowerLeft = lr
} }
def update(ul: Trapezoid, ll: Trapezoid, ur: Trapezoid, lr: Trapezoid) { def update(ul: Trapezoid, ll: Trapezoid, ur: Trapezoid, lr: Trapezoid) {
upperLeft = ul upperLeft = ul; if(ul != null) ul.upperRight = this
lowerLeft = ll lowerLeft = ll; if(ll != null) ll.lowerRight = this
upperRight = ur upperRight = ur; if(ur != null) ur.upperLeft = this
lowerRight = lr lowerRight = lr; if(lr != null) lr.lowerLeft = this
} }
def markNeighbors { def markNeighbors {

View File

@ -81,7 +81,6 @@ class TrapezoidalMap {
s.above = trapezoids(1) s.above = trapezoids(1)
s.below = trapezoids(2) s.below = trapezoids(2)
t.updateNeighbors(trapezoids(0), trapezoids(0), trapezoids(3), trapezoids(3))
trapezoids trapezoids
} }
@ -105,7 +104,6 @@ class TrapezoidalMap {
s.above = trapezoids(1) s.above = trapezoids(1)
s.below = trapezoids(2) s.below = trapezoids(2)
t.updateNeighbors(trapezoids(0), trapezoids(0), trapezoids(1), trapezoids(2))
trapezoids trapezoids
} }
@ -126,18 +124,18 @@ class TrapezoidalMap {
if(topCross) { if(topCross) {
trapezoids(0).upperRight = t.upperRight trapezoids(0).upperRight = t.upperRight
trapezoids(0).rightPoint = t.rightPoint if(t.upperRight != null) t.upperRight.upperLeft = trapezoids(0)
trapezoids(0).rightPoint = rp
} else { } else {
trapezoids(0).update(t.upperLeft, s.above, t.upperRight, null) trapezoids(0).update(t.upperLeft, s.above, t.upperRight, null)
if(s.above != null) s.above.lowerRight = trapezoids(0)
} }
if(bottomCross) { if(bottomCross) {
trapezoids(1).lowerRight = t.lowerRight trapezoids(1).lowerRight = t.lowerRight
trapezoids(1).rightPoint = t.rightPoint if(t.lowerRight != null) t.lowerRight.lowerLeft = trapezoids(1)
trapezoids(1).rightPoint = rp
} else { } else {
trapezoids(1).update(s.below, t.lowerLeft, null, t.lowerRight) trapezoids(1).update(s.below, t.lowerLeft, null, t.lowerRight)
if(s.below != null) s.below.upperRight = trapezoids(1)
} }
bCross = t.bottom bCross = t.bottom
@ -145,7 +143,6 @@ class TrapezoidalMap {
s.above = trapezoids(0) s.above = trapezoids(0)
s.below = trapezoids(1) s.below = trapezoids(1)
t.updateNeighbors(trapezoids(0), trapezoids(1), trapezoids(0), trapezoids(1))
trapezoids trapezoids
} }
@ -168,7 +165,6 @@ class TrapezoidalMap {
trapezoids(0).rightPoint = s.q trapezoids(0).rightPoint = s.q
} else { } else {
trapezoids(0).update(t.upperLeft, s.above, trapezoids(2), null) trapezoids(0).update(t.upperLeft, s.above, trapezoids(2), null)
if(s.above != null) s.above.lowerRight = trapezoids(0)
} }
if(bottomCross) { if(bottomCross) {
@ -176,14 +172,10 @@ class TrapezoidalMap {
trapezoids(1).rightPoint = s.q trapezoids(1).rightPoint = s.q
} else { } else {
trapezoids(1).update(s.below, t.lowerLeft, null, trapezoids(2)) 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) 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 trapezoids
} }

View File

@ -36,11 +36,12 @@ import scala.collection.mutable.ArrayBuffer
// algorithm for computing trapezoidal decompositions and for triangulating polygons" // algorithm for computing trapezoidal decompositions and for triangulating polygons"
class Triangulator(var segments: ArrayBuffer[Segment]) { class Triangulator(var segments: ArrayBuffer[Segment]) {
// Trapezoid decomposition list
var trapezoids : ArrayBuffer[Trapezoid] = null
// Triangle decomposition list // Triangle decomposition list
var triangles = new ArrayBuffer[Array[Point]] var triangles = new ArrayBuffer[Array[Point]]
// Order and randomize the segments
segments = orderSegments
// Build the trapezoidal map and query graph // Build the trapezoidal map and query graph
def process { def process {
@ -81,10 +82,14 @@ class Triangulator(var segments: ArrayBuffer[Segment]) {
for(i <- 0 until xMonoPoly.size) for(i <- 0 until xMonoPoly.size)
for(t <- xMonoPoly(i).triangles) for(t <- xMonoPoly(i).triangles)
triangles += t triangles += t
println("# triangles = " + triangles.size)
} }
// For debugging // The trapezoidal map
def trapezoidMap = trapezoidalMap.map def trapezoidMap = trapezoidalMap.map
// Trapezoid decomposition list
var trapezoids : ArrayBuffer[Trapezoid] = null
// 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]]
@ -99,8 +104,6 @@ class Triangulator(var segments: ArrayBuffer[Segment]) {
private val queryGraph = new QueryGraph(new Sink(boundingBox)) private val queryGraph = new QueryGraph(new Sink(boundingBox))
private val xMonoPoly = new ArrayBuffer[MonotoneMountain] private val xMonoPoly = new ArrayBuffer[MonotoneMountain]
segments = orderSegments
// Build a list of x-monotone mountains // Build a list of x-monotone mountains
private def createMountains { private def createMountains {
for(s <- segments) { for(s <- segments) {
@ -143,9 +146,8 @@ class Triangulator(var segments: ArrayBuffer[Segment]) {
s.p = s.q s.p = s.q
s.q = tmp s.q = tmp
segs += s segs += s
} else if(s.p.x < s.q.x) { } else if(s.p.x < s.q.x)
segs += s segs += s
}
} }
// This is actually important: See Seidel's paper // This is actually important: See Seidel's paper
Random.shuffle(segs) Random.shuffle(segs)