From 6757b713a02aa3874b5531f8a424e68914778038 Mon Sep 17 00:00:00 2001 From: zzzzrrr Date: Sat, 8 Aug 2009 20:50:41 -0400 Subject: [PATCH] fixed edge avent AFront update --- src/org/poly2tri/cdt/AFront.scala | 2 +- src/org/poly2tri/cdt/CDT.scala | 112 +++++++++++++++++++------ src/org/poly2tri/shapes/Triangle.scala | 17 ++-- 3 files changed, 95 insertions(+), 36 deletions(-) diff --git a/src/org/poly2tri/cdt/AFront.scala b/src/org/poly2tri/cdt/AFront.scala index 43ea6b6..2eb6c0c 100644 --- a/src/org/poly2tri/cdt/AFront.scala +++ b/src/org/poly2tri/cdt/AFront.scala @@ -53,7 +53,7 @@ class AFront(iTriangle: Triangle) { return node node = node.next } - throw new Exception("Advancing front error: point not found") + null } def insert(tuple: Tuple3[Point, Triangle, Node]) = { diff --git a/src/org/poly2tri/cdt/CDT.scala b/src/org/poly2tri/cdt/CDT.scala index abde848..ea601c6 100644 --- a/src/org/poly2tri/cdt/CDT.scala +++ b/src/org/poly2tri/cdt/CDT.scala @@ -157,7 +157,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian private def pointEvent(point: Point): Triangle = { val node = aFront.locate(point) - + /* // Projected point coincides with existing point; create two triangles if(point.x == node.point.x && node.prev != null) { @@ -190,7 +190,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian newNode.triangle } else { - + */ // Projected point hits advancing front; create new triangle val cwPoint = node.next.point val ccwPoint = node.point @@ -222,7 +222,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian // Fill in adjacent triangles if required scanAFront(newNode) newNode.triangle - } + //} } // EdgeEvent @@ -245,11 +245,17 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian // TODO: fix tList.last == null bug! // Not sure why this happens in bird & nazca monkey demo... - if(tList.last == null) - tList -= tList.last + if(tList.last == null) tList -= tList.last - // Remove old triangles - tList.foreach(t => mesh.map -= t) + // Neighbor triangles + val nTriangles = new ArrayBuffer[Triangle] + + // Remove old triangles; collect neighbor triangles + tList.foreach(t => { + t.neighbors.foreach(n => if(n != null) nTriangles += n) + mesh.map -= t + //mesh.debug += t + }) val lPoints = new ArrayBuffer[Point] val rPoints = new ArrayBuffer[Point] @@ -282,16 +288,60 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian val T2 = new ArrayBuffer[Triangle] triangulate(rPoints.toArray, List(point1, point2), T2) + // Update advancing front + + val qNode = aFront.locate(edge.q) + val pNode = aFront.locate(edge.p) + println(tList.size) + + for(t <- tList) { + + if(qNode.triangle == t) { + println("node") + val p1 = qNode.point + val p2 = qNode.next.point + T1.foreach(tri => if(tri.contains(p1, p2)) qNode.triangle = tri) + T2.foreach(tri => if(tri.contains(p1, p2)) qNode.triangle = tri) + } else if(qNode.prev.triangle == t) { + println("prev node") + val p1 = qNode.prev.point + val p2 = qNode.point + T1.foreach(tri => if(tri.contains(p1, p2)) qNode.prev.triangle = tri) + T2.foreach(tri => if(tri.contains(p1, p2)) qNode.prev.triangle = tri) + } else if(qNode.next.triangle == t) { + println("next node") + } else + + if(pNode.triangle == t) { + println("Pnode") + val p1 = pNode.point + val p2 = pNode.next.point + T1.foreach(tri => if(tri.contains(p1, p2)) pNode.triangle = tri) + T2.foreach(tri => if(tri.contains(p1, p2)) pNode.triangle = tri) + } else if(pNode.prev.triangle == t) { + println("prev Pnode") + val p1 = pNode.point + val p2 = pNode.prev.point + T1.foreach(tri => if(tri.contains(p1, p2)) pNode.prev.triangle = tri) + T2.foreach(tri => if(tri.contains(p1, p2)) pNode.prev.triangle = tri) + } else if(pNode.next.triangle == t) { + println("next Pnode") + } + } + + // Update neighbors + //updateNeighbors(nTriangles, T1) + updateNeighbors(nTriangles, T2) + //nTriangles.foreach(n => n.printDebug) + // Mark constrained edges - val dEdge = new Segment(point1, point2) - T1.first mark(point1, point2) - T2.first mark(point1, point2) - + T1.first.mark(point1, point2) + T2.first.mark(point1, point2) + //TODO update neighbor pointers } else if(firstTriangle == null) { - - // NOTE: So far this only works for single triangles + // No triangles are intersected by the edge; edge must lie outside the mesh // Apply constraint; traverse the AFront, and build triangles @@ -300,17 +350,18 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian val point2 = if(ahead) edge.p else edge.q val points = new ArrayBuffer[Point] - val triangles = new ArrayBuffer[Triangle] + // Neighbor triangles + val nTriangles = new ArrayBuffer[Triangle] var node = aFront.locate(point1) val first = node - triangles += first.triangle + nTriangles += first.triangle node = node.next while(node.point != point2) { points += node.point - triangles += node.triangle + nTriangles += node.triangle node = node.next } @@ -322,26 +373,33 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian // Update advancing front aFront -= (first, node.prev, T.first) - - // Update neigbor pointers - // Inneficient, but it works well... - for(i <- triangles) - for(j <- T) - i.markNeighbor(j) - for(i <- 0 until T.size) - for(j <- i+1 until T.size) - T(i).markNeighbor(T(j)) - + // Update neighbors + updateNeighbors(nTriangles, T) + // Mark constrained edge T.first mark(edge.p, edge.q) - + } else { // Mark constrained edge firstTriangle mark(edge.p, edge.q) } } + // Update neigbor pointers for edge event + // Inneficient, but it works well... + def updateNeighbors(nTriangles: ArrayBuffer[Triangle], T: ArrayBuffer[Triangle]) { + + for(t1 <- nTriangles) + for(t2 <- T) + t1.markNeighbor(t2) + + for(i <- 0 until T.size) + for(j <- i+1 until T.size) + T(i).markNeighbor(T(j)) + + } + // Marc Vigo Anglada's triangulate pseudo-polygon algo private def triangulate(P: Array[Point], ab: List[Point], T: ArrayBuffer[Triangle]) { diff --git a/src/org/poly2tri/shapes/Triangle.scala b/src/org/poly2tri/shapes/Triangle.scala index f692339..2ccac29 100644 --- a/src/org/poly2tri/shapes/Triangle.scala +++ b/src/org/poly2tri/shapes/Triangle.scala @@ -48,25 +48,26 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) { // Update neighbor pointers // Debug version - def markNeighbor(ccwPoint: Point, cwPoint: Point, triangle: Triangle, debug: HashSet[Triangle]) { - if((ccwPoint == points(2) && cwPoint == points(1)) || (ccwPoint == points(1) && cwPoint == points(2))) + def markNeighbor(p1: Point, p2: Point, triangle: Triangle, debug: HashSet[Triangle]) { + if((p1 == points(2) && p2 == points(1)) || (p1 == points(1) && p2 == points(2))) neighbors(0) = triangle - else if((ccwPoint == points(0) && cwPoint == points(2)) || (ccwPoint == points(2) && cwPoint == points(0))) + else if((p1 == points(0) && p2 == points(2)) || (p1 == points(2) && p2 == points(0))) neighbors(1) = triangle - else if((ccwPoint == points(0) && cwPoint == points(1)) || (ccwPoint == points(1) && cwPoint == points(0))) + else if((p1 == points(0) && p2 == points(1)) || (p1 == points(1) && p2 == points(0))) neighbors(2) = triangle else { debug += triangle + println("Neighbor pointer ERROR!") } } // Update neighbor pointers - def markNeighbor(ccwPoint: Point, cwPoint: Point, triangle: Triangle) { - if((ccwPoint == points(2) && cwPoint == points(1)) || (ccwPoint == points(1) && cwPoint == points(2))) + def markNeighbor(p1: Point, p2: Point, triangle: Triangle) { + if((p1 == points(2) && p2 == points(1)) || (p1 == points(1) && p2 == points(2))) neighbors(0) = triangle - else if((ccwPoint == points(0) && cwPoint == points(2)) || (ccwPoint == points(2) && cwPoint == points(0))) + else if((p1 == points(0) && p2 == points(2)) || (p1 == points(2) && p2 == points(0))) neighbors(1) = triangle - else if((ccwPoint == points(0) && cwPoint == points(1)) || (ccwPoint == points(1) && cwPoint == points(0))) + else if((p1 == points(0) && p2 == points(1)) || (p1 == points(1) && p2 == points(0))) neighbors(2) = triangle else { throw new Exception("Neighbor pointer error, please report!")