From c909954b2f427cf13a3d131c6f1a7f3eafed4f24 Mon Sep 17 00:00:00 2001 From: Mason Date: Fri, 7 Aug 2009 14:09:17 -0400 Subject: [PATCH] fixed legalization bug --- src/org/poly2tri/cdt/CDT.scala | 27 +++++++++++++------------- src/org/poly2tri/shapes/Triangle.scala | 6 ++---- src/org/poly2tri/utils/Util.scala | 16 ++++++--------- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/org/poly2tri/cdt/CDT.scala b/src/org/poly2tri/cdt/CDT.scala index 36c8557..3cfa39e 100644 --- a/src/org/poly2tri/cdt/CDT.scala +++ b/src/org/poly2tri/cdt/CDT.scala @@ -126,7 +126,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian // Implement sweep-line private def sweep { //var cTri: Triangle = null - for(i <- 1 until 15 /*points.size*/) { + for(i <- 1 until points.size) { val point = points(i) // Process Point event var triangle: Triangle = null @@ -149,9 +149,6 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian val node = aFront.locate(point) - // Avoid triangles that are almost collinear - if(!Util.collinear(point, node.point, node.next.point)) { - // Projected point coincides with existing point; create two triangles if(point.x == node.point.x && node.prev != null) { @@ -217,11 +214,6 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian scanAFront(newNode) newNode.triangle } - - } else { - println("bad triangle") - null - } } // EdgeEvent @@ -412,9 +404,10 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian val sinA = v1 cross v2 val sinB = v3 cross v4 - //println((cosA*sinB + sinA*cosB)) - // Some small number - if((cosA*sinB + sinA*cosB) < -10f) + + // Small negative number to prevent swapping + // in nearly neutral cases + if((cosA*sinB + sinA*cosB) < -0.01f) true else false @@ -426,7 +419,15 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian val oPoint = t2 oppositePoint t1 - if(illegal(t1.points(1), oPoint, t1.points(2), t1.points(0))) { + // Prevent creation of collinear traingles + val c1 = Util.collinear(t1.points(0), t1.points(1), oPoint) + val c2 = Util.collinear(t2.points(0), t2.points(1), oPoint) + val c3 = Util.collinear(t2.points(1), t2.points(2), oPoint) + val c4 = Util.collinear(t2.points(0), t2.points(2), oPoint) + val collinear = !(c1 && c2 && c3 && c4) + + if(illegal(t1.points(1), oPoint, t1.points(2), t1.points(0)) && !collinear) { + println("legalize") // Update neighbor pointers val ccwNeighbor = t2.neighborCCW(oPoint) diff --git a/src/org/poly2tri/shapes/Triangle.scala b/src/org/poly2tri/shapes/Triangle.scala index c7a7917..7b8d315 100644 --- a/src/org/poly2tri/shapes/Triangle.scala +++ b/src/org/poly2tri/shapes/Triangle.scala @@ -45,7 +45,7 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) { var clean = false // Update neighbor pointers - def updateNeighbors(ccwPoint: Point, cwPoint: Point, triangle: Triangle, mesh: HashSet[Triangle]) { + def updateNeighbors(ccwPoint: Point, cwPoint: Point, triangle: Triangle, debug: HashSet[Triangle]) { if((ccwPoint == points(2) && cwPoint == points(1)) || (ccwPoint == points(1) && cwPoint == points(2))) neighbors(0) = triangle else if((ccwPoint == points(0) && cwPoint == points(2)) || (ccwPoint == points(2) && cwPoint == points(0))) @@ -53,9 +53,7 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) { else if((ccwPoint == points(0) && cwPoint == points(1)) || (ccwPoint == points(1) && cwPoint == points(0))) neighbors(2) = triangle else { - mesh += triangle - println(ccwPoint + "," + cwPoint) - printDebug + debug += triangle throw new Exception("Neighbor update error") } } diff --git a/src/org/poly2tri/utils/Util.scala b/src/org/poly2tri/utils/Util.scala index fd600af..d9bc795 100644 --- a/src/org/poly2tri/utils/Util.scala +++ b/src/org/poly2tri/utils/Util.scala @@ -7,7 +7,8 @@ import shapes.Point object Util { - val COLLINEAR_SLOP = 10f + // Almost zero + val COLLINEAR_SLOP = 0.1f // From "Scala By Example," by Martin Odersky def msort[A](less: (A, A) => Boolean)(xs: List[A]): List[A] = { @@ -39,23 +40,18 @@ object Util { // Tests if the given points are collinear def collinear(p1: Point, p2: Point, p3: Point): Boolean = { - // 3x3 matrix + // 3x2 matrix val a11 = p1.x val a12 = p1.y - val a13 = 1f val a21 = p2.x val a22 = p2.y - val a23 = 1f val a31 = p3.x val a32 = p3.y - val a33 = 1f // Determinant - val d = a11*(a22*a33 - a32*a23) - a12*(a21*a33-a31*a23) + a13*(a21*a32-a31*a22) - - println("Determinant = " + d) - - if(d <= COLLINEAR_SLOP) { + val d = a11*(a22-a32) - a12*(a21-a31) + (a21*a32-a31*a22) + + if(Math.abs(d) <= COLLINEAR_SLOP) { true } else { false