edge event work

This commit is contained in:
Mason 2009-08-07 21:08:13 -04:00
parent 552cc3f564
commit 7d87363ba7
4 changed files with 81 additions and 42 deletions

View File

@ -76,6 +76,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
var hiLighter = 0
var drawEarClip = false
var drawCDT = true
var drawcdtMesh = true
val nazcaMonkey = "data/nazca_monkey.dat"
val bird = "data/bird.dat"
@ -84,7 +85,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
val strange = "data/strange.dat"
val i18 = "data/i.18"
var currentModel = star
var currentModel = i18
var mouseButton = 0
var mousePressed = false
@ -167,7 +168,8 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
})
if(drawCDT) {
slCDT.triangles.foreach( t => {
val draw = if(drawcdtMesh) slCDT.triangleMesh else slCDT.triangles
draw.foreach( t => {
val triangle = new Polygon
triangle.addPoint(t.points(0).x, t.points(0).y)
triangle.addPoint(t.points(1).x, t.points(1).y)
@ -264,6 +266,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
if(c == '5') selectModel(star)
if(c == '6') selectModel(i18)
if(c == 's') drawSegs = !drawSegs
if(c == 'c') drawcdtMesh = !drawcdtMesh
//if(c == 'e') {drawEarClip = !drawEarClip; selectModel(currentModel)}
}

View File

@ -107,7 +107,7 @@ object CDT {
class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Triangle) {
// Triangle list
def triangles = mesh.map
def triangles = mesh.triangles
def triangleMesh = mesh.map
def debugTriangles = mesh.debug
@ -119,6 +119,9 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
private val PI_2 = Math.Pi/2
private val PI_34 = Math.Pi*3/4
// Triangle used to clean interior
var cleanTri: Triangle = null
// Sweep points; build mesh
sweep
// Finalize triangulation
@ -126,7 +129,6 @@ 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 points.size) {
val point = points(i)
// Process Point event
@ -139,12 +141,18 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
}
// Process edge events
point.edges.foreach(e => edgeEvent(e, triangle))
//if(i == 7) {cTri = triangle; mesh.debug += cTri}
//if(i == 7) {cleanTri = triangle; mesh.debug += cleanTri}
}
//mesh clean cTri
//mesh.map.foreach(m => m.edges.foreach(e => if(e) mesh.debug += m))
}
// Final step in the sweep-line CDT algo
// Clean exterior triangles
private def finalization {
mesh.map.foreach(m => m.markEdges)
mesh clean cleanTri
//mesh.map.foreach(m => m.edges.foreach(e => if(e) mesh.debug += m))
}
// Point event
private def pointEvent(point: Point): Triangle = {
@ -276,11 +284,14 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
// Mark constrained edges
val dEdge = new Segment(point1, point2)
T1.first mark dEdge
T2.first mark dEdge
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
@ -292,29 +303,45 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
var node = aFront.locate(point1)
val first = node
node = node.next
while(node.point != point2) {
points += node.point
node = node.next
}
//assert(points.size == 1, "not implemented yet, points = " + points.size)
val endPoints = if(ahead) List(point2, point1) else List(point1, point2)
// STEP 3: Triangulate empty areas.
val T = new ArrayBuffer[Triangle]
triangulate(points.toArray, List(point1, point2), T)
triangulate(points.toArray, endPoints, T)
// Update advancing front
first.triangle = T.first
first.next = node
node.prev = first
aFront -= (first, node.prev, T.first)
// Update neigbor pointers
if(ahead) {
T.first.neighbors(2) = node.prev.triangle;
T.first.neighbors(0) = first.triangle
node.prev.triangle.updateNeighbors(T.first.points(0), T.first.points(1), T.first, mesh.debug)
first.triangle.updateNeighbors(T.first.points(1), T.first.points(2), T.first, mesh.debug)
} else {
T.first.neighbors(2) = first.triangle;
T.first.neighbors(0) = node.prev.triangle
node.prev.triangle.updateNeighbors(T.first.points(1), T.first.points(2), T.first, mesh.debug)
first.triangle.updateNeighbors(T.first.points(0), T.first.points(1), T.first, mesh.debug)
}
// Mark constrained edge
T.first mark(edge.p, edge.q)
} else {
// Mark constrained edge
val dEdge = new Segment(point1, point2)
T.first mark dEdge
}
// Mark constrained edge
if(contains)
firstTriangle mark edge
firstTriangle mark(edge.p, edge.q)
}
}
// Marc Vigo Anglada's triangulate pseudo-polygon algo
@ -347,7 +374,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
}
// Scan left and right along AFront to fill holes
def scanAFront(n: Node) {
private def scanAFront(n: Node) {
var node = n.next
// Update right
@ -371,7 +398,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
}
// Fill empty space with a triangle
def fill(node: Node): Double = {
private def fill(node: Node): Double = {
val a = (node.prev.point - node.point)
val b = (node.next.point - node.point)
val angle = Math.abs(Math.atan2(a cross b, a dot b))
@ -423,7 +450,7 @@ 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 = t1.collinear(oPoint)
val c2 = t2.collinear(oPoint, t1.points(0))
@ -453,11 +480,5 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
true
}
true
}
// Final step in the sweep-line CDT algo
private def finalization {
}
}
}

View File

@ -44,7 +44,7 @@ class Mesh(initialTriangle: Triangle) {
// Recursively collect triangles
def clean(triangle: Triangle) {
if(triangle != null && triangle.clean == false) {
if(triangle != null && !triangle.clean) {
triangle.clean = true
triangles += triangle
if(!triangle.edges(0))

View File

@ -56,7 +56,7 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
neighbors(2) = triangle
else {
debug += triangle
throw new Exception("Neighbor pointer error, please report!")
//throw new Exception("Neighbor pointer error, please report!")
}
}
@ -267,22 +267,37 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
ki = points(0) - points(2)
}
def mark(e: Segment) {
markEdge(e)
markNeighbors(e)
// Initial mark edges sweep
def mark(p: Point, q: Point) {
if(contains(p) && contains(q)) {
markEdge(p, q)
markNeighbors(p, q)
}
}
private def markNeighbors(e: Segment) = neighbors.foreach(n => if(n != null) n.markEdge(e))
// Finalize edge marking
def markEdges {
for(i <- 0 to 2)
if(edges(i))
i match {
case 0 => if(neighbors(0) != null) neighbors(0).markEdge(points(1), points(2))
case 1 => if(neighbors(1) != null) neighbors(1).markEdge(points(0), points(2))
case _ => if(neighbors(2) != null) neighbors(2).markEdge(points(0), points(1))
}
}
// Mark neighbor's edge
private def markNeighbors(p: Point, q: Point) = neighbors.foreach(n => if(n != null) n.markEdge(p, q))
// Mark edge as constrained
private def markEdge(e: Segment) {
if((e.q == points(0) && e.p == points(1)) || (e.q == points(1) && e.p == points(0))) {
private def markEdge(p: Point, q: Point) {
if((q == points(0) && p == points(1)) || (q == points(1) && p == points(0))) {
edges(2) = true
} else if ((e.q == points(0) && e.p == points(2)) || (e.q == points(2) && e.p == points(0))) {
} else if ((q == points(0) && p == points(2)) || (q == points(2) && p == points(0))) {
edges(1) = true
} else {
} else if ((q == points(1) && p == points(2)) || (q == points(2) && p == points(1))){
edges(0) = true
}
}
}
}