mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-26 15:26:12 +01:00
fixed collinear points bug
This commit is contained in:
parent
2a27491146
commit
4b40deb5db
@ -43,8 +43,10 @@ class MonotoneMountain {
|
|||||||
val monoPoly = new ArrayBuffer[Point]
|
val monoPoly = new ArrayBuffer[Point]
|
||||||
// Triangles that constitute the mountain
|
// Triangles that constitute the mountain
|
||||||
val triangles = new ArrayBuffer[Array[Point]]
|
val triangles = new ArrayBuffer[Array[Point]]
|
||||||
|
// Used to track which side of the line we are on
|
||||||
var slop = 0.0f
|
var positive = false
|
||||||
|
// Almost Pi!
|
||||||
|
val SLOP = 3.1
|
||||||
|
|
||||||
// Append a point to the list
|
// Append a point to the list
|
||||||
def +=(point: Point) {
|
def +=(point: Point) {
|
||||||
@ -83,10 +85,15 @@ class MonotoneMountain {
|
|||||||
lastTriangle
|
lastTriangle
|
||||||
} else {
|
} else {
|
||||||
// Initialize internal angles at each nonbase vertex
|
// Initialize internal angles at each nonbase vertex
|
||||||
|
// Link strictly convex vertices into a list, ignore reflex vertices
|
||||||
var p = head.next
|
var p = head.next
|
||||||
while(p != tail) {
|
while(p != tail) {
|
||||||
// Link strictly convex vertices into a list
|
val a = angle(p)
|
||||||
if(convex(p)) convexPoints.enqueue(p)
|
// If the point is almost colinear with it's neighbor, remove it!
|
||||||
|
if(a >= SLOP || a <= -SLOP)
|
||||||
|
remove(p)
|
||||||
|
else
|
||||||
|
if(convex(p)) convexPoints.enqueue(p)
|
||||||
p = p.next
|
p = p.next
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +104,7 @@ class MonotoneMountain {
|
|||||||
val b = ear.clone
|
val b = ear.clone
|
||||||
val c = ear.next.clone
|
val c = ear.next.clone
|
||||||
val triangle = Array(a, b, c)
|
val triangle = Array(a, b, c)
|
||||||
|
|
||||||
triangles += triangle
|
triangles += triangle
|
||||||
|
|
||||||
// Remove ear, update angles and convex list
|
// Remove ear, update angles and convex list
|
||||||
@ -105,17 +113,12 @@ class MonotoneMountain {
|
|||||||
if(c.prev != null && convex(c)) convexPoints.enqueue(c)
|
if(c.prev != null && convex(c)) convexPoints.enqueue(c)
|
||||||
|
|
||||||
}
|
}
|
||||||
if(size >= 4) {
|
|
||||||
println("Size = " + size)
|
|
||||||
println(convex(head.next) + ", Angle: " + slop)
|
|
||||||
println(convex(head.next.next) + ", Angle: " + slop)
|
|
||||||
}
|
|
||||||
assert(size <= 3, "Triangulation bug")
|
assert(size <= 3, "Triangulation bug")
|
||||||
if(size == 3)lastTriangle
|
if(size == 3)lastTriangle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the monotone polygon
|
// Create the monotone polygon
|
||||||
private def genMonoPoly {
|
private def genMonoPoly {
|
||||||
var p = head
|
var p = head
|
||||||
while(p != null) {
|
while(p != null) {
|
||||||
@ -124,13 +127,21 @@ class MonotoneMountain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if the inslide angle between edge v2-v3 and edge v2-v1 is convex
|
def angle(p: Point) = {
|
||||||
|
val a = (p.next - p)
|
||||||
|
val b = (p.prev - p)
|
||||||
|
Math.atan2(a cross b, a dot b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determines if the inslide angle is convex or reflex
|
||||||
private def convex(p: Point) = {
|
private def convex(p: Point) = {
|
||||||
val a = (p.next - p).normalize
|
val cvx = (angle(p) >= 0)
|
||||||
val b = (p.prev - p).normalize
|
if(p.prev == head)
|
||||||
slop = a dot b
|
positive = cvx
|
||||||
slop = 0.1f * Math.round( slop * 10.0f)
|
if(positive != cvx)
|
||||||
(slop >= 0f || slop == -1f || slop == 1f)
|
false
|
||||||
|
else
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
private def lastTriangle {
|
private def lastTriangle {
|
||||||
|
@ -45,6 +45,7 @@ class Point(val x: Float, val y: Float, var segment: Segment) {
|
|||||||
def +(f: Float) = new Point(x + f, y + f)
|
def +(f: Float) = new Point(x + f, y + f)
|
||||||
def *(f: Float) = new Point(x * f, y * f)
|
def *(f: Float) = new Point(x * f, y * f)
|
||||||
def /(a: Float) = new Point(x / a, y / a)
|
def /(a: Float) = new Point(x / a, y / a)
|
||||||
|
def cross(p: Point) = x * p.y - y * p.x
|
||||||
def dot(p: Point) = x * p.x + y * p.y
|
def dot(p: Point) = x * p.x + y * p.y
|
||||||
def length = Math.sqrt(x * x + y * y).toFloat
|
def length = Math.sqrt(x * x + y * y).toFloat
|
||||||
def normalize = this / length
|
def normalize = this / length
|
||||||
|
Loading…
Reference in New Issue
Block a user