mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-11-26 15:26:12 +01:00
fixed Python Seidel algo
This commit is contained in:
parent
bdcfc0eb04
commit
48805d55db
5
data/basic.dat
Normal file
5
data/basic.dat
Normal file
@ -0,0 +1,5 @@
|
||||
100.0 100.0
|
||||
-100.0 100.0
|
||||
-100.0 -100.0
|
||||
0.0 0.0
|
||||
100.0 -100.0
|
@ -14,7 +14,7 @@ SEGMENTS = 25
|
||||
INCREMENT = 2.0 * PI / SEGMENTS
|
||||
|
||||
def init_gl(width, height):
|
||||
#glEnable(GL_LINE_SMOOTH)
|
||||
glEnable(GL_LINE_SMOOTH)
|
||||
glEnable(GL_BLEND)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0)
|
||||
|
@ -5,22 +5,24 @@ from seidel import Triangulator
|
||||
|
||||
class Poly2Tri(Game):
|
||||
|
||||
#Screen size
|
||||
screen_size = 800.0, 600.0
|
||||
|
||||
def __init__(self):
|
||||
super(Poly2Tri, self).__init__(*self.screen_size)
|
||||
|
||||
# Load point set
|
||||
file_name = "../data/star.dat"
|
||||
points = self.load_points(file_name)
|
||||
file_name = "../data/dude.dat"
|
||||
self.points = self.load_points(file_name)
|
||||
|
||||
# Triangulate
|
||||
t1 = self.time
|
||||
seidel = Triangulator(points)
|
||||
seidel = Triangulator(self.points)
|
||||
dt = (self.time - t1) * 1000.0
|
||||
|
||||
self.triangles = seidel.triangles()
|
||||
dt = self.time - t1
|
||||
print "time = %f , num triangles = %d" % (dt, len(self.triangles))
|
||||
self.trapezoids = seidel.trapezoids
|
||||
#self.trapezoids = seidel.trapezoidal_map.map
|
||||
print "time (ms) = %f , num triangles = %d" % (dt, len(self.triangles))
|
||||
|
||||
self.main_loop()
|
||||
|
||||
@ -28,10 +30,19 @@ class Poly2Tri(Game):
|
||||
pass
|
||||
|
||||
def render(self):
|
||||
reset_zoom(1.0, (0,0), self.screen_size)
|
||||
reset_zoom(2.0, (400, 500), self.screen_size)
|
||||
red = 255, 0, 0
|
||||
for t in self.triangles:
|
||||
draw_polygon(t, red)
|
||||
green = 0, 255, 0
|
||||
#draw_polygon(self.points, green)
|
||||
'''
|
||||
yellow = 255, 255, 0
|
||||
for t in self.trapezoids:
|
||||
#verts = self.trapezoids[key].vertices()
|
||||
verts = t.vertices()
|
||||
draw_polygon(verts, yellow)
|
||||
'''
|
||||
|
||||
def load_points(self, file_name):
|
||||
infile = open(file_name, "r")
|
||||
|
155
python/seidel.py
155
python/seidel.py
@ -32,10 +32,11 @@
|
||||
from random import shuffle
|
||||
from math import atan2, floor
|
||||
|
||||
###
|
||||
### Based on Raimund Seidel'e paper "A simple and fast incremental randomized
|
||||
### algorithm for computing trapezoidal decompositions and for triangulating polygons"
|
||||
### (Ported from poly2tri)
|
||||
##
|
||||
## Based on Raimund Seidel'e paper "A simple and fast incremental randomized
|
||||
## algorithm for computing trapezoidal decompositions and for triangulating polygons"
|
||||
## (Ported from poly2tri)
|
||||
##
|
||||
|
||||
class Point(object):
|
||||
|
||||
@ -77,22 +78,20 @@ class Point(object):
|
||||
def less(self, p):
|
||||
return self.x < p.x
|
||||
|
||||
def not_equal(self, p):
|
||||
return not (p.x == self.x and p.y == self.y)
|
||||
|
||||
def clone(self):
|
||||
return Point(self.x, self.y)
|
||||
|
||||
class Edge(object):
|
||||
|
||||
mpoints = []
|
||||
above, below = None, None
|
||||
|
||||
def __init__(self, p, q):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.slope = 0.0 if (q.x - p.x) == 0 else (q.y - p.y)/(q.x - p.x)
|
||||
self.slope = 0.0 if (q.x - p.x) == 0.0 else (q.y - p.y)/(q.x - p.x)
|
||||
self.b = p.y - (p.x * self.slope)
|
||||
self.above, self.below = None, None
|
||||
self.mpoints = []
|
||||
self.mpoints.append(p)
|
||||
self.mpoints.append(q)
|
||||
|
||||
def is_above(self, point):
|
||||
return (floor(point.y) < floor(self.slope * point.x + self.b))
|
||||
@ -105,10 +104,10 @@ class Edge(object):
|
||||
b = self.q
|
||||
a1 = self.signed_area(a, b, d)
|
||||
a2 = self.signed_area(a, b, c)
|
||||
if a1 != 0 and a2 != 0 and (a1 * a2) < 0:
|
||||
if a1 != 0.0 and a2 != 0.0 and (a1 * a2) < 0.0:
|
||||
a3 = self.signed_area(c, d, a)
|
||||
a4 = a3 + a2 - a1
|
||||
if a3 * a4 < 0:
|
||||
if a3 * a4 < 0.0:
|
||||
t = a3 / (a3 - a4)
|
||||
return a + ((b - a) * t)
|
||||
return 0.0
|
||||
@ -123,6 +122,7 @@ class Trapezoid(object):
|
||||
self.right_point = right_point
|
||||
self.top = top
|
||||
self.bottom = bottom
|
||||
self.hash = hash(self)
|
||||
self.upper_left = None
|
||||
self.upper_right = None
|
||||
self.lower_left = None
|
||||
@ -132,24 +132,24 @@ class Trapezoid(object):
|
||||
|
||||
def update_left(self, ul, ll):
|
||||
self.upper_left = ul
|
||||
self.lower_left = ll
|
||||
if ul != None: ul.upper_right = self
|
||||
self.lower_left = ll
|
||||
if ll != None: ll.lower_right = self
|
||||
|
||||
def update_right(self, ur, lr):
|
||||
self.upper_right = ur
|
||||
self.lower_right = lr
|
||||
if ur != None: ur.upper_left = self
|
||||
self.lower_right = lr
|
||||
if lr != None: lr.lower_left = self
|
||||
|
||||
def update_left_right(self, ul, ll, ur, lr):
|
||||
self.upper_left = ul
|
||||
self.lower_left = ll
|
||||
self.upper_right = ur
|
||||
self.lower_right = lr
|
||||
if ul != None: ul.upper_right = self
|
||||
self.lower_left = ll
|
||||
if ll != None: ll.lower_right = self
|
||||
self.upper_right = ur
|
||||
if ur != None: ur.upper_left = self
|
||||
self.lower_right = lr
|
||||
if lr != None: lr.lower_left = self
|
||||
|
||||
def trim_neighbors(self):
|
||||
@ -165,12 +165,11 @@ class Trapezoid(object):
|
||||
self.top.is_above(point) and self.bottom.is_below(point))
|
||||
|
||||
def vertices(self):
|
||||
verts = []
|
||||
verts.append(line_intersect(self.top, self.left_point.x))
|
||||
verts.append(line_intersect(self.bottom, self.left_point.x))
|
||||
verts.append(line_intersect(self.bottom, self.right_point.x))
|
||||
verts.append(line_intersect(self.top, self.right_point.x))
|
||||
return verts
|
||||
v1 = line_intersect(self.top, self.left_point.x)
|
||||
v2 = line_intersect(self.bottom, self.left_point.x)
|
||||
v3 = line_intersect(self.bottom, self.right_point.x)
|
||||
v4 = line_intersect(self.top, self.right_point.x)
|
||||
return v1, v2, v3, v4
|
||||
|
||||
def add_points(self):
|
||||
if self.left_point != self.bottom.p:
|
||||
@ -184,19 +183,19 @@ class Trapezoid(object):
|
||||
|
||||
def line_intersect(edge, x):
|
||||
y = edge.slope * x + edge.b
|
||||
return Point(x, y)
|
||||
return x, y
|
||||
|
||||
class Triangulator(object):
|
||||
|
||||
def __init__(self, poly_line):
|
||||
|
||||
self.polygons = []
|
||||
self.edge_list = self.init_edges(poly_line)
|
||||
self.trapezoids = []
|
||||
self.xmono_poly = []
|
||||
self.edge_list = self.init_edges(poly_line)
|
||||
self.trapezoidal_map = TrapezoidalMap()
|
||||
self.bounding_box = self.trapezoidal_map.bounding_box(self.edge_list)
|
||||
self.query_graph = QueryGraph(isink(self.bounding_box))
|
||||
self.xmono_poly = []
|
||||
|
||||
self.process()
|
||||
|
||||
def triangles(self):
|
||||
@ -216,11 +215,9 @@ class Triangulator(object):
|
||||
for edge in self.edge_list:
|
||||
traps = self.query_graph.follow_edge(edge)
|
||||
for t in traps:
|
||||
try:
|
||||
self.trapezoidal_map.map.remove(t)
|
||||
except:
|
||||
pass
|
||||
for t in traps:
|
||||
# Remove old trapezods
|
||||
del self.trapezoidal_map.map[t.hash]
|
||||
# Bisect old trapezoids and create new
|
||||
cp = t.contains(edge.p)
|
||||
cq = t.contains(edge.q)
|
||||
if cp and cq:
|
||||
@ -237,15 +234,18 @@ class Triangulator(object):
|
||||
self.query_graph.case4(t.sink, edge, tlist)
|
||||
# Add new trapezoids to map
|
||||
for t in tlist:
|
||||
self.trapezoidal_map.map.append(t)
|
||||
self.trapezoidal_map.map[t.hash] = t
|
||||
self.trapezoidal_map.clear()
|
||||
|
||||
# Mark outside trapezoids
|
||||
for t in self.trapezoidal_map.map:
|
||||
#TODO remove invalid/extra trapezoids
|
||||
#print len(self.trapezoidal_map.map)
|
||||
|
||||
# Mark outside trapezoids w/ depth-first search
|
||||
for k, t in self.trapezoidal_map.map.items():
|
||||
self.mark_outside(t)
|
||||
|
||||
# Collect interior trapezoids
|
||||
for t in self.trapezoidal_map.map:
|
||||
for k, t in self.trapezoidal_map.map.items():
|
||||
if t.inside:
|
||||
self.trapezoids.append(t)
|
||||
t.add_points()
|
||||
@ -261,10 +261,9 @@ class Triangulator(object):
|
||||
|
||||
def create_mountains(self):
|
||||
for edge in self.edge_list:
|
||||
if len(edge.mpoints) > 0:
|
||||
if len(edge.mpoints) > 2:
|
||||
mountain = MonotoneMountain()
|
||||
k = merge_sort(edge.mpoints)
|
||||
points = [edge.p] + k + [edge.q]
|
||||
points = merge_sort(edge.mpoints)
|
||||
for p in points:
|
||||
mountain.add(p)
|
||||
mountain.process()
|
||||
@ -296,7 +295,7 @@ class Triangulator(object):
|
||||
edges.append(Edge(q, p))
|
||||
elif p.x < q.x:
|
||||
edges.append(Edge(p, q))
|
||||
shuffle(edges)
|
||||
#shuffle(edges)
|
||||
return edges
|
||||
|
||||
def shear_transform(self, point):
|
||||
@ -323,18 +322,17 @@ def merge_sort(l):
|
||||
|
||||
class TrapezoidalMap(object):
|
||||
|
||||
map = []
|
||||
margin = 50
|
||||
bcross = None
|
||||
tcross = None
|
||||
def __init__(self):
|
||||
self.map = {}
|
||||
self.margin = 50.0
|
||||
self.bcross = None
|
||||
self.tcross = None
|
||||
|
||||
def clear(self):
|
||||
self.bcross = None
|
||||
self.tcross = None
|
||||
map = []
|
||||
|
||||
def case1(self, trapezoid, edge):
|
||||
t = trapezoid; e = edge
|
||||
def case1(self, t, e):
|
||||
trapezoids = []
|
||||
trapezoids.append(Trapezoid(t.left_point, e.p, t.top, t.bottom))
|
||||
trapezoids.append(Trapezoid(e.p, e.q, t.top, e))
|
||||
@ -346,8 +344,7 @@ class TrapezoidalMap(object):
|
||||
trapezoids[3].update_right(t.upper_right, t.lower_right)
|
||||
return trapezoids
|
||||
|
||||
def case2(self, trapezoid, edge):
|
||||
t = trapezoid; e = edge
|
||||
def case2(self, t, e):
|
||||
rp = e.q if e.q.x == t.right_point.x else t.right_point
|
||||
trapezoids = []
|
||||
trapezoids.append(Trapezoid(t.left_point, e.p, t.top, t.bottom))
|
||||
@ -362,8 +359,7 @@ class TrapezoidalMap(object):
|
||||
e.below = trapezoids[2]
|
||||
return trapezoids
|
||||
|
||||
def case3(self, trapezoid, edge):
|
||||
t = trapezoid; e = edge
|
||||
def case3(self, t, e):
|
||||
lp = e.p if e.p.x == t.left_point.x else t.left_point
|
||||
rp = e.q if e.q.x == t.right_point.x else t.right_point
|
||||
trapezoids = []
|
||||
@ -387,8 +383,7 @@ class TrapezoidalMap(object):
|
||||
e.below = trapezoids[1]
|
||||
return trapezoids
|
||||
|
||||
def case4(self, trapezoid, edge):
|
||||
t = trapezoid; e = edge
|
||||
def case4(self, t, e):
|
||||
lp = e.p if e.p.x == t.left_point.x else t.left_point
|
||||
trapezoids = []
|
||||
if self.tcross is t.top:
|
||||
@ -411,20 +406,22 @@ class TrapezoidalMap(object):
|
||||
margin = self.margin
|
||||
max = edges[0].p + margin
|
||||
min = edges[0].q - margin
|
||||
for edge in edges:
|
||||
if edge.p.x > max.x: max = Point(edge.p.x + margin, max.y)
|
||||
if edge.p.y > max.y: max = Point(max.x, edge.p.y + margin)
|
||||
if edge.q.x > max.x: max = Point(edge.q.x + margin, max.y)
|
||||
if edge.q.y > max.y: max = Point(max.x, edge.q.y + margin)
|
||||
if edge.p.x < min.x: min = Point(edge.p.x - margin, min.y)
|
||||
if edge.p.y < min.y: min = Point(min.x, edge.p.y - margin)
|
||||
if edge.q.x < min.x: min = Point(edge.q.x - margin, min.y)
|
||||
if edge.q.y < min.y: min = Point(min.x, edge.q.y - margin)
|
||||
for e in edges:
|
||||
if e.p.x > max.x: max = Point(e.p.x + margin, max.y)
|
||||
if e.p.y > max.y: max = Point(max.x, e.p.y + margin)
|
||||
if e.q.x > max.x: max = Point(e.q.x + margin, max.y)
|
||||
if e.q.y > max.y: max = Point(max.x, e.q.y + margin)
|
||||
if e.p.x < min.x: min = Point(e.p.x - margin, min.y)
|
||||
if e.p.y < min.y: min = Point(min.x, e.p.y - margin)
|
||||
if e.q.x < min.x: min = Point(e.q.x - margin, min.y)
|
||||
if e.q.y < min.y: min = Point(min.x, e.q.y - margin)
|
||||
top = Edge(Point(min.x, max.y), Point(max.x, max.y))
|
||||
bottom = Edge(Point(min.x, min.y), Point(max.x, min.y))
|
||||
left = bottom.p
|
||||
right = top.q
|
||||
return Trapezoid(left, right, top, bottom)
|
||||
trap = Trapezoid(left, right, top, bottom)
|
||||
self.map[hash(trap)] = trap
|
||||
return trap
|
||||
|
||||
class Node(object):
|
||||
|
||||
@ -533,7 +530,6 @@ class QueryGraph:
|
||||
qNode = XNode(edge.q, yNode, isink(tlist[2]))
|
||||
self.replace(sink, qNode)
|
||||
|
||||
|
||||
PI_SLOP = 3.1
|
||||
|
||||
class MonotoneMountain:
|
||||
@ -549,17 +545,17 @@ class MonotoneMountain:
|
||||
self.convex_polies = []
|
||||
|
||||
def add(self, point):
|
||||
if self.size == 0:
|
||||
if self.size is 0:
|
||||
self.head = point
|
||||
self.size += 1
|
||||
elif self.size == 1:
|
||||
if point.not_equal(self.head):
|
||||
self.size = 1
|
||||
elif self.size is 1:
|
||||
if point != self.head:
|
||||
self.tail = point
|
||||
self.tail.prev = self.head
|
||||
self.head.next = self.tail
|
||||
self.size += 1
|
||||
self.size = 2
|
||||
else:
|
||||
if point.not_equal(self.tail):
|
||||
if point != self.tail:
|
||||
self.tail.next = point
|
||||
point.prev = self.tail
|
||||
self.tail = point
|
||||
@ -576,9 +572,9 @@ class MonotoneMountain:
|
||||
self.positive = self.angle_sign()
|
||||
self.gen_mono_poly()
|
||||
p = self.head.next
|
||||
while p is not self.tail:
|
||||
while p != self.tail:
|
||||
a = self.angle(p)
|
||||
if a >= PI_SLOP or a <= -PI_SLOP:
|
||||
if a >= PI_SLOP or a <= -PI_SLOP or a == 0:
|
||||
self.remove(p)
|
||||
elif self.is_convex(p):
|
||||
self.convex_points.append(p)
|
||||
@ -586,16 +582,18 @@ class MonotoneMountain:
|
||||
self.triangulate()
|
||||
|
||||
def triangulate(self):
|
||||
while len(self.convex_points) > 0:
|
||||
while self.convex_points:
|
||||
ear = self.convex_points.pop(0)
|
||||
a = ear.prev
|
||||
b = ear
|
||||
c = ear.next
|
||||
triangle = [a, b, c]
|
||||
triangle = (a, b, c)
|
||||
self.triangles.append(triangle)
|
||||
self.remove(ear)
|
||||
if self.valid(a): self.convex_points.append(a)
|
||||
if self.valid(c): self.convex_points.append(c)
|
||||
if self.valid(a):
|
||||
self.convex_points.append(a)
|
||||
if self.valid(c):
|
||||
self.convex_points.append(c)
|
||||
assert(self.size <= 3, "Triangulation bug, please report")
|
||||
|
||||
def valid(self, p):
|
||||
@ -618,5 +616,6 @@ class MonotoneMountain:
|
||||
return atan2(a.cross(b), a.dot(b)) >= 0
|
||||
|
||||
def is_convex(self, p):
|
||||
if self.positive != (self.angle(p) >= 0): return False
|
||||
if self.positive != (self.angle(p) >= 0):
|
||||
return False
|
||||
return True
|
@ -79,15 +79,16 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
var drawSegs = true
|
||||
var drawCDTMesh = false
|
||||
|
||||
val nazcaMonkey = "data/nazca_monkey.dat"
|
||||
val nazcaHeron = "data/nazca_heron_old.dat"
|
||||
val bird = "data/bird.dat"
|
||||
val snake = "data/i.snake"
|
||||
val star = "data/star.dat"
|
||||
val strange = "data/strange.dat"
|
||||
val i18 = "data/i.18"
|
||||
val tank = "data/tank.dat"
|
||||
val dude = "data/dude.dat"
|
||||
val nazcaMonkey = "../data/nazca_monkey.dat"
|
||||
val nazcaHeron = "../data/nazca_heron_old.dat"
|
||||
val bird = "../data/bird.dat"
|
||||
val snake = "../data/i.snake"
|
||||
val star = "../data/star.dat"
|
||||
val strange = "../data/strange.dat"
|
||||
val i18 = "../data/i.18"
|
||||
val tank = "../data/tank.dat"
|
||||
val dude = "../data/dude.dat"
|
||||
val basic = "../data/basic.dat"
|
||||
|
||||
var currentModel = dude
|
||||
var doCDT = true
|
||||
@ -207,7 +208,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
}
|
||||
}
|
||||
|
||||
if(currentModel == "data/dude.dat" && drawSegs) {
|
||||
if(currentModel == "../data/dude.dat" && drawSegs) {
|
||||
g.setColor(green)
|
||||
for(i <- 0 until chestSegs.size) {
|
||||
val s = chestSegs(i)
|
||||
@ -287,6 +288,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
if(c == '7') selectModel(nazcaHeron)
|
||||
if(c == '8') selectModel(tank)
|
||||
if(c == '9') selectModel(dude)
|
||||
if(c == '0') selectModel(basic)
|
||||
|
||||
if(c == 'd') drawSegs = !drawSegs
|
||||
if(c == 'm') drawCDTMesh = !drawCDTMesh
|
||||
@ -303,33 +305,36 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
|
||||
def selectModel(model: String) {
|
||||
model match {
|
||||
case "data/nazca_monkey.dat" =>
|
||||
case "../data/nazca_monkey.dat" =>
|
||||
val clearPoint = Point(418, 282)
|
||||
loadModel(nazcaMonkey, 4.5f, Point(400, 300), 1500, clearPoint)
|
||||
case "data/bird.dat" =>
|
||||
case "../data/bird.dat" =>
|
||||
val clearPoint = Point(400, 300)
|
||||
loadModel(bird, 25f, Point(400, 300), 350, clearPoint)
|
||||
case "data/i.snake" =>
|
||||
case "../data/i.snake" =>
|
||||
val clearPoint = Point(336f, 196f)
|
||||
loadModel(snake, 10f, Point(600, 300), 10, clearPoint)
|
||||
case "data/star.dat" =>
|
||||
case "../data/star.dat" =>
|
||||
val clearPoint = Point(400, 204)
|
||||
loadModel(star, -1f, Point(0f, 0f), 10, clearPoint)
|
||||
case "data/strange.dat" =>
|
||||
case "../data/strange.dat" =>
|
||||
val clearPoint = Point(400, 268)
|
||||
loadModel(strange, -1f, Point(0f, 0f), 15, clearPoint)
|
||||
case "data/i.18" =>
|
||||
case "../data/i.18" =>
|
||||
val clearPoint = Point(510, 385)
|
||||
loadModel(i18, 20f, Point(600f, 500f), 20, clearPoint)
|
||||
case "data/nazca_heron_old.dat" =>
|
||||
case "../data/nazca_heron_old.dat" =>
|
||||
val clearPoint = Point(85, 290)
|
||||
loadModel(nazcaHeron, 4.2f, Point(400f, 300f), 1500, clearPoint)
|
||||
case "data/tank.dat" =>
|
||||
case "../data/tank.dat" =>
|
||||
val clearPoint = Point(450, 350)
|
||||
loadModel(tank, -1f, Point(100f, 0f), 10, clearPoint)
|
||||
case "data/dude.dat" =>
|
||||
case "../data/dude.dat" =>
|
||||
val clearPoint = Point(365, 427)
|
||||
loadModel(dude, -1f, Point(100f, -200f), 10, clearPoint)
|
||||
case "../data/basic.dat" =>
|
||||
val clearPoint = Point(365, 427)
|
||||
loadModel(basic, -1f, Point(400f, 300f), 10, clearPoint)
|
||||
case _ =>
|
||||
}
|
||||
currentModel = model
|
||||
@ -378,7 +383,7 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
slCDT = new CDT(pts, clearPoint)
|
||||
|
||||
// Add some holes....
|
||||
if(model == "data/dude.dat") {
|
||||
if(model == "../data/dude.dat") {
|
||||
|
||||
val headHole = Array(Point(325f,437f), Point(320f,423f), Point(329f,413f), Point(332f,423f))
|
||||
val chestHole = Array(Point(320.72342f,480f), Point(338.90617f,465.96863f),
|
||||
@ -443,8 +448,8 @@ class Poly2TriDemo extends BasicGame("Poly2Tri") {
|
||||
var xVerts = polyX.toArray
|
||||
var yVerts = polyY.toArray
|
||||
|
||||
val xv = if(currentModel != "data/strange.dat") xVerts.reverse.toArray else xVerts
|
||||
val yv = if(currentModel != "data/strange.dat") yVerts.reverse.toArray else yVerts
|
||||
val xv = if(currentModel != "../data/strange.dat") xVerts.reverse.toArray else xVerts
|
||||
val yv = if(currentModel != "../data/strange.dat") yVerts.reverse.toArray else yVerts
|
||||
|
||||
val t1 = System.nanoTime
|
||||
earClip.triangulatePolygon(xv, yv, xVerts.size, earClipResults)
|
||||
|
@ -101,10 +101,10 @@ class MonotoneMountain {
|
||||
while(p != tail) {
|
||||
val a = angle(p)
|
||||
// If the point is almost colinear with it's neighbor, remove it!
|
||||
if(a >= PI_SLOP || a <= -PI_SLOP)
|
||||
if(a >= PI_SLOP || a <= -PI_SLOP || a == 0.0)
|
||||
remove(p)
|
||||
else
|
||||
if(convex(p)) convexPoints += p
|
||||
else if(convex(p))
|
||||
convexPoints += p
|
||||
p = p.next
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,6 @@ class Triangulator(points: ArrayBuffer[Point]) {
|
||||
k = Util.msort((p1: Point, p2: Point) => p1 < p2)(s.mPoints.toList)
|
||||
|
||||
val points = s.p :: k ::: List(s.q)
|
||||
|
||||
var j = 0
|
||||
while(j < points.size) {
|
||||
mountain += points(j)
|
||||
|
Loading…
Reference in New Issue
Block a user