Advertisement
Guest User

Untitled

a guest
Jul 25th, 2014
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.24 KB | None | 0 0
  1. """ Triangulation of a simple polygon.
  2. """
  3.  
  4. class Triangulate(object):
  5. 'Triangulation class for a simple polygon'
  6.  
  7. def __init__(self, data):
  8. """ data = Polygon class -- assume vertices cycle in
  9. clockwise order.
  10. """
  11. self.data = polygon.clone
  12. self.convex = []
  13. self.concave = []
  14. self.triangulation = []
  15.  
  16. def getCoordinate(self, vertex):
  17. return (vertex.x, vertex.y)
  18.  
  19. def getTriangle(self, vertex):
  20. """ Returns triangle with vertex as the 'ear-tip'
  21. """
  22. x = self.getCoordinate(vertex.previous)
  23. y = self.getCoordinate(vertex)
  24. z = self.getCoordinate(vertex.next)
  25. return (x,y,z)
  26.  
  27. def getBarycentricCoordinate(self, triangle, point):
  28. """ http://en.wikipedia.org/wiki/Barycentric_coordinate_system
  29. if coordinates z_1, z_2, z_3 between 0 and 1 then they are
  30. inside triangle. Equal to 1 or 0 and rest in [0,1] means
  31. on border of triangle.
  32. """
  33. x_1, y_1 = triangle[0][0], triangle[0][1]
  34. x_2, y_2 = triangle[1][0], triangle[1][1]
  35. x_3, y_3 = triangle[2][0], triangle[2][1]
  36. x , y = point[0] , point[1]
  37.  
  38. detT = (x_1 - x_3)*(y_2 - y_3) + (x_3 - x_2)*(y_1 - y_3)
  39.  
  40. z_1 = ((y_2 - y_3)*(x - x_3) + (x_3 - x_2)*(y - y_3)) / detT
  41. z_2 = ((y_3 - y_1)*(x - x_3) + (x_1 - x_3)*(y - y_3)) / detT
  42. z_3 = 1.0 - z_1 - z_2
  43. return (z_1, z_2, z_3)
  44.  
  45. def checkPointIn(self, triangle, point):
  46. """ Using definition of Barycentric Coordinate System:
  47. if coordinates all in (0,1) then inside, else outside
  48. or on border.
  49. """
  50. point_bbc = self.getBarycentricCoordinate(triangle, point)
  51. for i in point_bbc:
  52. if i <= 0.0 or i >= 1.0:
  53. return False
  54. return True
  55.  
  56. def noConcaveIn(self, triangle):
  57. """ Checks self.concave for intersecting points.
  58. Returns True if no points are in triangle.
  59. """
  60. for vertex_coord in self.concave:
  61. if self.checkPointIn(triangle, vertex_coord):
  62. return False
  63. return True
  64.  
  65. def checkConvex(self, vertex):
  66. """ Checks if angle made by vertex.prev - vertex - vertex.next
  67. is convex relative to polygon. Uses sign of triple product
  68. of vectors which gives orientation. CCW = +, CW = -.
  69. If same orientation as cycling then convex, else concave.
  70. eg. If vertices are cycling clockwise and signed_area is
  71. negative then returns True. Signed_area = 0 happens when
  72. triangle is degenerate. Implemented for clockwise cycling.
  73. """
  74. x = self.getCoordinate(vertex.previous)
  75. y = self.getCoordinate(vertex)
  76. z = self.getCoordinate(vertex.next)
  77.  
  78. signed_area = (x[0]*y[1] + y[0]*z[1] + z[0]*x[1] -
  79. y[0]*x[1] - z[0]*y[1] - x[0]*z[1])
  80.  
  81. return True if signed_area < 0 else False
  82.  
  83. def getConvexConcave(self, vertex):
  84. """ Populates self.convex/self.concave
  85. using self.checkConvex
  86. """
  87. if self.checkConvex(cursor):
  88. self.convex.append(self.getCoordinate(cursor))
  89. else:
  90. self.concave.append(self.getCoordinate(cursor))
  91.  
  92. def populateConvexConcave(self):
  93.  
  94. cursor = self.data.head #Some initial vertex
  95. sentinel = cursor
  96. self.getConvexConcave(cursor)
  97.  
  98. cursor = cursor.next
  99. while cursor != sentinel:
  100. self.getConvexConcave(cursor)
  101. cursor = cursor.next
  102.  
  103. def findEar(self):
  104. """ Resets and populates self.convex/self.concave,
  105. checks triangles where the ear-tip is a convex
  106. vertex for intersection with any concave vert-
  107. ices. If no intersection returns that ear.
  108. """
  109. n = self.data.ngon
  110. cursor = self.data.head #Some initial vertex
  111.  
  112. if n == 3:
  113. triangle = self.getTriangle(cursor)
  114. return [triangle, cursor]
  115.  
  116. self.convex = []
  117. self.concave = []
  118. self.populateConvexConcave()
  119.  
  120. i = 0
  121. while i <= 2*n:
  122. if self.getCoordinate(cursor) in self.convex:
  123. triangle = self.getTriangle(cursor)
  124. if self.noConcaveIn(triangle):
  125. return [triangle, cursor]
  126. cursor = cursor.next
  127. i += 1
  128. raise Exception('Algorithm is bugged, this should not happen.')
  129.  
  130. def triangulate(self):
  131. """ Finds an ear, documents and removes vertice from polygon,
  132. repeats until only a triangle is left and adds that to
  133. triangulation.
  134. """
  135. while self.data.ngon > 3:
  136. ear = self.findEar()
  137. self.triangulation.append(ear[0])
  138. self.data.remove(ear[1])
  139.  
  140. finalear = self.findEar()
  141. self.triangulation.append(ear[0])
  142. return self.triangulation
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement