mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-30 01:03:30 +01:00
fixed edge bug
This commit is contained in:
parent
251e8ed8ff
commit
7f999024b9
@ -79,7 +79,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
var drawcdtMesh = false
|
var drawcdtMesh = false
|
||||||
|
|
||||||
val nazcaMonkey = "data/nazca_monkey.dat"
|
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 bird = "data/bird.dat"
|
||||||
val snake = "data/i.snake"
|
val snake = "data/i.snake"
|
||||||
val star = "data/star.dat"
|
val star = "data/star.dat"
|
||||||
@ -87,7 +87,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
val i18 = "data/i.18"
|
val i18 = "data/i.18"
|
||||||
val tank = "data/tank.dat"
|
val tank = "data/tank.dat"
|
||||||
|
|
||||||
var currentModel = nazcaMonkey
|
var currentModel = nazcaHeron
|
||||||
var doCDT = true
|
var doCDT = true
|
||||||
|
|
||||||
var mouseButton = 0
|
var mouseButton = 0
|
||||||
@ -318,7 +318,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
doCDT = true; drawCDT = true
|
doCDT = true; drawCDT = true
|
||||||
CDT.clearPoint = 7
|
CDT.clearPoint = 7
|
||||||
loadModel(i18, 20f, Point(600f, 500f), 20)
|
loadModel(i18, 20f, Point(600f, 500f), 20)
|
||||||
case "data/nazca_heron.dat" =>
|
case "data/nazca_heron_old.dat" =>
|
||||||
//doCDT = false; drawCDT = false; drawcdtMesh = false
|
//doCDT = false; drawCDT = false; drawcdtMesh = false
|
||||||
CDT.clearPoint = 100
|
CDT.clearPoint = 100
|
||||||
loadModel(nazcaHeron, 4.2f, Point(400f, 300f), 1500)
|
loadModel(nazcaHeron, 4.2f, Point(400f, 300f), 1500)
|
||||||
|
@ -42,9 +42,9 @@ import seidel.MonotoneMountain
|
|||||||
* International Journal of Geographical Information Science
|
* 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.
|
// and triangle traversal respectively. See figure 14(a) from Domiter et al.
|
||||||
|
// Although it may not be necessary for simple polygons....
|
||||||
object CDT {
|
object CDT {
|
||||||
|
|
||||||
// Inital triangle factor
|
// Inital triangle factor
|
||||||
@ -83,12 +83,11 @@ object CDT {
|
|||||||
private def initSegments(points: ArrayBuffer[Point]): List[Segment] = {
|
private def initSegments(points: ArrayBuffer[Point]): List[Segment] = {
|
||||||
|
|
||||||
var segments = List[Segment]()
|
var segments = List[Segment]()
|
||||||
for(i <- 0 until points.size-1) {
|
|
||||||
|
|
||||||
|
for(i <- 0 until points.size-1) {
|
||||||
val endPoints = validatePoints(points(i), points(i+1))
|
val endPoints = validatePoints(points(i), points(i+1))
|
||||||
segments = new Segment(endPoints(0), endPoints(1)) :: segments
|
segments = new Segment(endPoints(0), endPoints(1)) :: segments
|
||||||
endPoints(1).edges += segments.first
|
endPoints(1).edges += segments.first
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val endPoints = validatePoints(points.first, points.last)
|
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
|
// Locate the first intersected triangle
|
||||||
val firstTriangle = node.triangle.locateFirst(edge)
|
val firstTriangle = node.triangle.locateFirst(edge)
|
||||||
//if(firstTriangle != null)mesh.debug += firstTriangle
|
|
||||||
// Remove intersected triangles
|
// Remove intersected triangles
|
||||||
if(firstTriangle != null && !firstTriangle.contains(edge)) {
|
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
|
// Mark constrained edge
|
||||||
T1.last markEdge(point1, point2)
|
T1.last markEdge(point1, point2)
|
||||||
T2.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) {
|
} 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 point1 = if(ahead) edge.q else edge.p
|
||||||
val point2 = if(ahead) edge.p else edge.q
|
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 first = pNode
|
||||||
|
|
||||||
val points = new ArrayBuffer[Point]
|
val points = new ArrayBuffer[Point]
|
||||||
@ -288,10 +290,9 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
|
|||||||
// Neighbor triangles
|
// Neighbor triangles
|
||||||
val nTriangles = new ArrayBuffer[Triangle]
|
val nTriangles = new ArrayBuffer[Triangle]
|
||||||
nTriangles += pNode.triangle
|
nTriangles += pNode.triangle
|
||||||
|
|
||||||
pNode = pNode.next
|
pNode = pNode.next
|
||||||
|
|
||||||
while(pNode.point != point2) {
|
while(pNode.point != point2 && edge > pNode.point) {
|
||||||
points += pNode.point
|
points += pNode.point
|
||||||
nTriangles += pNode.triangle
|
nTriangles += pNode.triangle
|
||||||
pNode = pNode.next
|
pNode = pNode.next
|
||||||
@ -437,9 +438,13 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
|
|||||||
if(illegal && !t2.finalized) {
|
if(illegal && !t2.finalized) {
|
||||||
|
|
||||||
// Flip edge and rotate everything clockwise
|
// Flip edge and rotate everything clockwise
|
||||||
|
|
||||||
|
// Legalize points
|
||||||
t1.legalize(oPoint)
|
t1.legalize(oPoint)
|
||||||
t2.legalize(oPoint, point)
|
t2.legalize(oPoint, point)
|
||||||
|
|
||||||
|
// Update neighbors
|
||||||
|
|
||||||
// Copy old neighbors
|
// Copy old neighbors
|
||||||
val neighbors = List(t2.neighbors(0), t2.neighbors(1), t2.neighbors(2))
|
val neighbors = List(t2.neighbors(0), t2.neighbors(1), t2.neighbors(2))
|
||||||
// Clear old neighbors
|
// Clear old neighbors
|
||||||
|
@ -42,16 +42,6 @@ class Mesh(initialTriangle: Triangle) {
|
|||||||
val debug = HashSet.empty[Triangle]
|
val debug = HashSet.empty[Triangle]
|
||||||
val triangles = new ArrayBuffer[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
|
// Recursively collect triangles
|
||||||
def clean(triangle: Triangle) {
|
def clean(triangle: Triangle) {
|
||||||
if(triangle != null && !triangle.interior) {
|
if(triangle != null && !triangle.interior) {
|
||||||
|
@ -44,13 +44,14 @@ class Triangle(val points: Array[Point]) {
|
|||||||
var neighbors = new Array[Triangle](3)
|
var neighbors = new Array[Triangle](3)
|
||||||
// Flags to determine if an edge is the final Delauney edge
|
// Flags to determine if an edge is the final Delauney edge
|
||||||
val edges = Array(false, false, false)
|
val edges = Array(false, false, false)
|
||||||
|
// Finalization flag. Set true if legalized or edge constrained
|
||||||
// Finalization flag
|
var finalized = false
|
||||||
|
// Has this triangle been marked as an interoir triangle?
|
||||||
var interior = false
|
var interior = false
|
||||||
|
|
||||||
var finalized = 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))
|
||||||
var test = false
|
def contains(p: Point, q: Point): Boolean = (contains(p) && contains(q))
|
||||||
|
|
||||||
// Update neighbor pointers
|
// Update neighbor pointers
|
||||||
private def markNeighbor(p1: Point, p2: Point, t: Triangle) {
|
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
|
// Fast point in triangle test
|
||||||
def pointIn(point: Point): Boolean = {
|
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
|
// Mark edge as constrained
|
||||||
def markEdge(p: Point, q: Point) {
|
def markEdge(p: Point, q: Point) {
|
||||||
if((q == points(0) && p == points(1)) || (q == points(1) && p == points(0))) {
|
if((q == points(0) && p == points(1)) || (q == points(1) && p == points(0))) {
|
||||||
|
Loading…
Reference in New Issue
Block a user