From 96713f659572a9a65b098b5afd693e81b4780f6c Mon Sep 17 00:00:00 2001 From: Mason Date: Fri, 7 Aug 2009 15:39:29 -0400 Subject: [PATCH] fixed Math.abs collinear bug --- src/org/poly2tri/Poly2Tri.scala | 2 +- src/org/poly2tri/cdt/CDT.scala | 60 +++++++++++++------------- src/org/poly2tri/shapes/Triangle.scala | 19 +++++++- src/org/poly2tri/utils/Util.scala | 2 +- 4 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/org/poly2tri/Poly2Tri.scala b/src/org/poly2tri/Poly2Tri.scala index c4179d0..90852b9 100644 --- a/src/org/poly2tri/Poly2Tri.scala +++ b/src/org/poly2tri/Poly2Tri.scala @@ -75,7 +75,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { var drawSegs = true var hiLighter = 0 var drawEarClip = false - var drawCDT = false + var drawCDT = true val nazcaMonkey = "data/nazca_monkey.dat" val bird = "data/bird.dat" diff --git a/src/org/poly2tri/cdt/CDT.scala b/src/org/poly2tri/cdt/CDT.scala index 080e819..da4888e 100644 --- a/src/org/poly2tri/cdt/CDT.scala +++ b/src/org/poly2tri/cdt/CDT.scala @@ -276,7 +276,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian val dEdge = new Segment(point1, point2) T1.first markEdge dEdge T2.first markEdge dEdge - + println("cut") } else if(firstTriangle == null) { // No triangles are intersected by the edge; edge must lie outside the mesh @@ -308,7 +308,8 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian val dEdge = new Segment(point1, point2) T.first markEdge dEdge - } else if(firstTriangle.contains(edge)) { + } else { + // Triangle must contain the edge // Mark constrained edge firstTriangle markEdge edge } @@ -420,39 +421,38 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian val oPoint = t2 oppositePoint t1 - // 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) { + if(illegal(t1.points(1), oPoint, t1.points(2), t1.points(0))) { - println("legalize") - // Update neighbor pointers - val ccwNeighbor = t2.neighborCCW(oPoint) - - if(ccwNeighbor != null) { - val point = if(t1.points(0).x > oPoint.x) t1.points(1) else t1.points(2) - ccwNeighbor.updateNeighbors(oPoint, point, t1, mesh.debug) - t1.neighbors(1) = ccwNeighbor - } + // Prevent creation of collinear traingles + val c1 = t1.collinear(oPoint) + val c2 = t2.collinear(oPoint, t1.points(0)) + + if(!c1 && !c2) { - t2.rotateNeighborsCW(oPoint, t1) - - t1.neighbors(0) = t2 - t1.neighbors(2) = null - - // Flip edges and rotate everything clockwise - val point = t1.points(0) - t1.legalize(oPoint) - t2.legalize(oPoint, point) - - false + // Update neighbor pointers + val ccwNeighbor = t2.neighborCCW(oPoint) + + if(ccwNeighbor != null) { + //val point = if(t1.points(0).x > oPoint.x) t1.points(1) else t1.points(2) + ccwNeighbor.updateNeighbors(oPoint, t1.points(2), t1, mesh.debug) + t1.neighbors(1) = ccwNeighbor + } + + t2.rotateNeighborsCW(oPoint, t1) + + t1.neighbors(0) = t2 + t1.neighbors(2) = null + + // Flip edges and rotate everything clockwise + val point = t1.points(0) + t1.legalize(oPoint) + t2.legalize(oPoint, point) + return false + } } else { true } + true } // Final step in the sweep-line CDT algo diff --git a/src/org/poly2tri/shapes/Triangle.scala b/src/org/poly2tri/shapes/Triangle.scala index d0b405f..ff982f0 100644 --- a/src/org/poly2tri/shapes/Triangle.scala +++ b/src/org/poly2tri/shapes/Triangle.scala @@ -33,6 +33,8 @@ package org.poly2tri.shapes import scala.collection.mutable.HashSet import scala.collection.mutable.ArrayBuffer +import utils.Util + // Triangle-based data structures are know to have better performance than quad-edge structures // See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator" // "Triangulations in CGAL" @@ -54,8 +56,7 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) { neighbors(2) = triangle else { debug += triangle - debug += this - throw new Exception("Neighbor pointer error, please report!") + //throw new Exception("Neighbor pointer error, please report!") } } @@ -217,6 +218,20 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) { updateEdges } + // Make legalized triangle will not be collinear + def collinear(oPoint: Point): Boolean = Util.collinear(points(0), points(1), oPoint) + + // Make sure legalized triangle will not be collinear + def collinear(oPoint: Point, nPoint: Point): Boolean = { + if(oPoint == points(0)) { + Util.collinear(points(0), points(2), nPoint) + } else if (oPoint == points(1)) { + Util.collinear(points(0), points(1), nPoint) + } else { + Util.collinear(points(2), points(1), nPoint) + } + } + // Rotate neighbors clockwise around give point. Share diagnal with triangle def rotateNeighborsCW(oPoint: Point, triangle: Triangle) { if(oPoint == points(0)) { diff --git a/src/org/poly2tri/utils/Util.scala b/src/org/poly2tri/utils/Util.scala index 2565730..dc77ae9 100644 --- a/src/org/poly2tri/utils/Util.scala +++ b/src/org/poly2tri/utils/Util.scala @@ -51,7 +51,7 @@ object Util { // Determinant val d = a11*(a22-a32) - a12*(a21-a31) + (a21*a32-a31*a22) - if(Math.abs(d) <= COLLINEAR_SLOP) + if(d <= COLLINEAR_SLOP) true else false