mirror of
https://github.com/jhasse/poly2tri.git
synced 2024-12-02 10:13:29 +01:00
added polydecomp
This commit is contained in:
parent
2e0041456a
commit
43ad3e41fa
@ -4,6 +4,7 @@
|
|||||||
from math import pi as PI
|
from math import pi as PI
|
||||||
|
|
||||||
from gl cimport *
|
from gl cimport *
|
||||||
|
include "polydecomp.pxi"
|
||||||
|
|
||||||
cdef extern from 'math.h':
|
cdef extern from 'math.h':
|
||||||
double cos(double)
|
double cos(double)
|
||||||
|
150
python/framework/polydecomp.pxi
Normal file
150
python/framework/polydecomp.pxi
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
##
|
||||||
|
## Ported from PolyDeomp by Mark Bayazit
|
||||||
|
## http://mnbayazit.com/406/credit
|
||||||
|
##
|
||||||
|
from sys import float_info
|
||||||
|
|
||||||
|
def makeCCW(list poly):
|
||||||
|
cdef int br = 0
|
||||||
|
# find bottom right point
|
||||||
|
for i from 1 <= i < len(poly):
|
||||||
|
if poly[i][1] < poly[br][1] or (poly[i][1] == poly[br][1] and poly[i][0] > poly[br][0]):
|
||||||
|
br = i
|
||||||
|
# reverse poly if clockwise
|
||||||
|
if not left(at(poly, br - 1), at(poly, br), at(poly, br + 1)):
|
||||||
|
poly.reverse()
|
||||||
|
|
||||||
|
cpdef list decompose_poly(list poly, list polys):
|
||||||
|
|
||||||
|
cdef list upperInt = [], lowerInt = [], p = [], closestVert = []
|
||||||
|
cdef float upperDist, lowerDist, d, closestDist
|
||||||
|
cdef int upper_index, lower_index, closest_index
|
||||||
|
cdef list lower_poly = [], upper_poly = []
|
||||||
|
|
||||||
|
for i from 0 <= i < len(poly):
|
||||||
|
if is_reflex(poly, i):
|
||||||
|
upperDist = lowerDist = float_info.max
|
||||||
|
for j from 0 <= j < len(poly):
|
||||||
|
if left(at(poly, i - 1), at(poly, i), at(poly, j)) and rightOn(at(poly, i - 1), at(poly, i), at(poly, j - 1)):
|
||||||
|
# if line intersects with an edge
|
||||||
|
# find the point of intersection
|
||||||
|
p = intersection(at(poly, i - 1), at(poly, i), at(poly, j), at(poly, j - 1))
|
||||||
|
if right(at(poly, i + 1), at(poly, i), p):
|
||||||
|
# make sure it's inside the poly
|
||||||
|
d = sqdist(poly[i], p)
|
||||||
|
if d < lowerDist:
|
||||||
|
# keep only the closest intersection
|
||||||
|
lowerDist = d
|
||||||
|
lowerInt = p
|
||||||
|
lower_index = j
|
||||||
|
if left(at(poly, i + 1), at(poly, i), at(poly, j + 1)) and rightOn(at(poly, i + 1), at(poly, i), at(poly, j)):
|
||||||
|
p = intersection(at(poly, i + 1), at(poly, i), at(poly, j), at(poly, j + 1))
|
||||||
|
if left(at(poly, i - 1), at(poly, i), p):
|
||||||
|
d = sqdist(poly[i], p)
|
||||||
|
if d < upperDist:
|
||||||
|
upperDist = d
|
||||||
|
upperInt = p
|
||||||
|
upper_index = j
|
||||||
|
|
||||||
|
# if there are no vertices to connect to, choose a point in the middle
|
||||||
|
if lower_index == (upper_index + 1) % len(poly):
|
||||||
|
p[0] = (lowerInt[0] + upperInt[0]) / 2
|
||||||
|
p[1] = (lowerInt[1] + upperInt[1]) / 2
|
||||||
|
|
||||||
|
if i < upper_index:
|
||||||
|
lower_poly.extend(poly[i:upper_index+1])
|
||||||
|
lower_poly.append(p)
|
||||||
|
upper_poly.append(p)
|
||||||
|
if lower_index != 0:
|
||||||
|
upper_poly.extend(poly[lower_index:])
|
||||||
|
upper_poly.extend(poly[:i+1])
|
||||||
|
else:
|
||||||
|
if i != 0:
|
||||||
|
lower_poly.extend(poly[i:])
|
||||||
|
lower_poly.extend(poly[:upper_index+1])
|
||||||
|
lower_poly.append(p)
|
||||||
|
upper_poly.append(p)
|
||||||
|
upper_poly.extend(poly[lower_index:i+1])
|
||||||
|
else:
|
||||||
|
|
||||||
|
# connect to the closest point within the triangle
|
||||||
|
|
||||||
|
if lower_index > upper_index:
|
||||||
|
upper_index += len(poly)
|
||||||
|
|
||||||
|
closestDist = float_info.max
|
||||||
|
for j from lower_index <= j <= upper_index:
|
||||||
|
if leftOn(at(poly, i - 1), at(poly, i), at(poly, j)) and rightOn(at(poly, i + 1), at(poly, i), at(poly, j)):
|
||||||
|
d = sqdist(at(poly, i), at(poly, j))
|
||||||
|
if d < closestDist:
|
||||||
|
closestDist = d
|
||||||
|
closestVert = at(poly, j)
|
||||||
|
closest_index = j % len(poly)
|
||||||
|
|
||||||
|
if i < closest_index:
|
||||||
|
lower_poly.extend(poly[i:closest_index+1])
|
||||||
|
if closest_index != 0:
|
||||||
|
upper_poly.extend(poly[closest_index:])
|
||||||
|
upper_poly.extend(poly[:i+1])
|
||||||
|
else:
|
||||||
|
if i != 0:
|
||||||
|
lower_poly.extend(poly[i:])
|
||||||
|
lower_poly.extend(poly[:closest_index+1])
|
||||||
|
upper_poly.extend(poly[closest_index:i+1])
|
||||||
|
|
||||||
|
# solve smallest poly first
|
||||||
|
if len(lower_poly) < len(upper_poly):
|
||||||
|
decompose_poly(lower_poly, polys)
|
||||||
|
decompose_poly(upper_poly, polys)
|
||||||
|
else:
|
||||||
|
decompose_poly(upper_poly, polys)
|
||||||
|
decompose_poly(lower_poly, polys)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
polys.append(poly)
|
||||||
|
|
||||||
|
cdef list intersection(list p1, list p2, list q1, list q2):
|
||||||
|
cdef list i = []
|
||||||
|
cdef float a1, b1, c1, a2, b2, c2, det
|
||||||
|
a1 = p2[1] - p1[1]
|
||||||
|
b1 = p1[0] - p2[0]
|
||||||
|
c1 = a1 * p1[0] + b1 * p1[1]
|
||||||
|
a2 = q2[1] - q1[1]
|
||||||
|
b2 = q1[0] - q2[0]
|
||||||
|
c2 = a2 * q1[0] + b2 * q1[1]
|
||||||
|
det = a1 * b2 - a2 * b1
|
||||||
|
if not eq(det, 0):
|
||||||
|
# lines are not parallel
|
||||||
|
i.append((b2 * c1 - b1 * c2) / det)
|
||||||
|
i.append((a1 * c2 - a2 * c1) / det)
|
||||||
|
return i
|
||||||
|
|
||||||
|
cdef bool eq(float a, float b):
|
||||||
|
return abs(a - b) <= 1e-8
|
||||||
|
|
||||||
|
cdef list at(list v, int i):
|
||||||
|
return v[i%len(v)]
|
||||||
|
|
||||||
|
cdef float area(list a, list b, list c):
|
||||||
|
return (((b[0] - a[0])*(c[1] - a[1]))-((c[0] - a[0])*(b[1] - a[1])))
|
||||||
|
|
||||||
|
cdef bool left(list a, list b, list c):
|
||||||
|
return area(a, b, c) > 0
|
||||||
|
|
||||||
|
cdef bool leftOn(list a, list b, list c):
|
||||||
|
return area(a, b, c) >= 0
|
||||||
|
|
||||||
|
cdef bool right(list a, list b, list c):
|
||||||
|
return area(a, b, c) < 0
|
||||||
|
|
||||||
|
cdef bool rightOn(list a, list b, list c):
|
||||||
|
return area(a, b, c) <= 0
|
||||||
|
|
||||||
|
cdef float sqdist(list a, list b):
|
||||||
|
cdef float dx = b[0] - a[0]
|
||||||
|
cdef float dy = b[1] - a[1]
|
||||||
|
return dx * dx + dy * dy
|
||||||
|
|
||||||
|
cdef bool is_reflex(list poly, int i):
|
||||||
|
return right(at(poly, i - 1), at(poly, i), at(poly, i + 1))
|
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python2.6
|
#!/usr/bin/env python2.6
|
||||||
from framework import Game, draw_polygon, reset_zoom, draw_line
|
from framework import Game, draw_polygon, reset_zoom, draw_line, decompose_poly, makeCCW
|
||||||
|
|
||||||
from seidel import Triangulator
|
from seidel import Triangulator
|
||||||
|
|
||||||
@ -7,11 +7,26 @@ class Poly2Tri(Game):
|
|||||||
|
|
||||||
screen_size = 800.0, 600.0
|
screen_size = 800.0, 600.0
|
||||||
|
|
||||||
|
dude = [[174.50415,494.59368],[215.21844,478.87939],[207.36129,458.87939],[203.07558,441.02225],[203.07558,418.1651],
|
||||||
|
[210.93272,394.59367],[224.50415,373.1651],[241.64701,358.1651],[257.36129,354.59367],[275.93272,356.73653],
|
||||||
|
[293.07558,359.59367],[309.50415,377.45082],[322.36129,398.1651],[331.64701,421.73653],[335.21844,437.45082],
|
||||||
|
[356.64701,428.52225],[356.1113,428.34367],[356.1113,428.34367],[368.78987,419.59368],[349.50415,384.59367],
|
||||||
|
[323.78987,359.59367],[290.93272,343.87939],[267.36129,341.02225],[264.50415,331.02225],[264.50415,321.02225],
|
||||||
|
[268.78987,306.02225],[285.93272,286.02225],[295.21844,270.30796],[303.78987,254.59367],[306.64701,213.87939],
|
||||||
|
[320,202.36218],[265,202.36218],[286.64701,217.45082],[293.78987,241.02225],[285,257.36218],[270.93272,271.73653],
|
||||||
|
[254.50415,266.02225],[250.93272,248.1651],[256.64701,233.1651],[256.64701,221.02225],[245.93272,215.30796],
|
||||||
|
[238.78987,216.73653],[233.78987,232.45082],[232.36129,249.59367],[243.07558,257.09367],[242.89701,270.30796],
|
||||||
|
[235.93272,279.95082],[222.36129,293.1651],[205.21844,300.6651],[185,297.36218],[170,242.36218],[175,327.36218],
|
||||||
|
[185,322.36218],[195,317.36218],[230.75415,301.02225],[235.39701,312.45082],[240.57558,323.52225],
|
||||||
|
[243.61129,330.48653],[245.21844,335.12939],[245.03987,344.4151],[229.86129,349.4151],[209.14701,362.09367],
|
||||||
|
[192.89701,377.80796],[177.18272,402.27225],[172.36129,413.87939],[169.14701,430.48653],[168.61129,458.52225],
|
||||||
|
[168.61129,492.80796]]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Poly2Tri, self).__init__(*self.screen_size)
|
super(Poly2Tri, self).__init__(*self.screen_size)
|
||||||
|
|
||||||
# Load point set
|
# Load point set
|
||||||
file_name = "../data/star.dat"
|
file_name = "../data/dude.dat"
|
||||||
self.points = self.load_points(file_name)
|
self.points = self.load_points(file_name)
|
||||||
|
|
||||||
# Triangulate
|
# Triangulate
|
||||||
@ -25,19 +40,32 @@ class Poly2Tri(Game):
|
|||||||
self.edges = seidel.edge_list
|
self.edges = seidel.edge_list
|
||||||
print "time (ms) = %f , num triangles = %d" % (dt, len(self.triangles))
|
print "time (ms) = %f , num triangles = %d" % (dt, len(self.triangles))
|
||||||
|
|
||||||
|
for p in self.dude:
|
||||||
|
p[0] -= 75
|
||||||
|
|
||||||
|
makeCCW(self.dude)
|
||||||
|
self.dude_poly = []
|
||||||
|
t1 = self.time
|
||||||
|
decompose_poly(self.dude, self.dude_poly)
|
||||||
|
dt = (self.time - t1) * 1000.0
|
||||||
|
print "time (ms) = %f , num polies = %d" % (dt, len(self.dude_poly))
|
||||||
|
|
||||||
self.main_loop()
|
self.main_loop()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
reset_zoom(2.1, (400, 100), self.screen_size)
|
reset_zoom(2.1, (300, 450), self.screen_size)
|
||||||
red = 255, 0, 0
|
red = 255, 0, 0
|
||||||
yellow = 255, 255, 0
|
yellow = 255, 255, 0
|
||||||
green = 0, 255, 0
|
green = 0, 255, 0
|
||||||
for t in self.triangles:
|
for t in self.triangles:
|
||||||
draw_polygon(t, red)
|
draw_polygon(t, red)
|
||||||
|
|
||||||
|
for p in self.dude_poly:
|
||||||
|
draw_polygon(p, red)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
for t in self.trapezoids:
|
for t in self.trapezoids:
|
||||||
verts = self.trapezoids[t].vertices()
|
verts = self.trapezoids[t].vertices()
|
||||||
|
Loading…
Reference in New Issue
Block a user