Alex Hunsley schrieb:
Shi Mu wrote:
is there any sample code of triangulation? many thanks!
Yes, probably.
Indeed, there is.
See attachment
regards
Gregor
_______________________________________________
Tutor maillist - Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor
--
Gregor Lingl
Reisnerstrasse 3/19
A-1030 Wien
Telefon: +43 1 713 33 98
Mobil: +43 664 140 35 27
Website: python4kids.net
## Run this program and create a polygon without
## intersecting edges by clicking the vertices with the mouse
from Tkinter import *
def area2(A,B,C):
"""2 * Flaeche des 2D-Dreiecks ABC"""
return (A[0]-C[0])*(B[1]-C[1]) - (A[1]-C[1])*(B[0]-C[0])
def insideTriangle(A, B, C, P):
"""Liegt P im Dreieck ABC?,
ABC sind im Gegenuhrzeigersinn angenommen!"""
return area2(A,B,P)>=0 and area2(B,C,P)>=0 and area2(C,A,P)>=0
def triangulate(poly):
tri = []
while len(poly) > 2:
triaFound = False
count = 0
while not triaFound and count < len(poly): #n:
count += 1
A, B, C = poly[:3]
if area2(A, B, C) >= 0:
for P in poly[3:]:
if insideTriangle(A,B,C,P):
break
else:
tri.append( (A,B,C) )
poly.remove(B)
triaFound = True
poly.append(poly.pop(0))
if count == len(poly): # n:
print "Not a simple polygon"
return None
return tri
class CvDefPoly(Canvas):
def __init__(self, root):
Canvas.__init__(self, root, bg="white", cursor="crosshair")
self.v = ()
self.rWidth, self.rHeight = 10.0, 7.5
self.bind("<Configure>", self.repaint)
self.bind("<Button-1>", self.mousePressed)
self.done = False
def mousePressed(self, event):
if self.done:
self.done = False
self.v = ()
x ,y = self.fx(event.x), self.fy(event.y)
if self.v:
x0, y0 = self.v[:2]
if abs(x-x0)<self.rWidth*0.01 and abs(y-y0)<self.rHeight*0.01:
self.done = True
if not self.done:
self.v += (x,y)
self.repaint(None)
def iX(self,x):
return self.centerX + x/self.pixelSize
def iY(self,y):
return self.centerY - y/self.pixelSize
def fx(self,x):
return (x-self.centerX)*self.pixelSize
def fy(self,y):
return (self.centerY - y)*self.pixelSize
def repaint(self, event):
items = self.find_all()
for item in items:
self.delete(item)
if event:
self.w, self.h = event.width, event.height
w,h = self.w, self.h
self.minX = self.minY = 2.0
self.maxX, self.maxY = w-3.0, h-3.0
dx, dy = self.maxX-self.minX, self.maxY-self.minY
self.centerX = 2.0 + dx/2.0
self.centerY = 2.0 + dy/2.0
self.pixelSize = max(self.rWidth/dx, self.rHeight/dy)
left = self.iX(-self.rWidth/2.0)
right = self.iX(self.rWidth/2.0)
bottom = self.iY(-self.rHeight/2.0)
top = self.iY(self.rHeight/2.0)
self.create_rectangle(left,top,right,bottom, outline="red")
if len(self.v) > 1:
x,y = self.v[:2]
self.create_rectangle(self.iX(x)-2, self.iY(y)-2,
self.iX(x)+2, self.iY(y)+2, outline="green")
if len(self.v) > 3:
if self.done:
v = []
sv = self.v[:]
while sv:
a,b=sv[:2]
v.extend([self.iX(a), self.iY(b)])
sv = sv[2:]
self.create_polygon( v, fill="", outline="blue")
else:
coo = list(self.v[2:])
while coo:
x1,y1 = coo[:2]
self.create_line(self.iX(x),self.iY(y),
self.iX(x1),self.iY(y1),fill="blue")
x,y=x1,y1
coo = coo[2:]
def ccw(poly):
n = len(poly)
k = poly.index(min(poly))
return area2(poly[k-1], poly[k], poly[(k+1)%n]) > 0
def color(n):
return "#%02x%02x%02x" % (255-n,0,n)
class PolyTria(Tk):
def __init__(self):
Tk.__init__(self)
self.geometry("500x300-10+50")
self.title("Define polygon vertices by clicking")
CvPolyTria(self).pack(expand=1, fill="both")
class CvPolyTria(CvDefPoly):
def repaint(self, event):
doit = False
if len(self.v)>3 and self.done:
poly = []
v = self.v[:]
while v:
p = tuple(v[:2])
poly.append(p)
v = v[2:]
if not ccw(poly):
poly.reverse()
tri = triangulate(poly)
doit = True
CvDefPoly.repaint(self, event)
if doit:
anz = len(tri)
diff = 255//anz
for i,t in enumerate(tri):
(x1,y1),(x2,y2),(x3,y3) = t
t =
(self.iX(x1),self.iY(y1),self.iX(x2),self.iY(y2),self.iX(x3),self.iY(y3))
self.create_polygon(t, fill=color(i*diff), outline="black")
if __name__ == "__main__":
PolyTria().mainloop()
_______________________________________________
Tutor maillist - Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor