mirror of
https://github.com/jhasse/poly2tri.git
synced 2025-10-01 00:35:39 +02:00
seidel
This commit is contained in:
@@ -5,13 +5,10 @@ from math import pi as PI
|
||||
|
||||
from gl cimport *
|
||||
|
||||
#from triangulator import Point
|
||||
|
||||
include "triangulator.pyx"
|
||||
|
||||
cdef extern from 'math.h':
|
||||
double cos(double)
|
||||
double sin(double)
|
||||
double sqrt(double)
|
||||
|
||||
SEGMENTS = 25
|
||||
INCREMENT = 2.0 * PI / SEGMENTS
|
||||
@@ -61,11 +58,6 @@ from glfw cimport *
|
||||
|
||||
import sys
|
||||
|
||||
cdef extern from 'math.h':
|
||||
double cos(double)
|
||||
double sin(double)
|
||||
double sqrt(double)
|
||||
|
||||
# Keyboard callback wrapper
|
||||
kbd_callback_method = None
|
||||
|
||||
@@ -78,9 +70,6 @@ cdef class Game:
|
||||
title = "Poly2Tri"
|
||||
|
||||
def __init__(self, window_width, window_height):
|
||||
|
||||
points = [Point(100,100), Point(-100,100), Point(-100,-100), Point(100,-100)]
|
||||
seidel = Triangulator(points)
|
||||
|
||||
glfwInit()
|
||||
|
||||
|
@@ -43,145 +43,9 @@ cdef extern from 'math.h':
|
||||
double floor(double)
|
||||
double sqrt(double)
|
||||
|
||||
class Triangulator:
|
||||
|
||||
def __init__(self, points):
|
||||
self.polygons = []
|
||||
self.edge_list = self.init_edges(points)
|
||||
self.trapezoids = []
|
||||
self.trapezoidal_map = TrapezoidalMap()
|
||||
bounding_box = self.trapezoidal_map.bounding_box(self.edge_list)
|
||||
self.query_graph = QueryGraph(Sink(bounding_box))
|
||||
self.xmono_poly = []
|
||||
self.process()
|
||||
|
||||
def trapezoidMap(self):
|
||||
return self.trapezoidal_map.map
|
||||
class Point:
|
||||
|
||||
# Build the trapezoidal map and query graph
|
||||
def process(self):
|
||||
for e in self.edge_list:
|
||||
traps = self.query_graph.follow_edge(e)
|
||||
for t in traps:
|
||||
try:
|
||||
self.trapezoidal_map.map.remove(t)
|
||||
except:
|
||||
pass
|
||||
for t in traps:
|
||||
tlist = []
|
||||
cp = t.contains(e.p)
|
||||
cq = t.contains(e.q)
|
||||
if cp and cq:
|
||||
tlist = self.trapezoidal_map.case1(t, e)
|
||||
self.query_graph.case1(t.sink, e, tlist)
|
||||
elif cp and not cq:
|
||||
tlist = self.trapezoidal_map.case2(t, e)
|
||||
self.query_graph.case2(t.sink, e, tlist)
|
||||
elif not cp and not cq:
|
||||
tlist = self.trapezoidal_map.case3(t, e)
|
||||
self.query_graph.case3(t.sink, e, tlist)
|
||||
else:
|
||||
tlist = self.trapezoidal_map.case4(t, e)
|
||||
self.query_graph.case4(t.sink, e, tlist)
|
||||
|
||||
# Add new trapezoids to map
|
||||
for t in tlist:
|
||||
self.trapezoidal_map.map.append(t)
|
||||
|
||||
self.trapezoidal_map.clear()
|
||||
|
||||
# Mark outside trapezoids
|
||||
for t in self.trapezoidal_map.map:
|
||||
self.mark_outside(t)
|
||||
|
||||
# Collect interior trapezoids
|
||||
for t in self.trapezoidal_map.map:
|
||||
if t.inside():
|
||||
self.trapezoids.append(t)
|
||||
t.add_points()
|
||||
|
||||
self.create_mountains()
|
||||
|
||||
def mono_polies(self):
|
||||
polies = []
|
||||
for x in self.xmono_poly:
|
||||
polies.append(x.monoPoly)
|
||||
return polies
|
||||
|
||||
def create_mountains(self):
|
||||
for s in self.edge_list:
|
||||
if len(s.mpoints) > 0:
|
||||
mountain = MonotoneMountain()
|
||||
k = merge_sort(s.mpoints)
|
||||
points = [s.p] + k + [s.q]
|
||||
for p in points:
|
||||
mountain.append(p)
|
||||
mountain.process()
|
||||
for t in mountain.triangles:
|
||||
self.polygons.append(t)
|
||||
self.xmono_poly.append(mountain)
|
||||
|
||||
def mark_outside(self, t):
|
||||
if t.top is self.bounding_box.top or t.bottom is self.bounding_box.bottom:
|
||||
t.trimNeighbors()
|
||||
|
||||
def init_edges(self, points):
|
||||
edges = []
|
||||
for i in range(len(points)-1):
|
||||
edges.append(Edge(points[i], points[i+1]))
|
||||
edges.append(Edge(points[0], points[-1]))
|
||||
return self.order_edges(edges)
|
||||
|
||||
def order_edges(self, edges):
|
||||
segs = []
|
||||
for s in edges:
|
||||
p = self.shearTransform(s.p)
|
||||
q = self.shearTransform(s.q)
|
||||
if p.x > q.x: segs.append(Edge(q, p))
|
||||
elif p.x < q.x: segs.append(Edge(p, q))
|
||||
shuffle(segs)
|
||||
return segs
|
||||
|
||||
def shearTransform(self, point):
|
||||
return Point(point.x + 1e-4 * point.y, point.y)
|
||||
|
||||
cdef list merge_sort(list l):
|
||||
cdef list lleft, lright
|
||||
cdef int p1, p2, p
|
||||
if len(l)>1 :
|
||||
lleft = merge_sort(l[:len(l)/2])
|
||||
lright = merge_sort(l[len(l)/2:])
|
||||
p1, p2, p = 0, 0, 0
|
||||
while p1<len(lleft) and p2<len(lright):
|
||||
if lleft[p1].x < lright[p2].x:
|
||||
l[p]=lleft[p1]
|
||||
p+=1
|
||||
p1+=1
|
||||
else:
|
||||
l[p]=lright[p2]
|
||||
p+=1
|
||||
p2+=1
|
||||
if p1<len(lleft):l[p:]=lleft[p1:]
|
||||
elif p2<len(lright):l[p:]=lright[p2:]
|
||||
else : print "internal error"
|
||||
return l
|
||||
|
||||
cdef class Point:
|
||||
|
||||
cdef float x, y
|
||||
|
||||
next = None
|
||||
prev = None
|
||||
edge = None
|
||||
edges = []
|
||||
|
||||
property x:
|
||||
def __get__(self): return self.x
|
||||
|
||||
property y:
|
||||
def __get__(self): return self.y
|
||||
|
||||
def __init__(self, float x, float y):
|
||||
def __cinit__(self, float x, float y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
@@ -203,10 +67,10 @@ cdef class Point:
|
||||
def __div__(self, float a):
|
||||
return Point(self.x / a, self.y / a)
|
||||
|
||||
def cross(self, Point p):
|
||||
def cross(self, p):
|
||||
return self.x * p.y - self.y * p.x
|
||||
|
||||
def dot(self, Point p):
|
||||
def dot(self, p):
|
||||
return self.x * p.x + self.y * p.y
|
||||
|
||||
def length(self):
|
||||
@@ -215,38 +79,22 @@ cdef class Point:
|
||||
def normalize(self):
|
||||
return self / self.length()
|
||||
|
||||
def less(self, Point p):
|
||||
def less(self, p):
|
||||
return self.x < p.x
|
||||
|
||||
'''
|
||||
# Sort along y axis
|
||||
def greater(self, p):
|
||||
if y < p.y:
|
||||
return True
|
||||
elif y > p.y:
|
||||
return False
|
||||
else:
|
||||
if x < p.x:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
'''
|
||||
|
||||
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)
|
||||
|
||||
cdef class Edge:
|
||||
|
||||
cdef Point p, q
|
||||
cdef bool above, below
|
||||
cdef float slope, b
|
||||
cdef class Edge:
|
||||
|
||||
cdef object above, below
|
||||
cdef float slope, b
|
||||
mpoints = []
|
||||
|
||||
def __init__(self, Point p, Point q):
|
||||
def __cinit__(self, p, q):
|
||||
self.p = p
|
||||
self.q = q
|
||||
self.slope = (q.y - p.y)/(q.x - p.x)
|
||||
@@ -264,12 +112,12 @@ cdef class Edge:
|
||||
property below:
|
||||
def __get__(self): return self.below
|
||||
|
||||
cdef bool is_above(self, Point point):
|
||||
cdef bool is_above(self, point):
|
||||
return (floor(point.y) < floor(self.slope * point.x + self.b))
|
||||
cdef bool is_below(self, Point point):
|
||||
cdef bool is_below(self, point):
|
||||
return (floor(point.y) > floor(self.slope * point.x + self.b))
|
||||
|
||||
cdef float intersect(self, Point c, Point d):
|
||||
cdef float intersect(self, c, d):
|
||||
cdef float a1, a2, a3, a4, t
|
||||
cdef Point a, b
|
||||
a = self.p
|
||||
@@ -284,24 +132,18 @@ cdef class Edge:
|
||||
return a + ((b - a) * t)
|
||||
return 0.0
|
||||
|
||||
cdef float signed_area(self, Point a, Point b, Point c):
|
||||
cdef float signed_area(self, a, b, c):
|
||||
return (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x)
|
||||
|
||||
cdef Point line_intersect(Edge e, float x):
|
||||
cdef float y = e.slope * x + e.b
|
||||
return Point(x, y)
|
||||
|
||||
cdef class Trapezoid:
|
||||
|
||||
cdef:
|
||||
Point left_point, right_point
|
||||
Edge top, bottom
|
||||
Trapezoid upper_left, lower_left
|
||||
Trapezoid upper_right, lower_right
|
||||
bool inside
|
||||
object sink
|
||||
|
||||
cdef Edge top, bottom
|
||||
cdef Trapezoid upper_left, lower_left
|
||||
cdef Trapezoid upper_right, lower_right
|
||||
cdef object sink
|
||||
cdef bool inside
|
||||
|
||||
def __init__(self, Point left_point, Point right_point, Edge top, Edge bottom):
|
||||
def __cinit__(self, left_point, right_point, Edge top, Edge bottom):
|
||||
self.left_point = left_point
|
||||
self.right_point = right_point
|
||||
self.top = top
|
||||
@@ -313,6 +155,9 @@ cdef class Trapezoid:
|
||||
self.inside = True
|
||||
self.sink = None
|
||||
|
||||
property inside:
|
||||
def __get__(self): return self.inside
|
||||
|
||||
property top:
|
||||
def __get__(self): return self.top
|
||||
|
||||
@@ -321,9 +166,11 @@ cdef class Trapezoid:
|
||||
|
||||
property left_point:
|
||||
def __get__(self): return self.left_point
|
||||
|
||||
def __set__(self, lp): self.left_point = lp
|
||||
|
||||
property right_point:
|
||||
def __get__(self): return self.right_point
|
||||
def __set__(self, rp): self.right_point = rp
|
||||
|
||||
property sink:
|
||||
def __get__(self): return self.sink
|
||||
@@ -375,7 +222,7 @@ cdef class Trapezoid:
|
||||
if self.upper_right != None: self.upper_right.trim_neighbors()
|
||||
if self.lower_right != None: self.lower_right.trim_neighbors()
|
||||
|
||||
def contains(self, Point point):
|
||||
def contains(self, point):
|
||||
return (point.x > self.left_point.x and point.x < self.right_point.x and
|
||||
self.top.is_above(point) and self.bottom.is_below(point))
|
||||
|
||||
@@ -397,6 +244,140 @@ cdef class Trapezoid:
|
||||
if self.right_point != self.top.q:
|
||||
self.top.mpoints.append(self.right_point.clone)
|
||||
|
||||
cdef Point line_intersect(Edge e, float x):
|
||||
cdef float y = e.slope * x + e.b
|
||||
return Point(x, y)
|
||||
|
||||
class Triangulator:
|
||||
|
||||
def __init__(self, poly_line):
|
||||
self.polygons = []
|
||||
self.edge_list = self.init_edges(poly_line)
|
||||
self.trapezoids = []
|
||||
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 trapezoidMap(self):
|
||||
return self.trapezoidal_map.map
|
||||
|
||||
# Build the trapezoidal map and query graph
|
||||
def process(self):
|
||||
|
||||
for e in self.edge_list:
|
||||
traps = self.query_graph.follow_edge(e)
|
||||
for t in traps:
|
||||
try:
|
||||
self.trapezoidal_map.map.remove(t)
|
||||
except:
|
||||
pass
|
||||
for t in traps:
|
||||
tlist = []
|
||||
cp = t.contains(e.p)
|
||||
cq = t.contains(e.q)
|
||||
if cp and cq:
|
||||
tlist = self.trapezoidal_map.case1(t, e)
|
||||
self.query_graph.case1(t.sink, e, tlist)
|
||||
elif cp and not cq:
|
||||
tlist = self.trapezoidal_map.case2(t, e)
|
||||
self.query_graph.case2(t.sink, e, tlist)
|
||||
elif not cp and not cq:
|
||||
tlist = self.trapezoidal_map.case3(t, e)
|
||||
self.query_graph.case3(t.sink, e, tlist)
|
||||
else:
|
||||
tlist = self.trapezoidal_map.case4(t, e)
|
||||
self.query_graph.case4(t.sink, e, tlist)
|
||||
# Add new trapezoids to map
|
||||
for t in tlist:
|
||||
self.trapezoidal_map.map.append(t)
|
||||
self.trapezoidal_map.clear()
|
||||
|
||||
# Mark outside trapezoids
|
||||
for t in self.trapezoidal_map.map:
|
||||
self.mark_outside(t)
|
||||
|
||||
# Collect interior trapezoids
|
||||
for t in self.trapezoidal_map.map:
|
||||
if t.inside:
|
||||
self.trapezoids.append(t)
|
||||
t.add_points()
|
||||
|
||||
self.create_mountains()
|
||||
|
||||
def mono_polies(self):
|
||||
polies = []
|
||||
for x in self.xmono_poly:
|
||||
polies.append(x.monoPoly)
|
||||
return polies
|
||||
|
||||
def create_mountains(self):
|
||||
for s in self.edge_list:
|
||||
if len(s.mpoints) > 0:
|
||||
mountain = MonotoneMountain()
|
||||
print s.mpoints
|
||||
k = merge_sort(s.mpoints)
|
||||
points = [s.p] + k + [s.q]
|
||||
for p in points:
|
||||
mountain.append(p)
|
||||
mountain.process()
|
||||
for t in mountain.triangles:
|
||||
self.polygons.append(t)
|
||||
self.xmono_poly.append(mountain)
|
||||
|
||||
def mark_outside(self, t):
|
||||
if t.top is self.bounding_box.top or t.bottom is self.bounding_box.bottom:
|
||||
t.trim_neighbors()
|
||||
|
||||
def init_edges(self, points):
|
||||
edges = []
|
||||
for i in range(len(points)-1):
|
||||
p = Point(points[i][0], points[i][1])
|
||||
q = Point(points[i+1][0], points[i+1][1])
|
||||
edges.append(Edge(p, q))
|
||||
p = Point(points[0][0], points[0][1])
|
||||
q = Point(points[-1][0], points[-1][1])
|
||||
edges.append(Edge(p, q))
|
||||
return self.order_edges(edges)
|
||||
|
||||
def order_edges(self, edges):
|
||||
segs = []
|
||||
for s in edges:
|
||||
p = self.shearTransform(s.p)
|
||||
q = self.shearTransform(s.q)
|
||||
if p.x > q.x:
|
||||
segs.append(Edge(q, p))
|
||||
elif p.x < q.x:
|
||||
segs.append(Edge(p, q))
|
||||
shuffle(segs)
|
||||
return segs
|
||||
|
||||
def shearTransform(self, point):
|
||||
return Point(point.x + 1e-4 * point.y, point.y)
|
||||
|
||||
cdef list merge_sort(l):
|
||||
cdef list lleft, lright
|
||||
cdef int p1, p2, p
|
||||
if len(l)>1 :
|
||||
lleft = merge_sort(l[:len(l)/2])
|
||||
lright = merge_sort(l[len(l)/2:])
|
||||
p1, p2, p = 0, 0, 0
|
||||
while p1<len(lleft) and p2<len(lright):
|
||||
if lleft[p1].x < lright[p2].x:
|
||||
l[p]=lleft[p1]
|
||||
p+=1
|
||||
p1+=1
|
||||
else:
|
||||
l[p]=lright[p2]
|
||||
p+=1
|
||||
p2+=1
|
||||
if p1<len(lleft):l[p:]=lleft[p1:]
|
||||
elif p2<len(lright):l[p:]=lright[p2:]
|
||||
else : print "internal error"
|
||||
return l
|
||||
|
||||
class TrapezoidalMap:
|
||||
|
||||
map = []
|
||||
@@ -408,7 +389,7 @@ class TrapezoidalMap:
|
||||
self.bcross = None
|
||||
self.tcross = None
|
||||
|
||||
def case1(self, t, e):
|
||||
def case1(self, Trapezoid t, Edge e):
|
||||
trapezoids = []
|
||||
trapezoids.append(Trapezoid(t.left_point, e.p, t.top, t.bottom))
|
||||
trapezoids.append(Trapezoid(e.p, e.q, t.top, e))
|
||||
@@ -420,7 +401,7 @@ class TrapezoidalMap:
|
||||
trapezoids[3].update_right(t.upper_right, t.lower_right)
|
||||
return trapezoids
|
||||
|
||||
def case2(self, t, e):
|
||||
def case2(self, Trapezoid t, Edge 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))
|
||||
@@ -435,7 +416,7 @@ class TrapezoidalMap:
|
||||
e.below = trapezoids[2]
|
||||
return trapezoids
|
||||
|
||||
def case3(self, t, e):
|
||||
def case3(self, Trapezoid t, Edge 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 = []
|
||||
@@ -459,7 +440,7 @@ class TrapezoidalMap:
|
||||
e.below = trapezoids[1]
|
||||
return trapezoids
|
||||
|
||||
def case4(self, t, e):
|
||||
def case4(self, Trapezoid t, Edge e):
|
||||
lp = e.p if e.p.x == t.left_point.x else t.left_point
|
||||
trapezoids = []
|
||||
if self.tcross is t.top:
|
||||
@@ -498,61 +479,81 @@ class TrapezoidalMap:
|
||||
right = top.q
|
||||
return Trapezoid(left, right, top, bottom)
|
||||
|
||||
class Node:
|
||||
cdef class Node:
|
||||
|
||||
parent_list = []
|
||||
cdef Node left, right
|
||||
cdef object parent_list
|
||||
|
||||
def __init__(self, left, right):
|
||||
def __init__(self, Node left, Node right):
|
||||
self.parent_list = []
|
||||
self.left = left
|
||||
self.right = right
|
||||
if left != None: left.parent_list.append(self)
|
||||
if right != None: right.parent_list.append(self)
|
||||
|
||||
def replace(self, node):
|
||||
if left != None:
|
||||
left.parent_list.append(self)
|
||||
if right != None:
|
||||
right.parent_list.append(self)
|
||||
|
||||
property left:
|
||||
def __get__(self): return self.left
|
||||
def __set__(self, Node left): self.left = left
|
||||
|
||||
property right:
|
||||
def __get__(self): return self.right
|
||||
def __set__(self, Node right): self.right = right
|
||||
|
||||
property parent_list:
|
||||
def __get__(self): return self.parent_list
|
||||
|
||||
def replace(self, Node node):
|
||||
for parent in node.parent_list:
|
||||
if parent.left is node:
|
||||
parent.left = self
|
||||
else:
|
||||
parent.right = self
|
||||
self.parent_list.append(parent)
|
||||
|
||||
class Sink(Node):
|
||||
|
||||
def __new__(cls, trapezoid):
|
||||
if trapezoid.sink != None:
|
||||
return trapezoid.sink
|
||||
return Sink(trapezoid)
|
||||
|
||||
self.parent_list += node.parent_list
|
||||
|
||||
cdef class Sink(Node):
|
||||
|
||||
cdef Trapezoid trapezoid
|
||||
|
||||
def __init__(self, trapezoid):
|
||||
self.trapezoid = trapezoid
|
||||
Node.__init__(self, None, None)
|
||||
super(Sink, self).__init__(None, None)
|
||||
trapezoid.sink = self
|
||||
|
||||
property trapezoid:
|
||||
def __get__(self): return self.trapezoid
|
||||
|
||||
def locate(self, e):
|
||||
return self
|
||||
|
||||
class XNode(Node):
|
||||
|
||||
def __init__(self, point, lchild, rchild):
|
||||
Node.__init__(self, lchild, rchild)
|
||||
self.point = point
|
||||
self.lchild = lchild
|
||||
self.rchild = rchild
|
||||
cdef Sink isink(Trapezoid trapezoid):
|
||||
if trapezoid.sink != None:
|
||||
return trapezoid.sink
|
||||
return Sink(trapezoid)
|
||||
|
||||
def locate(self, e):
|
||||
cdef class XNode(Node):
|
||||
|
||||
cdef Point point
|
||||
|
||||
def __init__(self, Point point, Node lchild, Node rchild):
|
||||
super(XNode, self).__init__(lchild, rchild)
|
||||
self.point = point
|
||||
|
||||
def locate(self, Edge e):
|
||||
if e.p.x >= self.point.x:
|
||||
return self.right.locate(e)
|
||||
return self.left.locate(e)
|
||||
|
||||
class YNode(Node):
|
||||
cdef class YNode(Node):
|
||||
|
||||
def __init__(self, edge, lchild, rchild):
|
||||
Node.__init__(self, lchild, rchild)
|
||||
cdef Edge edge
|
||||
|
||||
def __init__(self, Edge edge, Node lchild, Node rchild):
|
||||
super(YNode, self).__init__(lchild, rchild)
|
||||
self.edge = edge
|
||||
self.lchild = lchild
|
||||
self.rchild = rchild
|
||||
|
||||
def locate(self, e):
|
||||
def locate(self, Edge e):
|
||||
if self.edge.is_above(e.p):
|
||||
return self.right.locate(e)
|
||||
elif self.edge.is_below(e.p):
|
||||
@@ -560,53 +561,54 @@ class YNode(Node):
|
||||
else:
|
||||
if e.slope < self.edge.slope:
|
||||
return self.right.locate(e)
|
||||
return self.left.locate(e)
|
||||
else:
|
||||
return self.left.locate(e)
|
||||
|
||||
class QueryGraph:
|
||||
cdef class QueryGraph:
|
||||
|
||||
head = None
|
||||
cdef Node head
|
||||
|
||||
def __init__(self, head):
|
||||
def __init__(self, Node head):
|
||||
self.head = head
|
||||
|
||||
def locate(self, e):
|
||||
def locate(self, Edge e):
|
||||
return self.head.locate(e).trapezoid
|
||||
|
||||
def follow_edge(self, e):
|
||||
def follow_edge(self, Edge e):
|
||||
trapezoids = [self.locate(e)]
|
||||
j = 0
|
||||
cdef int j = 0
|
||||
while(e.q.x > trapezoids[j].right_point.x):
|
||||
if e > trapezoids[j].right_point:
|
||||
if e.is_above(trapezoids[j].right_point):
|
||||
trapezoids.append(trapezoids[j].upper_right)
|
||||
else:
|
||||
trapezoids .append(trapezoids[j].lower_right)
|
||||
trapezoids.append(trapezoids[j].lower_right)
|
||||
j += 1
|
||||
return trapezoids
|
||||
|
||||
def replace(self, sink, node):
|
||||
def replace(self, Sink sink, Node node):
|
||||
if not sink.parent_list:
|
||||
self.head = node
|
||||
else:
|
||||
node.replace(sink)
|
||||
|
||||
def case1(self, sink, e, tlist):
|
||||
yNode = YNode(e, Sink(tlist[1]), Sink(tlist[2]))
|
||||
qNode = XNode(e.q, yNode, Sink(tlist[3]))
|
||||
pNode = XNode(e.p, Sink(tlist[0]), qNode)
|
||||
def case1(self, Sink sink, Edge e, tlist):
|
||||
cdef Node yNode = YNode(e, isink(tlist[1]), isink(tlist[2]))
|
||||
cdef Node qNode = XNode(e.q, yNode, isink(tlist[3]))
|
||||
cdef Node pNode = XNode(e.p, isink(tlist[0]), qNode)
|
||||
self.replace(sink, pNode)
|
||||
|
||||
def case2(self, sink, e, tlist):
|
||||
yNode = YNode(e, Sink(tlist[1]), Sink(tlist[2]))
|
||||
pNode = XNode(e.p, Sink(tlist[0]), yNode)
|
||||
def case2(self, Sink sink, Edge e, tlist):
|
||||
yNode = YNode(e, isink(tlist[1]), isink(tlist[2]))
|
||||
pNode = XNode(e.p, isink(tlist[0]), yNode)
|
||||
self.replace(sink, pNode)
|
||||
|
||||
def case3(self, sink, e, tlist):
|
||||
yNode = YNode(e, Sink(tlist[0]), Sink(tlist[1]))
|
||||
def case3(self, Sink sink, Edge e, tlist):
|
||||
yNode = YNode(e, isink(tlist[0]), isink(tlist[1]))
|
||||
self.replace(sink, yNode)
|
||||
|
||||
def case4(self, sink, e, tlist):
|
||||
yNode = YNode(e, Sink(tlist[0]), Sink(tlist[1]))
|
||||
qNode = XNode(e.q, yNode, Sink(tlist[2]))
|
||||
def case4(self, Sink sink, Edge e, tlist):
|
||||
yNode = YNode(e, isink(tlist[0]), isink(tlist[1]))
|
||||
qNode = XNode(e.q, yNode, isink(tlist[2]))
|
||||
self.replace(sink, qNode)
|
||||
|
||||
cdef float PI_SLOP = 3.1
|
||||
@@ -624,7 +626,8 @@ cdef class MonotoneMountain:
|
||||
|
||||
def __init__(self):
|
||||
self.size = 0
|
||||
self.tail, self.head = None
|
||||
self.tail = None
|
||||
self.head = None
|
||||
self.positive = False
|
||||
self.convex_points = []
|
||||
self.mono_poly = []
|
||||
|
Reference in New Issue
Block a user