mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-12-29 06:03:31 +01:00
code cleanup
This commit is contained in:
parent
dc70f1ca78
commit
012dab34d3
@ -82,7 +82,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
var currentModel = nazcaMonkey
|
var currentModel = nazcaMonkey
|
||||||
|
|
||||||
def init(container: GameContainer) {
|
def init(container: GameContainer) {
|
||||||
selectModel
|
selectModel(currentModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
def update(gc: GameContainer, delta: Int) {
|
def update(gc: GameContainer, delta: Int) {
|
||||||
@ -109,10 +109,10 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
polygon.addPoint(v.x, v.y)
|
polygon.addPoint(v.x, v.y)
|
||||||
}
|
}
|
||||||
if(!drawMap) {
|
if(!drawMap) {
|
||||||
//val lCirc = new Circle(t.leftPoint.x, t.leftPoint.y, 4)
|
val lCirc = new Circle(t.leftPoint.x, t.leftPoint.y, 4)
|
||||||
//g.setColor(blue); g.draw(lCirc); g.fill(lCirc)
|
g.setColor(blue); g.draw(lCirc); g.fill(lCirc)
|
||||||
//val rCirc = new Circle(t.rightPoint.x+5, t.rightPoint.y, 4)
|
val rCirc = new Circle(t.rightPoint.x+5, t.rightPoint.y, 4)
|
||||||
//g.setColor(yellow); g.draw(rCirc); g.fill(rCirc)
|
g.setColor(yellow); g.draw(rCirc); g.fill(rCirc)
|
||||||
}
|
}
|
||||||
g.setColor(red)
|
g.setColor(red)
|
||||||
g.draw(polygon)
|
g.draw(polygon)
|
||||||
@ -175,19 +175,19 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
hiLighter = tesselator.polygons.size-1
|
hiLighter = tesselator.polygons.size-1
|
||||||
}
|
}
|
||||||
if(c == 'm') drawMap = !drawMap
|
if(c == 'm') drawMap = !drawMap
|
||||||
if(c == '1') {currentModel = nazcaMonkey; selectModel}
|
if(c == '1') selectModel(nazcaMonkey)
|
||||||
if(c == '2') {currentModel = bird; selectModel}
|
if(c == '2') selectModel(bird)
|
||||||
if(c == '3') {currentModel = strange; selectModel}
|
if(c == '3') selectModel(strange)
|
||||||
if(c == '4') {currentModel = snake; selectModel}
|
if(c == '4') selectModel(snake)
|
||||||
if(c == '5') {currentModel = star; selectModel}
|
if(c == '5') selectModel(star)
|
||||||
if(c == '6') {currentModel = i18; selectModel}
|
if(c == '6') selectModel(i18)
|
||||||
if(c == 's') drawSegs = !drawSegs
|
if(c == 's') drawSegs = !drawSegs
|
||||||
if(c == 'e') {drawEarClip = !drawEarClip; selectModel}
|
if(c == 'e') {drawEarClip = !drawEarClip; selectModel(currentModel)}
|
||||||
if(c == 'h') {hertelMehlhorn = !hertelMehlhorn; selectModel}
|
if(c == 'h') {hertelMehlhorn = !hertelMehlhorn; selectModel(currentModel)}
|
||||||
}
|
}
|
||||||
|
|
||||||
def selectModel {
|
def selectModel(model: String) {
|
||||||
currentModel match {
|
model match {
|
||||||
case "data/nazca_monkey.dat" =>
|
case "data/nazca_monkey.dat" =>
|
||||||
loadModel(nazcaMonkey, 4.5f, Point(400, 300), 1500)
|
loadModel(nazcaMonkey, 4.5f, Point(400, 300), 1500)
|
||||||
case "data/bird.dat" =>
|
case "data/bird.dat" =>
|
||||||
@ -199,10 +199,11 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
case "data/strange.dat" =>
|
case "data/strange.dat" =>
|
||||||
loadModel(strange, -1f, Point(0f, 0f), 15)
|
loadModel(strange, -1f, Point(0f, 0f), 15)
|
||||||
case "data/i.18" =>
|
case "data/i.18" =>
|
||||||
loadModel(i18, 15f, Point(500f, 400f), 20)
|
loadModel(i18, 20f, Point(600f, 500f), 20)
|
||||||
case _ =>
|
case _ =>
|
||||||
assert(false)
|
assert(false)
|
||||||
}
|
}
|
||||||
|
currentModel = model
|
||||||
}
|
}
|
||||||
|
|
||||||
def loadModel(model: String, scale: Float, center: Point, maxTriangles: Int) {
|
def loadModel(model: String, scale: Float, center: Point, maxTriangles: Int) {
|
||||||
@ -228,15 +229,13 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
|||||||
throw new Exception("Bad input file")
|
throw new Exception("Bad input file")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
points.foreach(println)
|
|
||||||
segments = new ArrayBuffer[Segment]
|
segments = new ArrayBuffer[Segment]
|
||||||
for(i <- 0 until polyX.size-1)
|
for(i <- 0 until polyX.size-1)
|
||||||
segments += new Segment(points(i), points(i+1))
|
segments += new Segment(points(i), points(i+1))
|
||||||
// Connect the end points
|
|
||||||
segments += new Segment(points.first, points.last)
|
segments += new Segment(points.first, points.last)
|
||||||
|
|
||||||
val cdt = CDT.init(points)
|
//val cdt = CDT.init(points)
|
||||||
println(cdt.points.size + "," + cdt.segments.size)
|
|
||||||
|
|
||||||
println("Number of points = " + polyX.size)
|
println("Number of points = " + polyX.size)
|
||||||
println
|
println
|
||||||
|
@ -30,7 +30,34 @@
|
|||||||
*/
|
*/
|
||||||
package org.poly2tri.cdt
|
package org.poly2tri.cdt
|
||||||
|
|
||||||
// Advancing front
|
import shapes.{Point, Triangle}
|
||||||
class AFront {
|
|
||||||
|
|
||||||
|
// Advancing front
|
||||||
|
class AFront(iTriangle: Triangle) {
|
||||||
|
|
||||||
|
// Doubly linked list
|
||||||
|
var head = new Node(iTriangle.points(0), iTriangle)
|
||||||
|
var tail = new Node(iTriangle.points(2), iTriangle)
|
||||||
|
|
||||||
|
head.next = new Node(iTriangle.points(1), iTriangle)
|
||||||
|
head.next.next = tail
|
||||||
|
tail.prev = head.next
|
||||||
|
|
||||||
|
def locate(point: Point): Tuple2[List[Point], Triangle] = {
|
||||||
|
var node = head
|
||||||
|
while(node != tail) {
|
||||||
|
if(point.x > node.point.x && point.x < node.next.point.x)
|
||||||
|
return (List(node.point, node.next.point), node.triangle)
|
||||||
|
node = node.next
|
||||||
|
}
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Node(val point: Point, val triangle: Triangle) {
|
||||||
|
|
||||||
|
var next: Node = null
|
||||||
|
var prev: Node = null
|
||||||
|
}
|
@ -45,10 +45,11 @@ object CDT {
|
|||||||
// Inital triangle factor
|
// Inital triangle factor
|
||||||
val ALPHA = 0.3f
|
val ALPHA = 0.3f
|
||||||
|
|
||||||
|
// Triangulate simple polygon
|
||||||
def init(points: ArrayBuffer[Point]): CDT = {
|
def init(points: ArrayBuffer[Point]): CDT = {
|
||||||
|
|
||||||
var xmax, xmin = 0f
|
var xmax, xmin = shearTransform(points.first).x
|
||||||
var ymax, ymin = 0f
|
var ymax, ymin = shearTransform(points.first).y
|
||||||
|
|
||||||
// Calculate bounds
|
// Calculate bounds
|
||||||
for(i <- 0 until points.size) {
|
for(i <- 0 until points.size) {
|
||||||
@ -56,27 +57,32 @@ object CDT {
|
|||||||
val p = points(i)
|
val p = points(i)
|
||||||
if(p.x > xmax) xmax = p.x
|
if(p.x > xmax) xmax = p.x
|
||||||
if(p.x < xmin) xmin = p.x
|
if(p.x < xmin) xmin = p.x
|
||||||
if(p.y > ymax) ymax = p.x
|
if(p.y > ymax) ymax = p.y
|
||||||
if(p.y < ymin) ymin = p.x
|
if(p.y < ymin) ymin = p.y
|
||||||
}
|
}
|
||||||
|
|
||||||
val deltaX = ALPHA * (xmax - xmin)
|
val deltaX = ALPHA * (xmax - xmin)
|
||||||
val deltaY = ALPHA * (ymax - ymin)
|
val deltaY = ALPHA * (ymax - ymin)
|
||||||
val p1 = Point(xmin - deltaX, ymin - deltaY)
|
val p1 = Point(xmin - deltaX, ymin - deltaY)
|
||||||
val p2 = Point(xmax - deltaX, ymin - deltaY)
|
val p2 = Point(xmax + deltaX, ymin - deltaY)
|
||||||
|
|
||||||
val initialTriangle = new Triangle(Array(p2, points(0), p1), null)
|
|
||||||
val segments = initSegments(points)
|
val segments = initSegments(points)
|
||||||
val sortedPoints = pointSort(points)
|
val sortedPoints = pointSort(points)
|
||||||
|
val initialTriangle = new Triangle(Array(p1, sortedPoints(0), p2), null)
|
||||||
new CDT(sortedPoints, segments, initialTriangle)
|
new CDT(sortedPoints, segments, initialTriangle)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create segments and connect end points
|
// Create segments and connect end points; update edge event pointer
|
||||||
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) {
|
||||||
segments = new Segment(points(i), points(i+1)) :: segments
|
val segment = new Segment(points(i), points(i+1))
|
||||||
segments = new Segment(points.first, points.last) :: segments
|
points(i+1).eEvent = segment
|
||||||
|
segments = segment :: segments
|
||||||
|
}
|
||||||
|
val segment = new Segment(points.first, points.last)
|
||||||
|
points.first.eEvent = segment
|
||||||
|
segments = segment :: segments
|
||||||
segments
|
segments
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +107,9 @@ class CDT(val points: List[Point], val segments: List[Segment], initialTriangle:
|
|||||||
|
|
||||||
// The triangle mesh
|
// The triangle mesh
|
||||||
val mesh = new Mesh(initialTriangle)
|
val mesh = new Mesh(initialTriangle)
|
||||||
|
// Advancing front
|
||||||
|
val aFront = new AFront(initialTriangle)
|
||||||
|
|
||||||
// Sweep points; build mesh
|
// Sweep points; build mesh
|
||||||
sweep
|
sweep
|
||||||
// Finalize triangulation
|
// Finalize triangulation
|
||||||
@ -109,6 +117,14 @@ class CDT(val points: List[Point], val segments: List[Segment], initialTriangle:
|
|||||||
|
|
||||||
// Implement sweep-line paradigm
|
// Implement sweep-line paradigm
|
||||||
private def sweep {
|
private def sweep {
|
||||||
|
|
||||||
|
for(i <- 1 until points.size) {
|
||||||
|
val point = points(i)
|
||||||
|
val triangle = aFront.locate(point)
|
||||||
|
val (nPoints, nTriangle) = triangle
|
||||||
|
println(nPoints)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private def finalization {
|
private def finalization {
|
||||||
|
@ -38,8 +38,6 @@ case class Point(val x: Float, val y: Float) {
|
|||||||
var segment: Segment = null
|
var segment: Segment = null
|
||||||
// Edge event pointer for CDT
|
// Edge event pointer for CDT
|
||||||
var eEvent: Segment = null
|
var eEvent: Segment = null
|
||||||
// Point event pointer for CDT
|
|
||||||
var pEvent: Segment = null
|
|
||||||
|
|
||||||
@inline def -(p: Point) = Point(x - p.x, y - p.y)
|
@inline def -(p: Point) = Point(x - p.x, y - p.y)
|
||||||
@inline def +(p: Point) = Point(x + p.x, y + p.y)
|
@inline def +(p: Point) = Point(x + p.x, y + p.y)
|
||||||
|
@ -33,7 +33,7 @@ package org.poly2tri.shapes
|
|||||||
// Triangle-based data structures are know to have better performance than quad-edge structures
|
// Triangle-based data structures are know to have better performance than quad-edge structures
|
||||||
// See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator"
|
// See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator"
|
||||||
// "Triangulations in CGAL"
|
// "Triangulations in CGAL"
|
||||||
class Triangle(points: Array[Point], neighbors: Array[Triangle]) {
|
class Triangle(val points: Array[Point], val neighbors: Array[Triangle]) {
|
||||||
|
|
||||||
// Flags to determine if an edge is the final Delauney edge
|
// Flags to determine if an edge is the final Delauney edge
|
||||||
val edges = new Array[Boolean](3)
|
val edges = new Array[Boolean](3)
|
||||||
|
Loading…
Reference in New Issue
Block a user