mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-05 22:09:52 +01:00
fixed legalization bug
This commit is contained in:
parent
c03ee9e0ff
commit
84598700c4
@ -87,6 +87,9 @@ class AFront(iTriangle: Triangle) {
|
|||||||
node
|
node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def constrainedEdge() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
def -=(tuple: Tuple3[Node, Node, Triangle]) {
|
def -=(tuple: Tuple3[Node, Node, Triangle]) {
|
||||||
val (node, kNode, triangle) = tuple
|
val (node, kNode, triangle) = tuple
|
||||||
|
@ -137,7 +137,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
|
|||||||
// Process Point event
|
// Process Point event
|
||||||
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}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,8 +407,10 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
|
|||||||
val neighbors = Array(node.triangle, null, node.prev.triangle)
|
val neighbors = Array(node.triangle, null, node.prev.triangle)
|
||||||
val triangle = new Triangle(points, neighbors)
|
val triangle = new Triangle(points, neighbors)
|
||||||
// Update neighbor pointers
|
// Update neighbor pointers
|
||||||
node.prev.triangle.markNeighbor(triangle.points(0), triangle.points(1), triangle, mesh.debug)
|
//node.prev.triangle.markNeighbor(triangle.points(0), triangle.points(1), triangle)
|
||||||
node.triangle.markNeighbor(triangle.points(1), triangle.points(2), triangle, mesh.debug)
|
node.prev.triangle.markNeighbor(triangle)
|
||||||
|
//node.triangle.markNeighbor(triangle.points(1), triangle.points(2), triangle)
|
||||||
|
node.triangle.markNeighbor(triangle)
|
||||||
mesh.map += triangle
|
mesh.map += triangle
|
||||||
aFront -= (node.prev, node, triangle)
|
aFront -= (node.prev, node, triangle)
|
||||||
}
|
}
|
||||||
@ -451,12 +453,13 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
|
|||||||
|
|
||||||
if(illegal(t1.points(1), oPoint, t1.points(2), t1.points(0))) {
|
if(illegal(t1.points(1), oPoint, t1.points(2), t1.points(0))) {
|
||||||
|
|
||||||
// Flip edges and rotate everything clockwise
|
// Flip edge and rotate everything clockwise
|
||||||
t1.legalize(oPoint)
|
t1.legalize(oPoint)
|
||||||
t2.legalize(oPoint, point)
|
t2.legalize(oPoint, point)
|
||||||
|
|
||||||
// Update neighbor pointers
|
// Update neighbor pointers
|
||||||
val neighbors = List(t2.neighbors(0), t2.neighbors(1), t2.neighbors(2))
|
val neighbors = List(t2.neighbors(0), t2.neighbors(1), t2.neighbors(2))
|
||||||
|
t2.clearNeighbors
|
||||||
for(n <- neighbors) {
|
for(n <- neighbors) {
|
||||||
if(n != null) {
|
if(n != null) {
|
||||||
t2.markNeighbor(n)
|
t2.markNeighbor(n)
|
||||||
@ -464,7 +467,7 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
t2.markNeighbor(t1)
|
t2.markNeighbor(t1)
|
||||||
|
|
||||||
// Update advancing front
|
// Update advancing front
|
||||||
aFront.insertLegalized(point, t1, node)
|
aFront.insertLegalized(point, t1, node)
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update neighbor pointers
|
// Update neighbor pointers
|
||||||
def markNeighbor(p1: Point, p2: Point, triangle: Triangle) {
|
private def markNeighbor(p1: Point, p2: Point, triangle: Triangle) {
|
||||||
if((p1 == points(2) && p2 == points(1)) || (p1 == points(1) && p2 == points(2)))
|
if((p1 == points(2) && p2 == points(1)) || (p1 == points(1) && p2 == points(2)))
|
||||||
neighbors(0) = triangle
|
neighbors(0) = triangle
|
||||||
else if((p1 == points(0) && p2 == points(2)) || (p1 == points(2) && p2 == points(0)))
|
else if((p1 == points(0) && p2 == points(2)) || (p1 == points(2) && p2 == points(0)))
|
||||||
@ -70,6 +70,9 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
|||||||
else if((p1 == points(0) && p2 == points(1)) || (p1 == points(1) && p2 == points(0)))
|
else if((p1 == points(0) && p2 == points(1)) || (p1 == points(1) && p2 == points(0)))
|
||||||
neighbors(2) = triangle
|
neighbors(2) = triangle
|
||||||
else {
|
else {
|
||||||
|
println("**********************")
|
||||||
|
triangle.printDebug
|
||||||
|
printDebug
|
||||||
throw new Exception("Neighbor pointer error, please report!")
|
throw new Exception("Neighbor pointer error, please report!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,6 +91,11 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def clearNeighbors {
|
||||||
|
for(i <- 0 until 3)
|
||||||
|
neighbors(i) = null
|
||||||
|
}
|
||||||
|
|
||||||
def oppositePoint(t: Triangle): Point = {
|
def oppositePoint(t: Triangle): Point = {
|
||||||
if(points(0) == t.points(1))
|
if(points(0) == t.points(1))
|
||||||
points(1)
|
points(1)
|
||||||
@ -101,6 +109,7 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
|||||||
printDebug
|
printDebug
|
||||||
throw new Exception("point location error")
|
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))
|
||||||
@ -110,11 +119,14 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
|||||||
// Fast point in triangle test
|
// Fast point in triangle test
|
||||||
def pointIn(point: Point): Boolean = {
|
def pointIn(point: Point): Boolean = {
|
||||||
|
|
||||||
|
val ij = points(1) - points(0)
|
||||||
|
val jk = points(2) - points(1)
|
||||||
val pab = (point - points(0)).cross(ij)
|
val pab = (point - points(0)).cross(ij)
|
||||||
val pbc = (point - points(1)).cross(jk)
|
val pbc = (point - points(1)).cross(jk)
|
||||||
var sameSign = Math.signum(pab) == Math.signum(pbc)
|
var sameSign = Math.signum(pab) == Math.signum(pbc)
|
||||||
if (!sameSign) return false
|
if (!sameSign) return false
|
||||||
|
|
||||||
|
val ki = points(0) - points(2)
|
||||||
val pca = (point - points(2)).cross(ki)
|
val pca = (point - points(2)).cross(ki)
|
||||||
sameSign = Math.signum(pab) == Math.signum(pca)
|
sameSign = Math.signum(pab) == Math.signum(pca)
|
||||||
if (!sameSign) return false
|
if (!sameSign) return false
|
||||||
@ -124,20 +136,27 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
|||||||
|
|
||||||
// Locate first triangle crossed by constrained edge
|
// Locate first triangle crossed by constrained edge
|
||||||
def locateFirst(edge: Segment): Triangle = {
|
def locateFirst(edge: Segment): Triangle = {
|
||||||
|
|
||||||
val p = edge.p
|
val p = edge.p
|
||||||
val q = edge.q
|
val q = edge.q
|
||||||
val e = p - q
|
val e = p - q
|
||||||
if(q == points(0)) {
|
if(q == points(0)) {
|
||||||
|
val ik = points(2) - points(0)
|
||||||
|
val ij = points(1) - points(0)
|
||||||
val sameSign = Math.signum(ik cross e) == Math.signum(ij cross e)
|
val sameSign = Math.signum(ik cross e) == Math.signum(ij cross e)
|
||||||
if(!sameSign) return this
|
if(!sameSign) return this
|
||||||
if(neighbors(2) == null) return null
|
if(neighbors(2) == null) return null
|
||||||
return neighbors(2).locateFirst(edge)
|
return neighbors(2).locateFirst(edge)
|
||||||
} else if(q == points(1)) {
|
} else if(q == points(1)) {
|
||||||
|
val jk = points(2) - points(1)
|
||||||
|
val ji = points(0) - points(1)
|
||||||
val sameSign = Math.signum(jk cross e) == Math.signum(ji cross e)
|
val sameSign = Math.signum(jk cross e) == Math.signum(ji cross e)
|
||||||
if(!sameSign) return this
|
if(!sameSign) return this
|
||||||
if(neighbors(0) == null) return null
|
if(neighbors(0) == null) return null
|
||||||
return neighbors(0).locateFirst(edge)
|
return neighbors(0).locateFirst(edge)
|
||||||
} else if(q == points(2)) {
|
} else if(q == points(2)) {
|
||||||
|
val kj = points(1) - points(2)
|
||||||
|
val ki = points(0) - points(2)
|
||||||
val sameSign = Math.signum(kj cross e) == Math.signum(ki cross e)
|
val sameSign = Math.signum(kj cross e) == Math.signum(ki cross e)
|
||||||
if(!sameSign) return this
|
if(!sameSign) return this
|
||||||
if(neighbors(1) == null) return null
|
if(neighbors(1) == null) return null
|
||||||
@ -229,10 +248,10 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
|||||||
|
|
||||||
// Legalized triangle by rotating clockwise around point(0)
|
// Legalized triangle by rotating clockwise around point(0)
|
||||||
def legalize(oPoint: Point) {
|
def legalize(oPoint: Point) {
|
||||||
|
Util.collinear(points(0), points(2), oPoint)
|
||||||
points(1) = points(0)
|
points(1) = points(0)
|
||||||
points(0) = points(2)
|
points(0) = points(2)
|
||||||
points(2) = oPoint
|
points(2) = oPoint
|
||||||
updateEdges
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legalize triagnle by rotating clockwise around oPoint
|
// Legalize triagnle by rotating clockwise around oPoint
|
||||||
@ -250,7 +269,7 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
|||||||
points(2) = points(1)
|
points(2) = points(1)
|
||||||
points(1) = nPoint
|
points(1) = nPoint
|
||||||
}
|
}
|
||||||
updateEdges
|
Util.collinear(points(0), points(2), points(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make legalized triangle will not be collinear
|
// Make legalized triangle will not be collinear
|
||||||
@ -288,25 +307,11 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
|||||||
|
|
||||||
def printDebug = println(points(0) + "," + points(1) + "," + points(2))
|
def printDebug = println(points(0) + "," + points(1) + "," + points(2))
|
||||||
|
|
||||||
private var ik, ij , jk, ji, kj, ki: Point = null
|
|
||||||
updateEdges
|
|
||||||
|
|
||||||
// Update the edges that consitite this triangle
|
|
||||||
// May change during legalization
|
|
||||||
private def updateEdges {
|
|
||||||
ik = points(2) - points(0)
|
|
||||||
ij = points(1) - points(0)
|
|
||||||
jk = points(2) - points(1)
|
|
||||||
ji = points(0) - points(1)
|
|
||||||
kj = points(1) - points(2)
|
|
||||||
ki = points(0) - points(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initial mark edges sweep
|
// Initial mark edges sweep
|
||||||
def mark(p: Point, q: Point) {
|
def mark(p: Point, q: Point) {
|
||||||
if(contains(p) && contains(q)) {
|
if(contains(p) && contains(q)) {
|
||||||
markEdge(p, q)
|
markEdge(p, q)
|
||||||
markNeighbors(p, q)
|
markNeighborEdge(p, q)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +327,8 @@ class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark neighbor's edge
|
// Mark neighbor's edge
|
||||||
private def markNeighbors(p: Point, q: Point) = neighbors.foreach(n => if(n != null) n.markEdge(p, q))
|
private def markNeighborEdge(p: Point, q: Point) =
|
||||||
|
neighbors.foreach(n => if(n != null) n.markEdge(p, q))
|
||||||
|
|
||||||
// Mark edge as constrained
|
// Mark edge as constrained
|
||||||
private def markEdge(p: Point, q: Point) {
|
private def markEdge(p: Point, q: Point) {
|
||||||
|
@ -41,8 +41,8 @@ object Util {
|
|||||||
def collinear(p1: Point, p2: Point, p3: Point): Boolean = {
|
def collinear(p1: Point, p2: Point, p3: Point): Boolean = {
|
||||||
|
|
||||||
val d = (p2 - p1) cross (p1 - p3)
|
val d = (p2 - p1) cross (p1 - p3)
|
||||||
|
|
||||||
if(Math.abs(d) <= COLLINEAR_SLOP)
|
if(d <= COLLINEAR_SLOP)
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
|
Loading…
Reference in New Issue
Block a user