From 8f8e8144bf2fc1fe7f6da7d881dc1604b67eb79f Mon Sep 17 00:00:00 2001 From: zzzzrrr Date: Tue, 25 Aug 2009 00:33:16 -0400 Subject: [PATCH] bug hunting --- src/org/poly2tri/Poly2Tri.scala | 12 +++-- src/org/poly2tri/cdt/CDT.scala | 70 ++++++++++++++++---------- src/org/poly2tri/shapes/Segment.scala | 24 +++++++++ src/org/poly2tri/shapes/Triangle.scala | 3 +- src/org/poly2tri/utils/Util.scala | 17 ++++++- 5 files changed, 92 insertions(+), 34 deletions(-) diff --git a/src/org/poly2tri/Poly2Tri.scala b/src/org/poly2tri/Poly2Tri.scala index e17b473..32c4d9a 100644 --- a/src/org/poly2tri/Poly2Tri.scala +++ b/src/org/poly2tri/Poly2Tri.scala @@ -210,10 +210,12 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { g.draw(triangle) }) - slCDT.cList.foreach(c => { - val circ = new Circle(c.x, c.y, 0.5f) + //slCDT.cList.foreach(c => { + for(i <- 0 until 9) { + val circ = new Circle(slCDT.cList(i).x, slCDT.cList(i).y, 0.5f) g.setColor(blue); g.draw(circ); g.fill(circ) - }) + } + //}) } @@ -437,9 +439,9 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { if(slCDT.cList.size > 1) { //slCDT.addPoint(slCDT.cList(0)) //slCDT.addPoint(slCDT.cList(1)) - for(i <- 0 until slCDT.cList.size) + for(i <- 0 until 9 /*slCDT.cList.size*/) slCDT.addPoint(slCDT.cList(i)) - //slCDT.triangulate + slCDT.triangulate } println("CDT average (ms) = " + runTime*1e-6) diff --git a/src/org/poly2tri/cdt/CDT.scala b/src/org/poly2tri/cdt/CDT.scala index 33968ed..7fe3c36 100644 --- a/src/org/poly2tri/cdt/CDT.scala +++ b/src/org/poly2tri/cdt/CDT.scala @@ -152,8 +152,8 @@ class CDT(polyLine: Array[Point], clearPoint: Point) { // Implement sweep-line private def sweep { - // 48 67 - val size = if(refine) 47 else points.size + // 49 69 + val size = if(refine) 50 else points.size for(i <- 1 until size) { @@ -187,7 +187,7 @@ class CDT(polyLine: Array[Point], clearPoint: Point) { if(t.thin) { val center = Util.circumcenter(t.points(0), t.points(1), t.points(2)) cList += center - //refine = true + refine = true //addPoint(center) //mesh.debug += t } @@ -218,7 +218,10 @@ class CDT(polyLine: Array[Point], clearPoint: Point) { private def edgeEvent(edge: Segment, node: Node) { // Locate the first intersected triangle - val firstTriangle = node.triangle.locateFirst(edge) + val firstTriangle = if(!node.triangle.contains(edge.q)) + node.triangle + else + node.triangle.locateFirst(edge) if(firstTriangle != null && !firstTriangle.contains(edge)) { @@ -306,57 +309,70 @@ class CDT(polyLine: Array[Point], clearPoint: Point) { nTriangles += pNode.triangle val ahead = (edge.p.x > edge.q.x) + var aboveEdge = false if(ahead) { + // Scan right pNode = pNode.next - while(pNode.point != edge.p) { + while(pNode.point != edge.p && !aboveEdge) { points += pNode.point nTriangles += pNode.triangle pNode = pNode.next + aboveEdge = edge < pNode.point } } else { + // Scal left pNode = pNode.prev - while(pNode.point != edge.p) { + while(pNode.point != edge.p && !aboveEdge) { points += pNode.point nTriangles += pNode.triangle pNode = pNode.prev + aboveEdge = edge < pNode.point } + nTriangles += pNode.triangle } - - /* - val s = new Segment(first.point, first.next.point) - if(s > point1) { - mesh.map -= first.triangle - first.triangle = first.triangle.neighborCW(first.point) - val t = first.triangle.neighborAcross(first.point) - val n = new Node(point1, t) - first.next = n - n.prev = first - n.next = first.next.next - n.next.prev = n + + val point2 = if(aboveEdge) { + val p1 = pNode.point + val p2 = if(ahead) pNode.prev.point else pNode.next.point + edge.intersect(p1, p2) + } else { + edge.p } - */ - // Triangulate empty areas. val T = new ArrayBuffer[Triangle] - triangulate(points.toArray, List(edge.q, edge.p), T) + triangulate(points.toArray, List(edge.q, point2), T) // Update neighbors edgeNeighbors(nTriangles, T) // Update advancing front - if(ahead) + if(ahead && !aboveEdge) aFront link (first, pNode, T.last) - else + else if(!ahead && !aboveEdge) aFront link (pNode, first, T.last) // Mark constrained edge - T.last markEdge(edge.q, edge.p) + T.last markEdge(edge.q, point2) - if(pNode.point != edge.p) { - println("span") - //edgeEvent(edge, pNode) + if(aboveEdge) { + val iNode = if(ahead) { + val n = new Node(point2, pNode.prev.triangle) + aFront link (first, n, T.last) + n.next = pNode + pNode.prev = n + n + } else { + val n = new Node(point2, pNode.next.triangle) + aFront link (n, first, T.last) + pNode.next = n + n.prev = pNode + n + } + val above = point2.y > edge.p.y + val e = if(above) new Segment(edge.p, point2) else { println("wtf"); new Segment(point2, edge.p)} + edgeEvent(e, iNode) } } else if(firstTriangle.contains(edge.q, edge.p)) { diff --git a/src/org/poly2tri/shapes/Segment.scala b/src/org/poly2tri/shapes/Segment.scala index 9487e29..2c36a9c 100644 --- a/src/org/poly2tri/shapes/Segment.scala +++ b/src/org/poly2tri/shapes/Segment.scala @@ -50,5 +50,29 @@ class Segment(var p: Point, var q: Point) { def > (point: Point) = (Math.floor(point.y) < Math.floor(slope * point.x + b)) // Determines if this segment lies below the given point def < (point: Point) = (Math.floor(point.y) > Math.floor(slope * point.x + b)) + + private def signedArea(a: Point, b: Point, c: Point): Float = + (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x) + + def intersect(c: Point, d: Point): Point = { + + val a = p + val b = q + + val a1 = signedArea(a, b, d) + val a2 = signedArea(a, b, c) + + if (a1 != 0.0f && a2 != 0.0f && a1*a2 < 0.0f) { + val a3 = signedArea(c, d, a) + val a4 = a3 + a2 - a1 + if (a3 * a4 < 0.0f) { + val t = a3 / (a3 - a4) + return a + ((b - a) * t) + } + } + + throw new Exception("Error") + } + } diff --git a/src/org/poly2tri/shapes/Triangle.scala b/src/org/poly2tri/shapes/Triangle.scala index b38a08a..73747af 100644 --- a/src/org/poly2tri/shapes/Triangle.scala +++ b/src/org/poly2tri/shapes/Triangle.scala @@ -125,7 +125,8 @@ class Triangle(val points: Array[Point]) { // Locate first triangle crossed by constrained edge def locateFirst(edge: Segment): Triangle = { - if(contains(edge)) this + if(contains(edge)) return this + if(edge.q == points(0)) search(points(1), points(2), edge, neighbors(2)) else if(edge.q == points(1)) diff --git a/src/org/poly2tri/utils/Util.scala b/src/org/poly2tri/utils/Util.scala index 4fa471f..db38567 100644 --- a/src/org/poly2tri/utils/Util.scala +++ b/src/org/poly2tri/utils/Util.scala @@ -283,8 +283,23 @@ object Util { throw new Exception("Points nearly collinear") } -} + } + def closestPtSegment(c: Point, a: Point, b: Point): Point = { + val ab = b - a + var t = (c - a) dot ab + if (t <= 0.0f) + return a + else { + val denom = ab dot ab + if (t >= denom) + return b + else { + t = t / denom + } + } + a + (ab * t) + } }