mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-26 15:26:12 +01:00
updated comments
This commit is contained in:
parent
ed89aea7c0
commit
d2dd39686e
@ -42,7 +42,7 @@ import earClip.EarClip
|
||||
import cdt.CDT
|
||||
|
||||
// TODO: Lots of documentation!
|
||||
|
||||
// : Add Hertel-Mehlhorn algorithm
|
||||
object Poly2Tri {
|
||||
|
||||
def main(args: Array[String]) {
|
||||
@ -250,11 +250,15 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
mousePressed = true
|
||||
mousePosOld = mousePos
|
||||
mousePos = Point(x, y)
|
||||
/*
|
||||
val point = mousePos/scaleFactor + Point(deltaX, deltaY)
|
||||
slCDT.addPoint(point)
|
||||
slCDT.triangulate
|
||||
*/
|
||||
|
||||
// Right click
|
||||
// Correctly adjust for pan and zoom
|
||||
if(mouseButton == 1) {
|
||||
val point = mousePos/scaleFactor + Point(deltaX, deltaY)
|
||||
slCDT.addPoint(point)
|
||||
slCDT.triangulate
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -306,6 +310,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
if (hiLighter == -1)
|
||||
hiLighter = seidel.polygons.size-1
|
||||
}
|
||||
|
||||
if(c == 'm') drawMap = !drawMap
|
||||
if(c == 'd') drawCDT = !drawCDT
|
||||
if(c == '1') selectModel(nazcaMonkey)
|
||||
@ -320,6 +325,8 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
if(c == 's') drawSegs = !drawSegs
|
||||
if(c == 'c') drawcdtMesh = !drawcdtMesh
|
||||
if(c == 'e') {drawEarClip = !drawEarClip; drawCDT = false; selectModel(currentModel)}
|
||||
if(c == 'r') slCDT.refine
|
||||
|
||||
}
|
||||
|
||||
def selectModel(model: String) {
|
||||
@ -434,12 +441,8 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
}
|
||||
|
||||
slCDT triangulate
|
||||
val runTime = System.nanoTime - t1
|
||||
val runTime = System.nanoTime - t1
|
||||
|
||||
for(j <- 0 until 1) {
|
||||
slCDT.refine
|
||||
}
|
||||
//slCDT.refine
|
||||
println("CDT average (ms) = " + runTime*1e-6)
|
||||
println("Number of triangles = " + slCDT.triangles.size)
|
||||
println
|
||||
|
@ -114,6 +114,23 @@ class AFront(iTriangle: Triangle) {
|
||||
|
||||
}
|
||||
|
||||
// Transition from AFront traversal to interior mesh traversal
|
||||
def aboveEdge(first: Node, pNode: Node, last: Triangle,
|
||||
point2: Point, ahead:Boolean): Node =
|
||||
if(ahead) {
|
||||
val n = new Node(point2, pNode.prev.triangle)
|
||||
link (first, n, last)
|
||||
n.next = pNode
|
||||
pNode.prev = n
|
||||
n
|
||||
} else {
|
||||
val n = new Node(point2, last)
|
||||
link (n, first, last)
|
||||
pNode.next = n
|
||||
n.prev = pNode
|
||||
pNode
|
||||
}
|
||||
|
||||
def -=(tuple: Tuple3[Node, Node, Triangle]) {
|
||||
val (node, kNode, triangle) = tuple
|
||||
kNode.next.prev = node
|
||||
|
@ -41,10 +41,6 @@ import utils.Util
|
||||
* International Journal of Geographical Information Science
|
||||
*/
|
||||
|
||||
// NOTE: May need to implement edge insertion which combines advancing front (AF)
|
||||
// and triangle traversal respectively. See figure 14(a) from Domiter et al.
|
||||
// Although it may not be necessary for simple polygons....
|
||||
|
||||
// clearPoint is any interior point inside the polygon
|
||||
class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
|
||||
@ -67,8 +63,7 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
}
|
||||
|
||||
// Add an internal point
|
||||
// Good for manually refining the mesh. Use this when you want to eliminate
|
||||
// skinny triangles
|
||||
// Good for manually refining the mesh
|
||||
def addPoint(point: Point) {
|
||||
points = point :: points
|
||||
}
|
||||
@ -186,21 +181,25 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
|
||||
}
|
||||
|
||||
// Refine the mesh using Steiner points
|
||||
// Delauney Refinement: Refine triangules using Steiner points
|
||||
// Probably overkill for 2D games, and will create a large number of
|
||||
// triangles that are probably unoptimal for a physics engine like
|
||||
// Box2D.... Better to manually enter interior points for mesh "smoothing"
|
||||
// TODO: Finish implementation... Maybe!
|
||||
def refine {
|
||||
cList.clear
|
||||
mesh.triangles.foreach(t => {
|
||||
if(t.thin) {
|
||||
val center = Util.circumcenter(t.points(0), t.points(1), t.points(2))
|
||||
cList += center
|
||||
addPoint(center)
|
||||
cList += center
|
||||
addPoint(center)
|
||||
}
|
||||
})
|
||||
// Retriangulate
|
||||
if(cList.size > 0)
|
||||
triangulate
|
||||
}
|
||||
|
||||
|
||||
// Point event
|
||||
private def pointEvent(point: Point): Node = {
|
||||
|
||||
@ -231,6 +230,7 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
|
||||
if(firstTriangle != null && !firstTriangle.contains(edge)) {
|
||||
|
||||
// Interior mesh traversal - edge is "burried" in the mesh
|
||||
// Constrained edge lies below the advancing front. Traverse through intersected triangles,
|
||||
// form empty pseudo-polygons, and re-triangulate
|
||||
|
||||
@ -238,14 +238,23 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
val tList = new ArrayBuffer[Triangle]
|
||||
tList += firstTriangle
|
||||
|
||||
while(!tList.last.contains(edge.p))
|
||||
while(tList.last != null && !tList.last.contains(edge.p))
|
||||
tList += tList.last.findNeighbor(edge.p)
|
||||
|
||||
// TODO: Finish implementing edge insertion which combines advancing front (AF)
|
||||
// and triangle traversal respectively. See figure 14(a) from Domiter et al.
|
||||
// Should only occur with complex patterns of interior points
|
||||
// Already added provision for transitioning from AFront traversal to
|
||||
// interior mesh traversal - may need to add the opposite case
|
||||
if(tList.last == null)
|
||||
throw new Exception("Not implemented yet - interior points too complex")
|
||||
|
||||
// Neighbor triangles
|
||||
// HashMap or set may improve performance
|
||||
val nTriangles = new ArrayBuffer[Triangle]
|
||||
|
||||
// Remove old triangles; collect neighbor triangles
|
||||
// Keep duplicates out
|
||||
// Keep duplicates out
|
||||
tList.foreach(t => {
|
||||
t.neighbors.foreach(n => if(n != null && !tList.contains(n)) nTriangles += n)
|
||||
mesh.map -= t
|
||||
@ -304,6 +313,7 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
|
||||
} else if(firstTriangle == null) {
|
||||
|
||||
// AFront traversal
|
||||
// No triangles are intersected by the edge; edge must lie outside the mesh
|
||||
// Apply constraint; traverse the advancing front, and build triangles
|
||||
|
||||
@ -315,6 +325,9 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
nTriangles += pNode.triangle
|
||||
|
||||
val ahead = (edge.p.x > edge.q.x)
|
||||
|
||||
// If this is true we transition from AFront traversal to
|
||||
// interior mesh traversal
|
||||
var aboveEdge = false
|
||||
|
||||
if(ahead) {
|
||||
@ -327,7 +340,7 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
aboveEdge = edge < pNode.point
|
||||
}
|
||||
} else {
|
||||
// Scal left
|
||||
// Scan left
|
||||
pNode = pNode.prev
|
||||
while(pNode.point != edge.p && !aboveEdge) {
|
||||
points += pNode.point
|
||||
@ -353,31 +366,19 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
// Update neighbors
|
||||
edgeNeighbors(nTriangles, T)
|
||||
|
||||
// Update advancing front
|
||||
if(ahead && !aboveEdge)
|
||||
aFront link (first, pNode, T.last)
|
||||
else if(!ahead && !aboveEdge)
|
||||
aFront link (pNode, first, T.last)
|
||||
|
||||
// Mark constrained edge
|
||||
T.last markEdge(edge.q, point2)
|
||||
T.last markEdge(edge.q, point2)
|
||||
|
||||
// Update advancing front
|
||||
if(aboveEdge) {
|
||||
val iNode = if(ahead) {
|
||||
val n = new Node(point2, pNode.prev.triangle)
|
||||
aFront link (first, n, T.last)
|
||||
n.next = pNode
|
||||
pNode.prev = n
|
||||
n
|
||||
} else {
|
||||
val n = new Node(point2, T.last)
|
||||
aFront link (n, first, T.last)
|
||||
pNode.next = n
|
||||
n.prev = pNode
|
||||
pNode
|
||||
}
|
||||
val iNode = aFront.aboveEdge(first, pNode, T.last, point2, ahead)
|
||||
edgeEvent(new Segment(edge.p, point2), iNode)
|
||||
}
|
||||
} else {
|
||||
if(ahead)
|
||||
aFront link (first, pNode, T.last)
|
||||
else
|
||||
aFront link (pNode, first, T.last)
|
||||
}
|
||||
|
||||
} else if(firstTriangle.contains(edge.q, edge.p)) {
|
||||
// Constrained edge lies on the side of a triangle
|
||||
|
@ -168,7 +168,7 @@ class Triangle(val points: Array[Point]) {
|
||||
else if(Util.orient2d(points(0), points(2), p) > 0)
|
||||
return neighbors(1)
|
||||
else
|
||||
throw new Exception("Point not found")
|
||||
return null
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user