restructure code

This commit is contained in:
Mason 2009-08-09 21:41:45 -04:00
parent d48d3f4fc0
commit 328d8e4962
5 changed files with 73 additions and 121 deletions

View File

@ -76,7 +76,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
var hiLighter = 0 var hiLighter = 0
var drawEarClip = false var drawEarClip = false
var drawCDT = true var drawCDT = true
var drawcdtMesh = false var drawcdtMesh = true
val nazcaMonkey = "data/nazca_monkey.dat" val nazcaMonkey = "data/nazca_monkey.dat"
val bird = "data/bird.dat" val bird = "data/bird.dat"

View File

@ -67,12 +67,9 @@ class AFront(iTriangle: Triangle) {
null null
} }
def insert(tuple: Tuple3[Point, Triangle, Node]) = { def insert(point: Point, triangle: Triangle, nNode: Node) = {
val (point, triangle, nNode) = tuple
val node = new Node(point, triangle) val node = new Node(point, triangle)
// Update pointer
nNode.triangle = triangle nNode.triangle = triangle
// Insert new node into advancing front
nNode.next.prev = node nNode.next.prev = node
node.next = nNode.next node.next = nNode.next
node.prev = nNode node.prev = nNode
@ -80,6 +77,17 @@ class AFront(iTriangle: Triangle) {
node node
} }
def insertLegalized(point: Point, triangle: Triangle, nNode: Node) = {
val node = new Node(triangle.points(1), triangle)
val rNode = nNode.next
rNode.prev = node
node.next = rNode
nNode.next = node
node.prev = nNode
node
}
def -=(tuple: Tuple3[Node, Node, Triangle]) { def -=(tuple: Tuple3[Node, Node, Triangle]) {
val (node, kNode, triangle) = tuple val (node, kNode, triangle) = tuple
kNode.next.prev = node kNode.next.prev = node

View File

@ -137,7 +137,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
var triangle = pointEvent(point) var triangle = pointEvent(point)
// Process edge events // Process edge events
point.edges.foreach(e => triangle = edgeEvent(e, triangle)) point.edges.foreach(e => triangle = edgeEvent(e, triangle))
if(i == CDT.clearPoint) {cleanTri = triangle; mesh.debug += cleanTri} if(i == CDT.clearPoint) {cleanTri = triangle; /*mesh.debug += cleanTri*/}
} }
} }
@ -153,72 +153,20 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
private def pointEvent(point: Point): Triangle = { private def pointEvent(point: Point): Triangle = {
val node = aFront.locate(point) val node = aFront.locate(point)
/*
// Projected point coincides with existing point; create two triangles // Projected point hits advancing front; create new triangle
if(point.x == node.point.x && node.prev != null) { val pts = Array(point, node.point, node.next.point)
val neighbors = Array(node.triangle, null, null)
val rPts = Array(point, node.point, node.next.point) val triangle = new Triangle(pts, neighbors)
val rNeighbors = Array(node.triangle, null, null) mesh.map += triangle
val rTriangle = new Triangle(rPts, rNeighbors)
// Legalize
val lPts = Array(point, node.prev.point, node.point) val newNode = legalization(triangle, node)
val lNeighbors = Array(node.prev.triangle, rTriangle, null)
val lTriangle = new Triangle(lPts, lNeighbors) // Fill in adjacent triangles if required
scanAFront(newNode)
rTriangle.neighbors(2) = lTriangle newNode.triangle
mesh.map += lTriangle
mesh.map += rTriangle
// TODO: check to see of legalization is necessary here
// Update neighbors
node.triangle.markNeighbor(rTriangle.points(1), rTriangle.points(2), rTriangle, mesh.debug)
node.prev.triangle.markNeighbor(lTriangle.points(1), lTriangle.points(2), lTriangle, mesh.debug)
// Update advancing front
val newNode = aFront.insert(point, rTriangle, node)
node.prev.next = newNode
newNode.prev = node.prev
node.prev.triangle = lTriangle
// Fill in adjacent triangles if required
scanAFront(newNode)
newNode.triangle
} else {
*/
// Projected point hits advancing front; create new triangle
val cwPoint = node.next.point
val ccwPoint = node.point
val nTri = node.triangle
val pts = Array(point, ccwPoint, cwPoint)
val neighbors = Array(nTri, null, null)
val triangle = new Triangle(pts, neighbors)
mesh.map += triangle
// Legalize
val legal = legalization(triangle, nTri)
var newNode: Node = null
// Update advancing front
if(legal) {
newNode = aFront.insert(point, triangle, node)
// Update neighbors
nTri.markNeighbor(cwPoint, ccwPoint, triangle, mesh.debug)
} else {
newNode = new Node(triangle.points(1), triangle)
val rNode = node.next
rNode.prev = newNode
newNode.next = rNode
node.next = newNode
newNode.prev = node
}
// Fill in adjacent triangles if required
scanAFront(newNode)
newNode.triangle
//}
} }
// EdgeEvent // EdgeEvent
@ -478,15 +426,13 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
if(cosA < 0 && cosB < 0) if(cosA < 0 && cosB < 0)
return true return true
else if(cosA > 0 && cosB > 0) if(cosA > 0 && cosB > 0)
return false return false
val sinA = v1 cross v2 val sinA = v1 cross v2
val sinB = v3 cross v4 val sinB = v3 cross v4
// Small negative number to prevent swapping if((cosA*sinB + sinA*cosB) < 0f)
// in nearly neutral cases
if((cosA*sinB + sinA*cosB) < -0.01f)
true true
else else
false false
@ -494,40 +440,41 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
// Ensure adjacent triangles are legal // Ensure adjacent triangles are legal
// If illegal, flip edges and update triangle's pointers // If illegal, flip edges and update triangle's pointers
private def legalization(t1: Triangle, t2: Triangle): Boolean = { private def legalization(t1: Triangle, node: Node): Node = {
val t2 = node.triangle
val oPoint = t2 oppositePoint t1 val oPoint = t2 oppositePoint t1
if(illegal(t1.points(1), oPoint, t1.points(2), t1.points(0))) { if(illegal(t1.points(1), oPoint, t1.points(2), t1.points(0))) {
// Prevent creation of collinear traingles // Flip edges and rotate everything clockwise
val c1 = t1.collinear(oPoint) val point = t1.points(0)
val c2 = t2.collinear(oPoint, t1.points(0)) t1.legalize(oPoint)
t2.legalize(oPoint, point)
if(!c1 && !c2) {
// Update neighbor pointers // Update neighbor pointers
val ccwNeighbor = t2.neighborCCW(oPoint) val neighbors = List(t2.neighbors(0), t2.neighbors(1), t2.neighbors(2))
for(n <- neighbors) {
if(ccwNeighbor != null) { if(n != null) {
ccwNeighbor.markNeighbor(oPoint, t1.points(2), t1, mesh.debug) t2.markNeighbor(n)
t1.neighbors(1) = ccwNeighbor t1.markNeighbor(n)
} }
}
t2.rotateNeighborsCW(oPoint, t1) t2.markNeighbor(t1)
t1.neighbors(0) = t2 // Update advancing front
t1.neighbors(2) = null aFront.insertLegalized(point, t1, node)
// Flip edges and rotate everything clockwise
val point = t1.points(0)
t1.legalize(oPoint)
t2.legalize(oPoint, point)
return false
}
} else { } else {
true
// Update neighbor
node.triangle.markNeighbor(t1)
// Update advancing front
aFront.insert(t1.points(0), t1, node)
} }
true
} }
} }

View File

@ -88,13 +88,19 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
} }
} }
def oppositePoint(t: Triangle) = { def oppositePoint(t: Triangle): Point = {
if(points(0) == t.points(1)) if(points(0) == t.points(1))
points(1) points(1)
else if(points(0) == t.points(2)) else if(points(0) == t.points(2))
points(2) points(2)
else else if((points(2) == t.points(1) && points(1) == t.points(2)) || (points(1) == t.points(1) && points(2) == t.points(2)))
points(0) points(0)
else {
println("**********************")
t.printDebug
printDebug
throw new Exception("point location error")
}
} }
def contains(p: Point): Boolean = (p == points(0) || p == points(1) || p == points(2)) def contains(p: Point): Boolean = (p == points(0) || p == points(1) || p == points(2))
@ -176,10 +182,10 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
} }
// The neighbor counter-clockwise to given point // The neighbor counter-clockwise to given point
def neighborCCW(point: Point): Triangle = { def neighborCCW(oPoint: Point): Triangle = {
if(point == points(0)) { if(oPoint == points(0)) {
neighbors(2) neighbors(2)
}else if(point == points(1)) { }else if(oPoint == points(1)) {
neighbors(0) neighbors(0)
} else } else
neighbors(1) neighbors(1)

View File

@ -39,19 +39,10 @@ object Util {
// Tests if the given points are collinear // Tests if the given points are collinear
def collinear(p1: Point, p2: Point, p3: Point): Boolean = { def collinear(p1: Point, p2: Point, p3: Point): Boolean = {
// 3x2 matrix
val a11 = p1.x
val a12 = p1.y
val a21 = p2.x
val a22 = p2.y
val a31 = p3.x
val a32 = p3.y
// Determinant
val d = a11*(a22-a32) - a12*(a21-a31) + (a21*a32-a31*a22)
if(d <= COLLINEAR_SLOP) val d = (p2 - p1) cross (p1 - p3)
if(Math.abs(d) <= COLLINEAR_SLOP)
true true
else else
false false