mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-05 22:09:52 +01:00
edge event work
This commit is contained in:
parent
552cc3f564
commit
7d87363ba7
@ -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)}
|
||||
}
|
||||
|
||||
|
@ -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,9 +141,15 @@ 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
|
||||
}
|
||||
|
||||
// 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))
|
||||
}
|
||||
|
||||
@ -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
|
||||
firstTriangle mark(edge.p, edge.q)
|
||||
}
|
||||
|
||||
// Mark constrained edge
|
||||
if(contains)
|
||||
firstTriangle mark edge
|
||||
|
||||
}
|
||||
|
||||
// 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))
|
||||
@ -454,10 +481,4 @@ class CDT(val points: List[Point], val segments: List[Segment], iTriangle: Trian
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
// Final step in the sweep-line CDT algo
|
||||
private def finalization {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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,20 +267,35 @@ 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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user