mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-26 15:26:12 +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.setColor(blue)
|
||||||
g.draw(triangle)
|
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
|
mousePressed = true
|
||||||
mousePosOld = mousePos
|
mousePosOld = mousePos
|
||||||
mousePos = Point(x, y)
|
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
|
slCDT triangulate
|
||||||
val runTime = System.nanoTime - t1
|
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("CDT average (ms) = " + runTime*1e-6)
|
||||||
println("Number of triangles = " + slCDT.triangles.size)
|
println("Number of triangles = " + slCDT.triangles.size)
|
||||||
println
|
println
|
||||||
|
@ -53,6 +53,9 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
|||||||
def triangleMesh = mesh.map
|
def triangleMesh = mesh.map
|
||||||
def debugTriangles = mesh.debug
|
def debugTriangles = mesh.debug
|
||||||
|
|
||||||
|
val cList = new ArrayBuffer[Point]
|
||||||
|
var refine = false
|
||||||
|
|
||||||
// Initialize edges
|
// Initialize edges
|
||||||
initEdges(polyLine)
|
initEdges(polyLine)
|
||||||
|
|
||||||
@ -62,9 +65,20 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
|||||||
points = points ++ holePolyLine.toList
|
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
|
// Triangulate simple polygon with holes
|
||||||
def triangulate {
|
def triangulate {
|
||||||
|
|
||||||
|
mesh.map.clear
|
||||||
|
mesh.triangles.clear
|
||||||
|
mesh.debug.clear
|
||||||
|
|
||||||
var xmax, xmin = points.first.x
|
var xmax, xmin = points.first.x
|
||||||
var ymax, ymin = points.first.y
|
var ymax, ymin = points.first.y
|
||||||
|
|
||||||
@ -125,7 +139,6 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
|||||||
if(p1.x > p2.x) {
|
if(p1.x > p2.x) {
|
||||||
return List(p2, p1)
|
return List(p2, p1)
|
||||||
} else if(p1.x == p2.x) {
|
} else if(p1.x == p2.x) {
|
||||||
println(p1 + "," + p2)
|
|
||||||
throw new Exception("Duplicate point")
|
throw new Exception("Duplicate point")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,8 +152,10 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
|||||||
|
|
||||||
// Implement sweep-line
|
// Implement sweep-line
|
||||||
private def sweep {
|
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)
|
val point = points(i)
|
||||||
// Process Point event
|
// Process Point event
|
||||||
@ -167,6 +182,17 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
|||||||
})
|
})
|
||||||
// Collect interior triangles constrained by edges
|
// Collect interior triangles constrained by edges
|
||||||
mesh clean cleanTri
|
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
|
// Point event
|
||||||
@ -286,12 +312,24 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
|||||||
nTriangles += pNode.triangle
|
nTriangles += pNode.triangle
|
||||||
pNode = pNode.next
|
pNode = pNode.next
|
||||||
|
|
||||||
while(pNode.point != point2 && edge > pNode.point) {
|
while(pNode.point != point2) {
|
||||||
points += pNode.point
|
points += pNode.point
|
||||||
nTriangles += pNode.triangle
|
nTriangles += pNode.triangle
|
||||||
pNode = pNode.next
|
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.
|
// Triangulate empty areas.
|
||||||
val T = new ArrayBuffer[Triangle]
|
val T = new ArrayBuffer[Triangle]
|
||||||
triangulate(points.toArray, List(point1, point2), T)
|
triangulate(points.toArray, List(point1, point2), T)
|
||||||
@ -305,6 +343,11 @@ class CDT(polyLine: Array[Point], clearPoint: Point) {
|
|||||||
// Mark constrained edge
|
// Mark constrained edge
|
||||||
T.last markEdge(point1, point2)
|
T.last markEdge(point1, point2)
|
||||||
|
|
||||||
|
if(pNode.point != edge.p) {
|
||||||
|
println("span")
|
||||||
|
//edgeEvent(edge, pNode)
|
||||||
|
}
|
||||||
|
|
||||||
} else if(firstTriangle.contains(edge.q, edge.p)) {
|
} else if(firstTriangle.contains(edge.q, edge.p)) {
|
||||||
// Constrained edge lies on the side of a triangle
|
// Constrained edge lies on the side of a triangle
|
||||||
// Mark constrained edge
|
// Mark constrained edge
|
||||||
|
@ -353,7 +353,8 @@ class Triangle(val points: Array[Point]) {
|
|||||||
|
|
||||||
val b = points(0).x - points(1).x
|
val b = points(0).x - points(1).x
|
||||||
val h = points(2).y - points(1).y
|
val h = points(2).y - points(1).y
|
||||||
(b*h*0.5f)
|
|
||||||
|
Math.abs((b*h*0.5f))
|
||||||
}
|
}
|
||||||
|
|
||||||
def centroid: Point = {
|
def centroid: Point = {
|
||||||
@ -363,4 +364,18 @@ class Triangle(val points: Array[Point]) {
|
|||||||
Point(cx, cy)
|
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
|
// Returns triangle circumcircle point and radius
|
||||||
def circumCircle(a: Point, b: Point, c: Point): Tuple2[Point, Float] = {
|
def circumCircle(a: Point, b: Point, c: Point): Tuple2[Point, Float] = {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user