예제 #1
0
 def CastAgainst(self, other, cast_distance=1000.0):
     if isinstance(other, Circle):
         pass
     elif isinstance(other, LineSegment):
         ray_segment = LineSegment(point_a=self.point,
                                   point_b=self.EvalParam(cast_distance))
         hit_point = ray_segment.IntersectWith(other)
         if hit_point is not None:
             return self.CalcParam(hit_point)
     elif isinstance(other, Ray):
         pass
     elif isinstance(other, Polygon):
         pass
     elif type(other) is list:
         smallest_hit = None
         for item in other:
             hit = self.CastAgainst(item)
             if hit is not None and hit >= 0.0 and (smallest_hit is None
                                                    or hit < smallest_hit):
                 smallest_hit = hit
         return smallest_hit
예제 #2
0
 def _Tessellate(self, given_mesh):
     self.RemoveRedundantVertices()
     if len(self.vertex_list) < 3:
         return
     elif len(self.vertex_list) == 3:
         triangle = Triangle(self.vertex_list[0], self.vertex_list[1],
                             self.vertex_list[2])
         given_mesh.AddTriangle(triangle)
     else:
         candidate_list = []
         for i in range(len(self.vertex_list)):
             for j in range(i + 1, len(self.vertex_list)):
                 if (i + 1) % len(self.vertex_list) != j and (i - 1) % len(
                         self.vertex_list) != j:
                     candidate_list.append((i, j))
         # The idea here is that we might get better tessellations if we try the candidates in this order.
         candidate_list.sort(key=lambda pair: (self.vertex_list[pair[
             1]] - self.vertex_list[pair[0]]).Length(),
                             reverse=True)
         for pair in candidate_list:
             i = pair[0]
             j = pair[1]
             line_segment = LineSegment(self.vertex_list[i],
                                        self.vertex_list[j])
             try:
                 for k in range(len(self.vertex_list)):
                     if k != i and k != j:
                         if line_segment.ContainsPoint(self.vertex_list[k]):
                             raise Exception()
                     if k != i and (k + 1) % len(self.vertex_list) != i:
                         if k != j and (k + 1) % len(self.vertex_list) != j:
                             edge_segment = LineSegment(
                                 self.vertex_list[k],
                                 self.vertex_list[(k + 1) %
                                                  len(self.vertex_list)])
                             point = edge_segment.IntersectWith(
                                 line_segment)
                             if point is not None:
                                 raise Exception()
                 polygon_a = Polygon()
                 k = 0
                 while True:
                     r = (j + k) % len(self.vertex_list)
                     polygon_a.vertex_list.append(self.vertex_list[r])
                     if r == i:
                         break
                     k += 1
                 if polygon_a.IsWoundCW():
                     raise Exception()
                 polygon_b = Polygon()
                 k = 0
                 while True:
                     r = (i + k) % len(self.vertex_list)
                     polygon_b.vertex_list.append(self.vertex_list[r])
                     if r == j:
                         break
                     k += 1
                 if polygon_b.IsWoundCW():
                     raise Exception()
             except:
                 pass
             else:
                 polygon_a._Tessellate(given_mesh)
                 polygon_b._Tessellate(given_mesh)
                 break
         else:
             raise Exception('Failed to tessellate polygon!')