mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-05 13:59:53 +01:00
added new circumcenter test
This commit is contained in:
parent
5811c2c0d1
commit
daa7b135c8
@ -209,6 +209,13 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
g.setColor(blue)
|
||||
g.draw(triangle)
|
||||
})
|
||||
|
||||
//slCDT.cList.foreach(c => {
|
||||
for(i <- 0 until 7) {
|
||||
val circ = new Circle(slCDT.cList(i).x, slCDT.cList(i).y, 0.5f)
|
||||
g.setColor(blue); g.draw(circ); g.fill(circ)
|
||||
}
|
||||
//})
|
||||
|
||||
}
|
||||
|
||||
@ -243,6 +250,11 @@ 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
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
@ -424,6 +436,15 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
slCDT triangulate
|
||||
val runTime = System.nanoTime - t1
|
||||
|
||||
if(slCDT.cList.size > 1) {
|
||||
//slCDT.addPoint(slCDT.cList(0))
|
||||
//slCDT.addPoint(slCDT.cList(1))
|
||||
println(slCDT.cList.size)
|
||||
for(i <- 0 until 7)
|
||||
slCDT.addPoint(slCDT.cList(i))
|
||||
slCDT.triangulate
|
||||
}
|
||||
|
||||
println("CDT average (ms) = " + runTime*1e-6)
|
||||
println("Number of triangles = " + slCDT.triangles.size)
|
||||
println
|
||||
|
@ -53,6 +53,9 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
def triangleMesh = mesh.map
|
||||
def debugTriangles = mesh.debug
|
||||
|
||||
val cList = new ArrayBuffer[Point]
|
||||
var refine = false
|
||||
|
||||
// Initialize edges
|
||||
initEdges(polyLine)
|
||||
|
||||
@ -62,9 +65,20 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
points = points ++ holePolyLine.toList
|
||||
}
|
||||
|
||||
// Add an internal point
|
||||
// Good for manually refining the mesh. Use this when you want to eliminate
|
||||
// skinny triangles
|
||||
def addPoint(point: Point) {
|
||||
points = point :: points
|
||||
}
|
||||
|
||||
// Triangulate simple polygon with holes
|
||||
def triangulate {
|
||||
|
||||
mesh.map.clear
|
||||
mesh.triangles.clear
|
||||
mesh.debug.clear
|
||||
|
||||
var xmax, xmin = points.first.x
|
||||
var ymax, ymin = points.first.y
|
||||
|
||||
@ -125,7 +139,6 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
if(p1.x > p2.x) {
|
||||
return List(p2, p1)
|
||||
} else if(p1.x == p2.x) {
|
||||
println(p1 + "," + p2)
|
||||
throw new Exception("Duplicate point")
|
||||
}
|
||||
}
|
||||
@ -139,8 +152,10 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
|
||||
// Implement sweep-line
|
||||
private def sweep {
|
||||
// 48 67
|
||||
val size = if(refine) 68 else points.size
|
||||
|
||||
for(i <- 1 until points.size) {
|
||||
for(i <- 1 until size) {
|
||||
|
||||
val point = points(i)
|
||||
// Process Point event
|
||||
@ -167,6 +182,17 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
})
|
||||
// Collect interior triangles constrained by edges
|
||||
mesh clean cleanTri
|
||||
|
||||
mesh.triangles.foreach(t => {
|
||||
if(t.thin) {
|
||||
val center = Util.circumcenter(t.points(0), t.points(1), t.points(2))
|
||||
cList += center
|
||||
refine = true
|
||||
//addPoint(center)
|
||||
//mesh.debug += t
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Point event
|
||||
@ -286,12 +312,24 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
nTriangles += pNode.triangle
|
||||
pNode = pNode.next
|
||||
|
||||
while(pNode.point != point2 && edge > pNode.point) {
|
||||
while(pNode.point != point2) {
|
||||
points += pNode.point
|
||||
nTriangles += pNode.triangle
|
||||
pNode = pNode.next
|
||||
}
|
||||
|
||||
val s = new Segment(first.point, first.next.point)
|
||||
if(s > point1) {
|
||||
mesh.map -= first.triangle
|
||||
first.triangle = first.triangle.neighborCW(first.point)
|
||||
val t = first.triangle.neighborAcross(first.point)
|
||||
val n = new Node(point1, t)
|
||||
first.next = n
|
||||
n.prev = first
|
||||
n.next = first.next.next
|
||||
n.next.prev = n
|
||||
}
|
||||
|
||||
// Triangulate empty areas.
|
||||
val T = new ArrayBuffer[Triangle]
|
||||
triangulate(points.toArray, List(point1, point2), T)
|
||||
@ -305,6 +343,11 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
||||
// Mark constrained edge
|
||||
T.last markEdge(point1, point2)
|
||||
|
||||
if(pNode.point != edge.p) {
|
||||
println("span")
|
||||
//edgeEvent(edge, pNode)
|
||||
}
|
||||
|
||||
} else if(firstTriangle.contains(edge.q, edge.p)) {
|
||||
// Constrained edge lies on the side of a triangle
|
||||
// Mark constrained edge
|
||||
|
@ -353,7 +353,8 @@ class Triangle(val points: Array[Point]) {
|
||||
|
||||
val b = points(0).x - points(1).x
|
||||
val h = points(2).y - points(1).y
|
||||
(b*h*0.5f)
|
||||
|
||||
Math.abs((b*h*0.5f))
|
||||
}
|
||||
|
||||
def centroid: Point = {
|
||||
@ -363,4 +364,18 @@ class Triangle(val points: Array[Point]) {
|
||||
Point(cx, cy)
|
||||
}
|
||||
|
||||
def thin: Boolean = {
|
||||
val a1 = (points(1) - points(0))
|
||||
val b1 = (points(2) - points(0))
|
||||
val a2 = (points(0) - points(1))
|
||||
val b2 = (points(2) - points(1))
|
||||
val angle1 = Math.abs(Math.atan2(a1 cross b1, a1 dot b1))
|
||||
val angle2 = Math.abs(Math.atan2(a2 cross b2, a2 dot b2))
|
||||
val angle3 = Math.Pi - angle1 - angle2
|
||||
// 30 degrees
|
||||
val minAngle = Math.Pi/6
|
||||
//println(angle1 + "," + angle2 + "," + angle3)
|
||||
(angle1 <= minAngle || angle2 <= minAngle || angle3 <= minAngle)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -133,6 +133,30 @@ object Util {
|
||||
|
||||
}
|
||||
|
||||
// Original by Jonathan Shewchuk
|
||||
// http://www.ics.uci.edu/~eppstein/junkyard/circumcenter.html
|
||||
def circumcenter(a: Point, b: Point, c: Point): Point = {
|
||||
|
||||
/* Use coordinates relative to point `a' of the triangle. */
|
||||
val xba = b.x - a.x
|
||||
val yba = b.y - a.y
|
||||
val xca = c.x - a.x
|
||||
val yca = c.y - a.y
|
||||
/* Squares of lengths of the edges incident to `a'. */
|
||||
val balength = xba * xba + yba * yba
|
||||
val calength = xca * xca + yca * yca
|
||||
|
||||
/* Calculate the denominator of the formulae. */
|
||||
val denominator = 0.5 / orient2d(b, c, a)
|
||||
|
||||
/* Calculate offset (from `a') of circumcenter. */
|
||||
val xcirca = (yca * balength - yba * calength) * denominator
|
||||
val ycirca = (xba * calength - xca * balength) * denominator
|
||||
|
||||
a + Point(xcirca.toFloat, ycirca.toFloat)
|
||||
|
||||
}
|
||||
|
||||
// Returns triangle circumcircle point and radius
|
||||
def circumCircle(a: Point, b: Point, c: Point): Tuple2[Point, Float] = {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user