fixed legalization bug

This commit is contained in:
Mason 2009-08-07 14:09:17 -04:00
parent 8c7b86d715
commit c909954b2f
3 changed files with 22 additions and 27 deletions

View File

@ -126,7 +126,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
// Implement sweep-line // Implement sweep-line
private def sweep { private def sweep {
//var cTri: Triangle = null //var cTri: Triangle = null
for(i <- 1 until 15 /*points.size*/) { for(i <- 1 until points.size) {
val point = points(i) val point = points(i)
// Process Point event // Process Point event
var triangle: Triangle = null var triangle: Triangle = null
@ -149,9 +149,6 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
val node = aFront.locate(point) val node = aFront.locate(point)
// Avoid triangles that are almost collinear
if(!Util.collinear(point, node.point, node.next.point)) {
// Projected point coincides with existing point; create two triangles // Projected point coincides with existing point; create two triangles
if(point.x == node.point.x && node.prev != null) { if(point.x == node.point.x && node.prev != null) {
@ -217,11 +214,6 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
scanAFront(newNode) scanAFront(newNode)
newNode.triangle newNode.triangle
} }
} else {
println("bad triangle")
null
}
} }
// EdgeEvent // EdgeEvent
@ -412,9 +404,10 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
val sinA = v1 cross v2 val sinA = v1 cross v2
val sinB = v3 cross v4 val sinB = v3 cross v4
//println((cosA*sinB + sinA*cosB))
// Some small number // Small negative number to prevent swapping
if((cosA*sinB + sinA*cosB) < -10f) // in nearly neutral cases
if((cosA*sinB + sinA*cosB) < -0.01f)
true true
else else
false false
@ -426,7 +419,15 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
val oPoint = t2 oppositePoint t1 val oPoint = t2 oppositePoint t1
if(illegal(t1.points(1), oPoint, t1.points(2), t1.points(0))) { // 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) {
println("legalize") println("legalize")
// Update neighbor pointers // Update neighbor pointers
val ccwNeighbor = t2.neighborCCW(oPoint) val ccwNeighbor = t2.neighborCCW(oPoint)

View File

@ -45,7 +45,7 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
var clean = false var clean = false
// Update neighbor pointers // Update neighbor pointers
def updateNeighbors(ccwPoint: Point, cwPoint: Point, triangle: Triangle, mesh: HashSet[Triangle]) { def updateNeighbors(ccwPoint: Point, cwPoint: Point, triangle: Triangle, debug: HashSet[Triangle]) {
if((ccwPoint == points(2) && cwPoint == points(1)) || (ccwPoint == points(1) && cwPoint == points(2))) if((ccwPoint == points(2) && cwPoint == points(1)) || (ccwPoint == points(1) && cwPoint == points(2)))
neighbors(0) = triangle neighbors(0) = triangle
else if((ccwPoint == points(0) && cwPoint == points(2)) || (ccwPoint == points(2) && cwPoint == points(0))) else if((ccwPoint == points(0) && cwPoint == points(2)) || (ccwPoint == points(2) && cwPoint == points(0)))
@ -53,9 +53,7 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
else if((ccwPoint == points(0) && cwPoint == points(1)) || (ccwPoint == points(1) && cwPoint == points(0))) else if((ccwPoint == points(0) && cwPoint == points(1)) || (ccwPoint == points(1) && cwPoint == points(0)))
neighbors(2) = triangle neighbors(2) = triangle
else { else {
mesh += triangle debug += triangle
println(ccwPoint + "," + cwPoint)
printDebug
throw new Exception("Neighbor update error") throw new Exception("Neighbor update error")
} }
} }

View File

@ -7,7 +7,8 @@ import shapes.Point
object Util { object Util {
val COLLINEAR_SLOP = 10f // Almost zero
val COLLINEAR_SLOP = 0.1f
// From "Scala By Example," by Martin Odersky // From "Scala By Example," by Martin Odersky
def msort[A](less: (A, A) => Boolean)(xs: List[A]): List[A] = { def msort[A](less: (A, A) => Boolean)(xs: List[A]): List[A] = {
@ -39,23 +40,18 @@ 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 = {
// 3x3 matrix // 3x2 matrix
val a11 = p1.x val a11 = p1.x
val a12 = p1.y val a12 = p1.y
val a13 = 1f
val a21 = p2.x val a21 = p2.x
val a22 = p2.y val a22 = p2.y
val a23 = 1f
val a31 = p3.x val a31 = p3.x
val a32 = p3.y val a32 = p3.y
val a33 = 1f
// Determinant // Determinant
val d = a11*(a22*a33 - a32*a23) - a12*(a21*a33-a31*a23) + a13*(a21*a32-a31*a22) val d = a11*(a22-a32) - a12*(a21-a31) + (a21*a32-a31*a22)
println("Determinant = " + d) if(Math.abs(d) <= COLLINEAR_SLOP) {
if(d <= COLLINEAR_SLOP) {
true true
} else { } else {
false false