fixed rounding bug

This commit is contained in:
zzzzrrr 2009-07-22 13:18:51 -04:00
parent c67d9d1b86
commit a131fa7866
5 changed files with 104 additions and 43 deletions

View File

@ -42,8 +42,8 @@
-7.61308 2.03218 -7.61308 2.03218
-7.18844 1.45589 -7.18844 1.45589
-6.79414 1.12225 -6.79414 1.12225
-6.64248.788605 -6.64248 0.788605
-6.36951.242648 -6.36951 0.242648
-6.24818 -0.212317 -6.24818 -0.212317
-6.00553 -0.515627 -6.00553 -0.515627
-5.73255 -0.818936 -5.73255 -0.818936

View File

@ -57,17 +57,21 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
var tesselator: Triangulator = null var tesselator: Triangulator = null
var segments: ArrayBuffer[Segment] = null var segments: ArrayBuffer[Segment] = null
val earClip = new EarClip val earClip = new EarClip
var earClipResults: Array[Triangle] = null
var polyX: ArrayBuffer[Float] = null
var polyY: ArrayBuffer[Float] = null
var quit = false var quit = false
var debug = false var debug = false
var drawMap = false var drawMap = false
var drawSegs = true var drawSegs = true
var hiLighter = 0 var hiLighter = 0
var drawEarClip = false
def init(container: GameContainer) { def init(container: GameContainer) {
poly
earClipPoly
bird bird
} }
@ -100,7 +104,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
} }
} }
if(!debug) { if(!debug && !drawEarClip) {
var i = 0 var i = 0
for(t <- tesselator.triangles) { for(t <- tesselator.triangles) {
val triangle = new Polygon val triangle = new Polygon
@ -108,7 +112,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
g.setColor(red) g.setColor(red)
g.draw(triangle) g.draw(triangle)
} }
} else if (debug && drawMap){ } else if (debug && drawMap && !drawEarClip){
for(mp <- tesselator.monoPolies) { for(mp <- tesselator.monoPolies) {
val poly = new Polygon val poly = new Polygon
mp.foreach(p => poly.addPoint(p.x, p.y)) mp.foreach(p => poly.addPoint(p.x, p.y))
@ -117,13 +121,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
} }
} }
if(drawSegs) { if(drawEarClip)
g.setColor(green)
for(s <- segments)
g.drawLine(s.p.x,s.p.y,s.q.x,s.q.y)
}
/*
earClipResults.foreach(t => { earClipResults.foreach(t => {
val triangle = new Polygon val triangle = new Polygon
triangle.addPoint(t.x(0), t.y(0)) triangle.addPoint(t.x(0), t.y(0))
@ -131,7 +129,15 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
triangle.addPoint(t.x(2), t.y(2)) triangle.addPoint(t.x(2), t.y(2))
g.setColor(red) g.setColor(red)
g.draw(triangle) g.draw(triangle)
})*/ })
if(drawSegs) {
g.setColor(green)
for(i <- 0 until segments.size) {
val s = segments(i)
g.drawLine(s.p.x,s.p.y,s.q.x,s.q.y)
}
}
} }
@ -153,11 +159,12 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
hiLighter = tesselator.triangles.size-1 hiLighter = tesselator.triangles.size-1
} }
if(c == 'm') drawMap = !drawMap if(c == 'm') drawMap = !drawMap
if(c == '1') {poly; earClipPoly; hiLighter = 0} if(c == '1') bird
if(c == '2') {snake; hiLighter = 0} if(c == '2') {poly; earClipPoly}
if(c == '3') {star; hiLighter = 0} if(c == '3') snake
if(c == '4') star
if(c == 's') drawSegs = !drawSegs if(c == 's') drawSegs = !drawSegs
if(c == 'e') drawEarClip = !drawEarClip
} }
// Test #1 // Test #1
@ -204,7 +211,6 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
val t2 = System.nanoTime val t2 = System.nanoTime
println println
println("**Poly1**") println("**Poly1**")
println("Poly2Tri core (ms) = " + tesselator.coreTime*1e-6)
println("Poly2Tri total (ms) = " + (t2-t1)*1e-6) println("Poly2Tri total (ms) = " + (t2-t1)*1e-6)
} }
@ -240,7 +246,6 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
val t2 = System.nanoTime val t2 = System.nanoTime
println println
println("**Star**") println("**Star**")
println("Poly2Tri core (ms) = " + tesselator.coreTime*1e-6)
println("Poly2Tri total (ms) = " + (t2-t1)*1e-6) println("Poly2Tri total (ms) = " + (t2-t1)*1e-6)
} }
@ -282,15 +287,82 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
val t2 = System.nanoTime val t2 = System.nanoTime
println println
println("**Snake**") println("**Snake**")
println("Poly2Tri core (ms) = " + tesselator.coreTime*1e-6)
println("Poly2Tri total (ms) = " + (t2-t1)*1e-6) println("Poly2Tri total (ms) = " + (t2-t1)*1e-6)
} }
def bird { def bird {
for (line <- Source.fromFile("data/bird.dat").getLines) println("*** Bird ***")
print(line)
polyX = new ArrayBuffer[Float]
polyY = new ArrayBuffer[Float]
val scale = 25.0f
val center = Point(400, 300)
val angle = Math.Pi
for (line <- Source.fromFile("data/bird.dat").getLines) {
val s = line.replaceAll("\n", "")
val tokens = s.split("[ ]+")
if(tokens.size == 2) {
var x = tokens(0).toFloat
var y = tokens(1).toFloat
// Transform the shape
polyX += (Math.cos(angle)*x - Math.sin(angle)*y).toFloat * scale + center.x
polyY += (Math.sin(angle)*x + Math.cos(angle)*y).toFloat * scale + center.y
}
}
segments = new ArrayBuffer[Segment]
var i = 0
val numPoints = polyX.size
while(i < polyX.size-2) {
val p1 = new Point(polyX(i), polyY(i))
val p2 = new Point(polyX(i+1), polyY(i+1))
segments += new Segment(p1, p2)
i += 1
}
// Connect the end points
val p1 = segments(0).p
val p2 = segments(segments.length-1).q
segments += new Segment(p2, p1)
var t1: Float = 0f
var t2: Float = 0f
var runTime: Float = 0
val iterations = 100
println("Iteration count = " + iterations)
println("Seidel triangulation:")
for(i <- 0 until iterations) {
// Run benchmarks
tesselator = new Triangulator(segments)
t1 = System.nanoTime
tesselator.process
runTime += System.nanoTime - t1
}
println("Poly2Tri average (ms) = " + runTime*1e-6/iterations)
println("Number of triangles = " + tesselator.triangles.size)
println("Earclip triangulation:")
// Earclip
earClipResults = new Array[Triangle](500)
for(i <- 0 until earClipResults.size) earClipResults(i) = new Triangle
val xVerts = polyX.toArray.reverse
val yVerts = polyY.toArray.reverse
runTime = 0
for(i <- 0 until iterations) {
t1 = System.nanoTime
earClip.triangulatePolygon(xVerts, yVerts, xVerts.size, earClipResults)
runTime += System.nanoTime - t1
}
println("Earclip average (ms) = " + runTime*1e-6/iterations)
val numTriangles = earClip.triangulatePolygon(xVerts, yVerts, xVerts.size, earClipResults)
println("Number of triangles = " + numTriangles)
} }
def earClipPoly { def earClipPoly {

View File

@ -47,8 +47,8 @@ class Segment(var p: Point, var q: Point) {
val b = p.y - (p.x * slope) val b = p.y - (p.x * slope)
// Determines if this segment lies above the given point // Determines if this segment lies above the given point
def > (point: Point) = (point.y < Math.round(slope * point.x + b)) def > (point: Point) = (Math.floor(point.y) < Math.floor(slope * point.x + b))
// Determines if this segment lies below the given point // Determines if this segment lies below the given point
def < (point: Point) = (point.y > Math.round(slope * point.x + b)) def < (point: Point) = (Math.floor(point.y) > Math.floor(slope * point.x + b))
} }

View File

@ -36,11 +36,6 @@ 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(segments: ArrayBuffer[Segment]) { class Triangulator(segments: ArrayBuffer[Segment]) {
var sortTime = 0.0
var coreTime = 0.0
var trapezoidTime = 0.0
var markTime = 0.0
// Triangle decomposition list // Triangle decomposition list
var triangles = new ArrayBuffer[Array[Point]] var triangles = new ArrayBuffer[Array[Point]]
@ -50,13 +45,10 @@ class Triangulator(segments: ArrayBuffer[Segment]) {
// Build the trapezoidal map and query graph // Build the trapezoidal map and query graph
def process { def process {
val t1 = System.nanoTime
var i = 0 var i = 0
while(i < segmentList.size) { while(i < segmentList.size) {
val s = segmentList(i) val s = segmentList(i)
var traps = queryGraph.followSegment(s) var traps = queryGraph.followSegment(s)
// Remove trapezoids from trapezoidal Map // Remove trapezoids from trapezoidal Map
@ -104,8 +96,6 @@ class Triangulator(segments: ArrayBuffer[Segment]) {
} }
coreTime = System.nanoTime - t1
// Mark outside trapezoids // Mark outside trapezoids
for(t <- trapezoidalMap.map) for(t <- trapezoidalMap.map)
markOutside(t) markOutside(t)
@ -174,9 +164,7 @@ class Triangulator(segments: ArrayBuffer[Segment]) {
} }
// Triangulate monotone mountain // Triangulate monotone mountain
val t1 = System.nanoTime
mountain.triangulate mountain.triangulate
coreTime += System.nanoTime - t1
// Extract the triangles into a single list // Extract the triangles into a single list
j = 0 j = 0

View File

@ -33,6 +33,7 @@ package org.poly2tri
class XNode(point: Point, lChild: Node, rChild: Node) extends Node(lChild, rChild) { class XNode(point: Point, lChild: Node, rChild: Node) extends Node(lChild, rChild) {
override def locate(s: Segment): Sink = { override def locate(s: Segment): Sink = {
if(s.p.x >= point.x) { if(s.p.x >= point.x) {
// Move to the right in the graph // Move to the right in the graph
return right.locate(s) return right.locate(s)