mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-26 07:16:11 +01:00
fixed pointer bug
This commit is contained in:
parent
e484852d39
commit
735fe986b9
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user