mirror of
https://github.com/jhasse/poly2tri.git
synced 2025-02-18 12:23:31 +01:00
happy bug hunting
This commit is contained in:
parent
76a60ae144
commit
1e660e965e
@ -79,9 +79,8 @@ cdef class Game:
|
|||||||
|
|
||||||
def __init__(self, window_width, window_height):
|
def __init__(self, window_width, window_height):
|
||||||
|
|
||||||
p1 = Point(12, 10)
|
points = [Point(100,100), Point(-100,100), Point(-100,-100), Point(100,-100)]
|
||||||
p2 = Point(50, 47)
|
seidel = Triangulator(points)
|
||||||
print p1.cross(p2)
|
|
||||||
|
|
||||||
glfwInit()
|
glfwInit()
|
||||||
|
|
||||||
|
@ -50,8 +50,8 @@ class Triangulator:
|
|||||||
self.edge_list = self.init_edges(points)
|
self.edge_list = self.init_edges(points)
|
||||||
self.trapezoids = []
|
self.trapezoids = []
|
||||||
self.trapezoidal_map = TrapezoidalMap()
|
self.trapezoidal_map = TrapezoidalMap()
|
||||||
boundingBox = self.trapezoidal_map.boundingBox(self.edge_list)
|
bounding_box = self.trapezoidal_map.bounding_box(self.edge_list)
|
||||||
self.query_graph = QueryGraph(Sink(boundingBox))
|
self.query_graph = QueryGraph(Sink(bounding_box))
|
||||||
self.xmono_poly = []
|
self.xmono_poly = []
|
||||||
self.process()
|
self.process()
|
||||||
|
|
||||||
@ -61,9 +61,12 @@ class Triangulator:
|
|||||||
# Build the trapezoidal map and query graph
|
# Build the trapezoidal map and query graph
|
||||||
def process(self):
|
def process(self):
|
||||||
for e in self.edge_list:
|
for e in self.edge_list:
|
||||||
traps = self.query_graph.followSegment(e)
|
traps = self.query_graph.follow_edge(e)
|
||||||
for t in traps:
|
for t in traps:
|
||||||
|
try:
|
||||||
self.trapezoidal_map.map.remove(t)
|
self.trapezoidal_map.map.remove(t)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
for t in traps:
|
for t in traps:
|
||||||
tlist = []
|
tlist = []
|
||||||
cp = t.contains(e.p)
|
cp = t.contains(e.p)
|
||||||
@ -119,7 +122,7 @@ class Triangulator:
|
|||||||
self.xmono_poly.append(mountain)
|
self.xmono_poly.append(mountain)
|
||||||
|
|
||||||
def mark_outside(self, t):
|
def mark_outside(self, t):
|
||||||
if t.top is self.boundingBox.top or t.bottom is self.boundingBox.bottom:
|
if t.top is self.bounding_box.top or t.bottom is self.bounding_box.bottom:
|
||||||
t.trimNeighbors()
|
t.trimNeighbors()
|
||||||
|
|
||||||
def init_edges(self, points):
|
def init_edges(self, points):
|
||||||
@ -291,17 +294,16 @@ cdef Point line_intersect(Edge e, float x):
|
|||||||
cdef class Trapezoid:
|
cdef class Trapezoid:
|
||||||
|
|
||||||
cdef:
|
cdef:
|
||||||
Point lpoint, rpoint
|
Point left_point, right_point
|
||||||
Edge top, bottom
|
Edge top, bottom
|
||||||
Trapezoid upper_left, lower_left
|
Trapezoid upper_left, lower_left
|
||||||
Trapezoid upper_right, lower_right
|
Trapezoid upper_right, lower_right
|
||||||
bool inside
|
bool inside
|
||||||
|
object sink
|
||||||
|
|
||||||
sink = None
|
def __init__(self, Point left_point, Point right_point, Edge top, Edge bottom):
|
||||||
|
self.left_point = left_point
|
||||||
def __init__(self, Point lpoint, Point rpoint, Edge top, Edge bottom):
|
self.right_point = right_point
|
||||||
self.lpoint = lpoint
|
|
||||||
self.rpoint = rpoint
|
|
||||||
self.top = top
|
self.top = top
|
||||||
self.bottom = bottom
|
self.bottom = bottom
|
||||||
self.upper_left = None
|
self.upper_left = None
|
||||||
@ -309,6 +311,23 @@ cdef class Trapezoid:
|
|||||||
self.lower_left = None
|
self.lower_left = None
|
||||||
self.lower_right = None
|
self.lower_right = None
|
||||||
self.inside = True
|
self.inside = True
|
||||||
|
self.sink = None
|
||||||
|
|
||||||
|
property top:
|
||||||
|
def __get__(self): return self.top
|
||||||
|
|
||||||
|
property bottom:
|
||||||
|
def __get__(self): return self.bottom
|
||||||
|
|
||||||
|
property left_point:
|
||||||
|
def __get__(self): return self.left_point
|
||||||
|
|
||||||
|
property right_point:
|
||||||
|
def __get__(self): return self.right_point
|
||||||
|
|
||||||
|
property sink:
|
||||||
|
def __get__(self): return self.sink
|
||||||
|
def __set__(self, object s): self.sink = s
|
||||||
|
|
||||||
property upper_left:
|
property upper_left:
|
||||||
def __get__(self): return self.upper_left
|
def __get__(self): return self.upper_left
|
||||||
@ -357,30 +376,30 @@ cdef class Trapezoid:
|
|||||||
if self.lower_right != None: self.lower_right.trim_neighbors()
|
if self.lower_right != None: self.lower_right.trim_neighbors()
|
||||||
|
|
||||||
def contains(self, Point point):
|
def contains(self, Point point):
|
||||||
return (point.x > self.lpoint.x and point.x < self.rpoint.x and
|
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))
|
self.top.is_above(point) and self.bottom.is_below(point))
|
||||||
|
|
||||||
def vertices(self):
|
def vertices(self):
|
||||||
cdef list verts = []
|
cdef list verts = []
|
||||||
verts.append(line_intersect(self.top, self.lpoint.x))
|
verts.append(line_intersect(self.top, self.left_point.x))
|
||||||
verts.append(line_intersect(self.bottom, self.lpoint.x))
|
verts.append(line_intersect(self.bottom, self.left_point.x))
|
||||||
verts.append(line_intersect(self.bottom, self.rpoint.x))
|
verts.append(line_intersect(self.bottom, self.right_point.x))
|
||||||
verts.append(line_intersect(self.top, self.rpoint.x))
|
verts.append(line_intersect(self.top, self.right_point.x))
|
||||||
return verts
|
return verts
|
||||||
|
|
||||||
def add_points(self):
|
def add_points(self):
|
||||||
if self.lpoint != self.bottom.p:
|
if self.left_point != self.bottom.p:
|
||||||
self.bottom.mpoints.append(self.lpoint.clone)
|
self.bottom.mpoints.append(self.left_point.clone)
|
||||||
if self.rpoint != self.bottom.q:
|
if self.right_point != self.bottom.q:
|
||||||
self.bottom.mpoints.append(self.rpoint.clone)
|
self.bottom.mpoints.append(self.right_point.clone)
|
||||||
if self.lpoint != self.top.p:
|
if self.left_point != self.top.p:
|
||||||
self.top.mpoints.append(self.lpoint.clone)
|
self.top.mpoints.append(self.left_point.clone)
|
||||||
if self.rpoint != self.top.q:
|
if self.right_point != self.top.q:
|
||||||
self.top.mpoints.append(self.rpoint.clone)
|
self.top.mpoints.append(self.right_point.clone)
|
||||||
|
|
||||||
class TrapezoidalMap:
|
class TrapezoidalMap:
|
||||||
|
|
||||||
map = {}
|
map = []
|
||||||
margin = 50
|
margin = 50
|
||||||
bcross = None
|
bcross = None
|
||||||
tcross = None
|
tcross = None
|
||||||
@ -390,11 +409,11 @@ class TrapezoidalMap:
|
|||||||
self.tcross = None
|
self.tcross = None
|
||||||
|
|
||||||
def case1(self, t, e):
|
def case1(self, t, e):
|
||||||
trapezoids = [None, None, None, None]
|
trapezoids = []
|
||||||
trapezoids.append(Trapezoid(t.lpoint, e.p, t.top, t.bottom))
|
trapezoids.append(Trapezoid(t.left_point, e.p, t.top, t.bottom))
|
||||||
trapezoids.append(Trapezoid(e.p, e.q, t.top, e))
|
trapezoids.append(Trapezoid(e.p, e.q, t.top, e))
|
||||||
trapezoids.append(Trapezoid(e.p, e.q, e, t.bottom))
|
trapezoids.append(Trapezoid(e.p, e.q, e, t.bottom))
|
||||||
trapezoids.append(Trapezoid(e.q, t.rpoint, t.top, t.bottom))
|
trapezoids.append(Trapezoid(e.q, t.right_point, t.top, t.bottom))
|
||||||
trapezoids[0].update_left(t.upper_left, t.lower_left)
|
trapezoids[0].update_left(t.upper_left, t.lower_left)
|
||||||
trapezoids[1].update_left_right(trapezoids[0], None, trapezoids[3], None)
|
trapezoids[1].update_left_right(trapezoids[0], None, trapezoids[3], None)
|
||||||
trapezoids[2].update_left_right(None, trapezoids[0], None, trapezoids[3])
|
trapezoids[2].update_left_right(None, trapezoids[0], None, trapezoids[3])
|
||||||
@ -402,9 +421,9 @@ class TrapezoidalMap:
|
|||||||
return trapezoids
|
return trapezoids
|
||||||
|
|
||||||
def case2(self, t, e):
|
def case2(self, t, e):
|
||||||
rp = e.q if e.q.x == t.rpoint.x else t.rpoint
|
rp = e.q if e.q.x == t.right_point.x else t.right_point
|
||||||
trapezoids = [None, None, None]
|
trapezoids = []
|
||||||
trapezoids.append(Trapezoid(t.lpoint, e.p, t.top, t.bottom))
|
trapezoids.append(Trapezoid(t.left_point, e.p, t.top, t.bottom))
|
||||||
trapezoids.append(Trapezoid(e.p, rp, t.top, e))
|
trapezoids.append(Trapezoid(e.p, rp, t.top, e))
|
||||||
trapezoids.append(Trapezoid(e.p, rp, e, t.bottom))
|
trapezoids.append(Trapezoid(e.p, rp, e, t.bottom))
|
||||||
trapezoids[0].update_left(t.upper_left, t.lower_left)
|
trapezoids[0].update_left(t.upper_left, t.lower_left)
|
||||||
@ -417,22 +436,22 @@ class TrapezoidalMap:
|
|||||||
return trapezoids
|
return trapezoids
|
||||||
|
|
||||||
def case3(self, t, e):
|
def case3(self, t, e):
|
||||||
lp = e.p if e.p.x == t.lpoint.x else t.lpoint
|
lp = e.p if e.p.x == t.left_point.x else t.left_point
|
||||||
rp = e.q if e.q.x == t.rpoint.x else t.rpoint
|
rp = e.q if e.q.x == t.right_point.x else t.right_point
|
||||||
trapezoids = [None, None]
|
trapezoids = []
|
||||||
if self.tcross is t.top:
|
if self.tcross is t.top:
|
||||||
trapezoids[0] = t.upper_left
|
trapezoids.append(t.upper_left)
|
||||||
trapezoids[0].update_right(t.upper_right, None)
|
trapezoids[0].update_right(t.upper_right, None)
|
||||||
trapezoids[0].rpoint = rp
|
trapezoids[0].right_point = rp
|
||||||
else:
|
else:
|
||||||
trapezoids[0] = Trapezoid(lp, rp, t.top, e)
|
trapezoids.append(Trapezoid(lp, rp, t.top, e))
|
||||||
trapezoids[0].update_left_right(t.upper_left, e.above, t.upper_right, None)
|
trapezoids[0].update_left_right(t.upper_left, e.above, t.upper_right, None)
|
||||||
if self.bcross is t.bottom:
|
if self.bcross is t.bottom:
|
||||||
trapezoids[1] = t.lower_left
|
trapezoids.append(t.lower_left)
|
||||||
trapezoids[1].update_right(None, t.lower_right)
|
trapezoids[1].update_right(None, t.lower_right)
|
||||||
trapezoids[1].rpoint = rp
|
trapezoids[1].right_point = rp
|
||||||
else:
|
else:
|
||||||
trapezoids[1] = Trapezoid(lp, rp, e, t.bottom)
|
trapezoids.append(Trapezoid(lp, rp, e, t.bottom))
|
||||||
trapezoids[1].update_left_right(e.below, t.lower_left, None, t.lower_right)
|
trapezoids[1].update_left_right(e.below, t.lower_left, None, t.lower_right)
|
||||||
self.bcross = t.bottom
|
self.bcross = t.bottom
|
||||||
self.tcross = t.top
|
self.tcross = t.top
|
||||||
@ -441,21 +460,21 @@ class TrapezoidalMap:
|
|||||||
return trapezoids
|
return trapezoids
|
||||||
|
|
||||||
def case4(self, t, e):
|
def case4(self, t, e):
|
||||||
lp = e.p if e.p.x == t.lpoint.x else t.lpoint
|
lp = e.p if e.p.x == t.left_point.x else t.left_point
|
||||||
trapezoids = [None, None, None]
|
trapezoids = []
|
||||||
if self.tcross is t.top:
|
if self.tcross is t.top:
|
||||||
trapezoids[0] = t.upper_left
|
trapezoids.append(t.upper_left)
|
||||||
trapezoids[0].rpoint = e.q
|
trapezoids[0].right_point = e.q
|
||||||
else:
|
else:
|
||||||
trapezoids[0] = Trapezoid(lp, e.q, t.top, e)
|
trapezoids.append(Trapezoid(lp, e.q, t.top, e))
|
||||||
trapezoids[0].update_left(t.upper_left, e.above)
|
trapezoids[0].update_left(t.upper_left, e.above)
|
||||||
if self.bcross is t.bottom:
|
if self.bcross is t.bottom:
|
||||||
trapezoids[1] = t.lower_left
|
trapezoids.append(t.lower_left)
|
||||||
trapezoids[1].rpoint = e.q
|
trapezoids[1].right_point = e.q
|
||||||
else:
|
else:
|
||||||
trapezoids[1] = Trapezoid(lp, e.q, e, t.bottom)
|
trapezoids.append(Trapezoid(lp, e.q, e, t.bottom))
|
||||||
trapezoids[1].update_left(e.below, t.lower_left)
|
trapezoids[1].update_left(e.below, t.lower_left)
|
||||||
trapezoids[2] = Trapezoid(e.q, t.rpoint, t.top, t.bottom)
|
trapezoids.append(Trapezoid(e.q, t.right_point, t.top, t.bottom))
|
||||||
trapezoids[2].update_left_right(trapezoids[0], trapezoids[1], t.upper_right, t.lower_right)
|
trapezoids[2].update_left_right(trapezoids[0], trapezoids[1], t.upper_right, t.lower_right)
|
||||||
|
|
||||||
return trapezoids
|
return trapezoids
|
||||||
@ -486,22 +505,26 @@ class Node:
|
|||||||
def __init__(self, left, right):
|
def __init__(self, left, right):
|
||||||
self.left = left
|
self.left = left
|
||||||
self.right = right
|
self.right = right
|
||||||
if left is not None: left.parent_list.append(self)
|
if left != None: left.parent_list.append(self)
|
||||||
if right is not None: right.parent_list.append(self)
|
if right != None: right.parent_list.append(self)
|
||||||
|
|
||||||
def replace(self, node):
|
def replace(self, node):
|
||||||
for parent in node.parent_list:
|
for parent in node.parent_list:
|
||||||
if parent.left is node: parent.left = self
|
if parent.left is node:
|
||||||
else: parent.right = self
|
parent.left = self
|
||||||
|
else:
|
||||||
|
parent.right = self
|
||||||
self.parent_list.append(parent)
|
self.parent_list.append(parent)
|
||||||
|
|
||||||
class Sink(Node):
|
class Sink(Node):
|
||||||
|
|
||||||
def __new__(cls, trapezoid):
|
def __new__(cls, trapezoid):
|
||||||
if trapezoid.sink is not None: return trapezoid.sink
|
if trapezoid.sink != None:
|
||||||
else: return Sink(trapezoid)
|
return trapezoid.sink
|
||||||
|
return Sink(trapezoid)
|
||||||
|
|
||||||
def __init__(self, trapezoid):
|
def __init__(self, trapezoid):
|
||||||
|
self.trapezoid = trapezoid
|
||||||
Node.__init__(self, None, None)
|
Node.__init__(self, None, None)
|
||||||
trapezoid.sink = self
|
trapezoid.sink = self
|
||||||
|
|
||||||
@ -517,8 +540,9 @@ class XNode(Node):
|
|||||||
self.rchild = rchild
|
self.rchild = rchild
|
||||||
|
|
||||||
def locate(self, e):
|
def locate(self, e):
|
||||||
if e.p.x >= self.point.x: return self.right.locate(e)
|
if e.p.x >= self.point.x:
|
||||||
else: return self.left.locate(e)
|
return self.right.locate(e)
|
||||||
|
return self.left.locate(e)
|
||||||
|
|
||||||
class YNode(Node):
|
class YNode(Node):
|
||||||
|
|
||||||
@ -529,11 +553,14 @@ class YNode(Node):
|
|||||||
self.rchild = rchild
|
self.rchild = rchild
|
||||||
|
|
||||||
def locate(self, e):
|
def locate(self, e):
|
||||||
if self.edge.is_above(e.p): return self.right.locate(e)
|
if self.edge.is_above(e.p):
|
||||||
elif self.edge.is_below(e.p): return self.left.locate(e)
|
return self.right.locate(e)
|
||||||
|
elif self.edge.is_below(e.p):
|
||||||
|
return self.left.locate(e)
|
||||||
else:
|
else:
|
||||||
if e.slope < self.edge.slope: return self.right.locate(e)
|
if e.slope < self.edge.slope:
|
||||||
else: return self.left.locate(e)
|
return self.right.locate(e)
|
||||||
|
return self.left.locate(e)
|
||||||
|
|
||||||
class QueryGraph:
|
class QueryGraph:
|
||||||
|
|
||||||
@ -545,7 +572,7 @@ class QueryGraph:
|
|||||||
def locate(self, e):
|
def locate(self, e):
|
||||||
return self.head.locate(e).trapezoid
|
return self.head.locate(e).trapezoid
|
||||||
|
|
||||||
def follow_segment(self, e):
|
def follow_edge(self, e):
|
||||||
trapezoids = [self.locate(e)]
|
trapezoids = [self.locate(e)]
|
||||||
j = 0
|
j = 0
|
||||||
while(e.q.x > trapezoids[j].right_point.x):
|
while(e.q.x > trapezoids[j].right_point.x):
|
||||||
@ -658,7 +685,7 @@ cdef class MonotoneMountain:
|
|||||||
|
|
||||||
cdef void gen_mono_poly(self):
|
cdef void gen_mono_poly(self):
|
||||||
cdef Point p = self.head
|
cdef Point p = self.head
|
||||||
while(p is not None):
|
while(p != None):
|
||||||
self.mono_poly.append(p)
|
self.mono_poly.append(p)
|
||||||
p = p.next
|
p = p.next
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user