From 7f999024b967b2aa3951e1bc29a2865119acb3b2 Mon Sep 17 00:00:00 2001 From: zzzzrrr Date: Tue, 18 Aug 2009 16:47:22 -0400 Subject: [PATCH] fixed edge bug --- src/org/poly2tri/Poly2Tri.scala | 6 +++--- src/org/poly2tri/cdt/CDT.scala | 23 +++++++++++++--------- src/org/poly2tri/cdt/Mesh.scala | 10 ---------- src/org/poly2tri/shapes/Triangle.scala | 27 +++++++++++++++++--------- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/org/poly2tri/Poly2Tri.scala b/src/org/poly2tri/Poly2Tri.scala index 4a50cb4..2ad6bab 100644 --- a/src/org/poly2tri/Poly2Tri.scala +++ b/src/org/poly2tri/Poly2Tri.scala @@ -79,7 +79,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { var drawcdtMesh = false val nazcaMonkey = "data/nazca_monkey.dat" - val nazcaHeron = "data/nazca_heron.dat" + val nazcaHeron = "data/nazca_heron_old.dat" val bird = "data/bird.dat" val snake = "data/i.snake" val star = "data/star.dat" @@ -87,7 +87,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { val i18 = "data/i.18" val tank = "data/tank.dat" - var currentModel = nazcaMonkey + var currentModel = nazcaHeron var doCDT = true var mouseButton = 0 @@ -318,7 +318,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") { doCDT = true; drawCDT = true CDT.clearPoint = 7 loadModel(i18, 20f, Point(600f, 500f), 20) - case "data/nazca_heron.dat" => + case "data/nazca_heron_old.dat" => //doCDT = false; drawCDT = false; drawcdtMesh = false CDT.clearPoint = 100 loadModel(nazcaHeron, 4.2f, Point(400f, 300f), 1500) diff --git a/src/org/poly2tri/cdt/CDT.scala b/src/org/poly2tri/cdt/CDT.scala index 56ddd3f..de09f94 100644 --- a/src/org/poly2tri/cdt/CDT.scala +++ b/src/org/poly2tri/cdt/CDT.scala @@ -42,9 +42,9 @@ import seidel.MonotoneMountain * International Journal of Geographical Information Science */ -// NOTE: Still need to implement edge insertion which combines advancing front (AF) +// NOTE: May need to implement edge insertion which combines advancing front (AF) // and triangle traversal respectively. See figure 14(a) from Domiter et al. - +// Although it may not be necessary for simple polygons.... object CDT { // Inital triangle factor @@ -83,12 +83,11 @@ object CDT { private def initSegments(points: ArrayBuffer[Point]): List[Segment] = { var segments = List[Segment]() + for(i <- 0 until points.size-1) { - val endPoints = validatePoints(points(i), points(i+1)) segments = new Segment(endPoints(0), endPoints(1)) :: segments endPoints(1).edges += segments.first - } val endPoints = validatePoints(points.first, points.last) @@ -199,7 +198,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian // Locate the first intersected triangle val firstTriangle = node.triangle.locateFirst(edge) - //if(firstTriangle != null)mesh.debug += firstTriangle + // Remove intersected triangles if(firstTriangle != null && !firstTriangle.contains(edge)) { @@ -270,6 +269,9 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian // Mark constrained edge T1.last markEdge(point1, point2) T2.last markEdge(point1, point2) + // Copy constraied edges from old triangles + T1.foreach(t => t.markEdge(tList)) + T2.foreach(t => t.markEdge(tList)) } else if(firstTriangle == null) { @@ -280,7 +282,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian val point1 = if(ahead) edge.q else edge.p val point2 = if(ahead) edge.p else edge.q - var pNode = if(ahead) node else aFront.locatePoint(point1) + var pNode = if(ahead) node else aFront.locate(point1) val first = pNode val points = new ArrayBuffer[Point] @@ -288,15 +290,14 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian // Neighbor triangles val nTriangles = new ArrayBuffer[Triangle] nTriangles += pNode.triangle - pNode = pNode.next - while(pNode.point != point2) { + while(pNode.point != point2 && edge > pNode.point) { points += pNode.point nTriangles += pNode.triangle pNode = pNode.next } - + // Triangulate empty areas. val T = new ArrayBuffer[Triangle] triangulate(points.toArray, List(point1, point2), T) @@ -437,9 +438,13 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian if(illegal && !t2.finalized) { // Flip edge and rotate everything clockwise + + // Legalize points t1.legalize(oPoint) t2.legalize(oPoint, point) + // Update neighbors + // Copy old neighbors val neighbors = List(t2.neighbors(0), t2.neighbors(1), t2.neighbors(2)) // Clear old neighbors diff --git a/src/org/poly2tri/cdt/Mesh.scala b/src/org/poly2tri/cdt/Mesh.scala index 827b8d9..de1fa5d 100644 --- a/src/org/poly2tri/cdt/Mesh.scala +++ b/src/org/poly2tri/cdt/Mesh.scala @@ -42,16 +42,6 @@ class Mesh(initialTriangle: Triangle) { val debug = HashSet.empty[Triangle] val triangles = new ArrayBuffer[Triangle] - def test(triangle: Triangle) { - if(triangle != null && !triangle.test){ - triangle.test = true - debug += triangle - for(i <- 0 until 3) { - test(triangle.neighbors(i)) - } - } - } - // Recursively collect triangles def clean(triangle: Triangle) { if(triangle != null && !triangle.interior) { diff --git a/src/org/poly2tri/shapes/Triangle.scala b/src/org/poly2tri/shapes/Triangle.scala index cf52132..2d134a7 100644 --- a/src/org/poly2tri/shapes/Triangle.scala +++ b/src/org/poly2tri/shapes/Triangle.scala @@ -44,13 +44,14 @@ class Triangle(val points: Array[Point]) { var neighbors = new Array[Triangle](3) // Flags to determine if an edge is the final Delauney edge val edges = Array(false, false, false) - - // Finalization flag + // Finalization flag. Set true if legalized or edge constrained + var finalized = false + // Has this triangle been marked as an interoir triangle? var interior = false - var finalized = false - - var test = false + def contains(p: Point): Boolean = (p == points(0) || p == points(1) || p == points(2)) + def contains(e: Segment): Boolean = (contains(e.p) && contains(e.q)) + def contains(p: Point, q: Point): Boolean = (contains(p) && contains(q)) // Update neighbor pointers private def markNeighbor(p1: Point, p2: Point, t: Triangle) { @@ -102,10 +103,6 @@ class Triangle(val points: Array[Point]) { } - def contains(p: Point): Boolean = (p == points(0) || p == points(1) || p == points(2)) - def contains(e: Segment): Boolean = (contains(e.p) && contains(e.q)) - def contains(p: Point, q: Point): Boolean = (contains(p) && contains(q)) - // Fast point in triangle test def pointIn(point: Point): Boolean = { @@ -308,6 +305,18 @@ class Triangle(val points: Array[Point]) { } } + def markEdge(T: ArrayBuffer[Triangle]) { + for(t <- T) { + for(i <- 0 to 2) + if(t.edges(i)) + i match { + case 0 => markEdge(t.points(1), t.points(2)) + case 1 => markEdge(t.points(0), t.points(2)) + case 2 => markEdge(t.points(0), t.points(1)) + } + } + } + // Mark edge as constrained def markEdge(p: Point, q: Point) { if((q == points(0) && p == points(1)) || (q == points(1) && p == points(0))) {