mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-05 22:09:52 +01:00
fixed pointer bug
This commit is contained in:
parent
e484852d39
commit
735fe986b9
@ -44,8 +44,6 @@ class MonotoneMountain {
|
|||||||
// 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) {
|
||||||
size match {
|
size match {
|
||||||
@ -123,15 +121,16 @@ 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,10 +146,9 @@ 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)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user