def paint_polygon(polygon: tr.Triangle, draw: ImageDraw, texture: Image, z_buffer ): """ Colorize inner part of triangle with specified color """ first , second , third = polygon.first.projection() , polygon.second.projection() , polygon.third.projection() x0 = int(min(first.x, second.x, third.x)) x1 = int(max(first.x, second.x, third.x)) y0 = int(min(first.y, second.y, third.y)) y1 = int(max(first.y, second.y, third.y)) for x in range( x0 , x1 + 1 ) : for y in range( y0 , y1 + 1 ) : barycentric = polygon.getBaricenterCordinates(gr.Point(x, y)) is_inside_triangle = all( i >= 0 for i in barycentric ) if is_inside_triangle : # получаем координаты пикселя, соответствующего отрисовываемому в данный момент, из файла текстур # получаем цвет пикселя из файла текстур по вычисленным координатам z = polygon.tmp_Z(barycentric) get_pixel = get_texture_point(polygon, barycentric) color = (texture.getpixel(get_pixel)) pixels = texture.load() intensity = (polygon.normalFirst.first +polygon.normalFirst.second + polygon.normalFirst.third) *barycentric[0]+\ (polygon.normalSecond.first +polygon.normalSecond.second + polygon.normalSecond.third) *barycentric[1]+\ (polygon.normalThird.first +polygon.normalThird.second + polygon.normalThird.third) *barycentric[2] color = (int(color[0]*intensity),int(color[1]*intensity),int(color[2]*intensity)) draw_pixel(tr.Point(x, y, z), z_buffer, draw,get_pixel,intensity ,pixels,color)
def __init__(self, master): self.dim = 500 #init vars self.got_edge = 0 #self.move_line = 0 #self.move_oval = 0 self.anistack = deque() self.moveanistack = deque() # create paining area self.canv = Canvas(root, width=self.dim, height=self.dim) self.canv.bind("<Button-1>", self.clicked) self.canv.bind("<B1-Motion>", self.moved) self.canv.bind("<ButtonRelease-1>", self.released) self.canv.pack() self.tri = Triangle([50, 70], [300, 300], [400, 100]) self.tri.id = self.canv.create_polygon(self.tri.coo, fill='yellow') frame = Frame(master) frame.pack() self.button = Button(frame, text="QUIT", fg="red", command=frame.quit) self.button.pack(side=LEFT) self.hi_there = Button(frame, text="Reset", command=self.reset) self.hi_there.pack(side=LEFT)
def main(): """ Asks user for an input file Converts the series of height data values into triangles Writes triangles to file in stl format :return: None """ # Ask user for file path and return data: in_path, data, meta_data = file_path_and_data() # Get useful meta data: cell_size = meta_data["cellsize"] offset = (meta_data["xllcorner"], meta_data["yllcorner"]) # Set up output file: out_path = os.path.splitext(in_path)[0] + ".stl" setup_out_file(out_path) # Loop through data and write to file: # Each data point and its three right and lower neighbours # generate two surface triangles print("Writing STL surface...") for j0, row in enumerate(data[:-1]): for i0, z0 in enumerate(row[:-1]): # Triangle 1 i = [i0, i0 + 1, i0] j = [j0, j0 + 1, j0 + 1] vx, vy, vz = calc_vertices(i, j, data, cell_size, offset) write_to_file(out_path, Triangle(vx, vy, vz)) # Triangle 2 i = [i0, i0 + 1, i0 + 1] j = [j0, j0, j0 + 1] vx, vy, vz = calc_vertices(i, j, data, cell_size, offset) write_to_file(out_path, Triangle(vx, vy, vz)) end_out_file(out_path) print("Done.")
class TestTriangle(unittest.TestCase): def setUp(self): self.triangle = Triangle(2, 3, 4) def testInvariants(self): self.assertAlmostEqual( math.pi, self.triangle.alfa() + self.triangle.beta() + self.triangle.gamma()) self.assertAlmostEqual( self.triangle.a / math.sin(self.triangle.alfa()), self.triangle.b / math.sin(self.triangle.beta())) self.assertAlmostEqual( self.triangle.c / math.sin(self.triangle.gamma()), self.triangle.b / math.sin(self.triangle.beta())) def testCircumference(self): self.assertAlmostEqual(9, self.triangle.circumference()) def testScale(self): self.triangle.scale(10) self.assertAlmostEqual(20, self.triangle.a) self.assertAlmostEqual(30, self.triangle.b) self.assertAlmostEqual(40, self.triangle.c) self.testInvariants()
def make_triangles(self): polyline = [] triangles = [] for p in self.points_list: polyline.append(p.get_coord()) this_polygon = None for i in range(5): try: this_polygon = poly2tri.Triangulator(polyline) break except: pass if not this_polygon: return None for triangle in this_polygon.polygons: point_a = Point() point_a.set_coord(triangle[0].x, triangle[0].y) point_b = Point() point_b.set_coord(triangle[1].x, triangle[1].y) point_c = Point() point_c.set_coord(triangle[2].x, triangle[2].y) this_triangle = Triangle() this_triangle.set_point_by_points(point_a, point_b, point_c) triangles.append(this_triangle) return triangles
def polygon_triangulation(self): """returns a list of triangles that describe the current polygon""" self.close_polygon() poly_line = [] triangles = [] for point in self.polygon_points: poly_line.append(point.get_point()) this_polygon = None for i in range(5): try: this_polygon = poly2tri.Triangulator(poly_line) break except: pass if not this_polygon: return None for triangle in this_polygon.polygons: point_a = Point() point_a.set_point(triangle[0].x, triangle[0].y) point_b = Point() point_b.set_point(triangle[1].x, triangle[1].y) point_c = Point() point_c.set_point(triangle[2].x, triangle[2].y) this_triangle = Triangle() this_triangle.set_points_by_point(point_a, point_b, point_c) triangles.append(this_triangle) return triangles
def testTriangleThirdNode(self): n1 = Node((0,0),1) n2 = Node((1,1),2) n3 = Node((0,1),3) t = Triangle(n1, n2, n3) self.assertEqual(n1, t.getThirdNode(n2,n3)) self.assertEqual(n2, t.getThirdNode(n1,n3)) self.assertEqual(n3, t.getThirdNode(n1,n2))
def test_normal_Triangle(self): t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0)) n1 = t.local_normal_at(Point(0, 0.5, 0)) n2 = t.local_normal_at(Point(-0.5, 0.75, 0)) n3 = t.local_normal_at(Point(0.5, 0.25, 0)) self.assertEqual(n1, t.normal) self.assertEqual(n2, t.normal) self.assertEqual(n3, t.normal)
def test_triangle_bounding_box(self): p1 = Point(-3, 7, 2) p2 = Point(6, 2, -4) p3 = Point(2, -1, -1) shape = Triangle(p1, p2, p3) box = shape.bounds_of() self.assertEqual(box.min, Point(-3, -1, -4)) self.assertEqual(box.max, Point(6, 7, 2))
def add_point(self, p): # получаем новые образованные рёбра и треугольники в виде очереди flip_list = self.make_triangles(p) # флипаем некоторые рёбра, добавляем их соседей в очередь while flip_list: t1, e = flip_list.popleft() if t1 is None: continue t2 = t1.get_neigh(e) if t2 is None: continue p1, p2 = e p3 = t1.get_opposite(e) p4 = t2.get_opposite(e) # получаем окружность по трём точкам circle = Circle.get_circle(p1, p2, p3) # если четвертая точка в окружности, то делаем флип if Circle.is_in_circle(circle, p4): id1 = t1.id id2 = t2.id e13 = (p1, p3) e14 = (p1, p4) e23 = (p2, p3) e24 = (p2, p4) e34 = (p3, p4) t13 = t1.get_neigh(e13) t23 = t1.get_neigh(e23) t14 = t2.get_neigh(e14) t24 = t2.get_neigh(e24) t1_new = Triangle([[e13, t13], [e14, t14], [e34, None]], id1) t2_new = Triangle([[e23, t23], [e24, t24], [e34, t1_new]], id2) t1_new.set_neigh(e34, t2_new) # заменяем старые треугольники на новые self.triangles_list[id1] = t1_new self.triangles_list[id2] = t2_new if t13 is not None: t13.set_neigh(e13, t1_new) if t14 is not None: t14.set_neigh(e14, t1_new) if t23 is not None: t23.set_neigh(e23, t2_new) if t24 is not None: t24.set_neigh(e24, t2_new) # добавляем новые потенциально опасные ребра в виде пар [треугольник, проблемное ребро] flip_list.append([t14, e14]) flip_list.append([t24, e24]) flip_list.append([t13, e13]) flip_list.append([t23, e23])
def calcAffordances(self, lines): # Calculate affordances by intersecting agains one triangle per affordance # make initial triangle o = Point(0,0,0) # The triangle is a bit behind oBehind = Point(-.2,0,0) v1 = Point(cos(self.aperture/2)*self.lenght, sin(self.aperture/2)*self.lenght,0) v2 = Point(cos(self.aperture/2)*self.lenght, -sin(self.aperture/2)*self.lenght,0) t = Triangle([o,v1,v2]) # for each angle: transform the triangle and intersect it with all lines lBase = Line(o, Point(1,0,0)); affordances = [] markers = [] i = 0 for angle in self.possibleAngles: # reference transformation lTransform = Line(o, Point(cos(angle), sin(angle), 0)) mov = Movement(lBase, lTransform) tMoved = t.moved(mov); canMove = True j = 0 while j < len(lines) and canMove: l = lines[j] p1 = l.p1 p2 = l.p2 canMove = canMove and not tMoved.containedOrIntersect(Point(p1.x,p1.y,p1.z), Point(p2.x,p2.y,p2.z)) if not canMove: print "cant move to", angle print tMoved.vertices print p1 print p2 j += 1 affordances.append(canMove) # if canMove: # color = 'b' # else: # color = 'r' # geomPoints = [geometry_msgs.msg.Point(p.r[0],p.r[1],p.r[2]) for p in tMoved.vertices] # geomPoints.append(geomPoints[0]) # markers.append(self.getLineStrip(geomPoints, i, rospy.Time.now(), color)) # i += 1 # for l in lines: ## print "line", a # markers.append(self.getLineStrip([l.p1,l.p2], i, rospy.Time.now(), 'g')) # i = i + 1 # # mArray = MarkerArray() # mArray.markers = markers # self.pubMarker.publish(mArray) # print "lines", lines return affordances
def flip_edges(self, min_sabr=0.05): new_internal_edges = list() while len(self.internal_edges) != 0: edge = self.internal_edges.pop() o_edge = opposite_edge(edge) if o_edge is not None: edge_len_squared = distance_squared(edge[0], edge[1]) o_edge_len_squared = distance_squared(o_edge[0], o_edge[1]) # sabr = "squared altitude-base ratio" current_too_skinny = min_sabr > min( o_edge[0].dist_squared_from_line(edge[0], edge[1]) / edge_len_squared, o_edge[1].dist_squared_from_line(edge[0], edge[1]) / edge_len_squared) new_too_skinny = min_sabr > min( edge[0].dist_squared_from_line(o_edge[0], o_edge[1]) / o_edge_len_squared, edge[1].dist_squared_from_line(o_edge[0], o_edge[1]) / o_edge_len_squared) current_tri1 = [o_edge[0], edge[0], edge[1]] current_tri2 = [o_edge[1], edge[0], edge[1]] new_tri1 = [edge[0], o_edge[0], o_edge[1]] new_tri2 = [edge[1], o_edge[0], o_edge[1]] if new_too_skinny == current_too_skinny: # we won't check var_improves if (F, T) or (T, F) current_var1 = self.variance(pixels_in_tri(current_tri1)) current_var2 = self.variance(pixels_in_tri(current_tri2)) new_var1 = self.variance(pixels_in_tri(new_tri1)) new_var2 = self.variance(pixels_in_tri(new_tri2)) var_improves = None not in (current_var1, current_var2, new_var1, new_var2) and \ new_var1 + new_var2 < current_var1 + current_var1 # the edge will be flipped if a bordering triangle is currently too skinny (and flipping will fix that) # or if the variance would be better in the other direction if (current_too_skinny and not new_too_skinny) or \ (current_too_skinny and var_improves) or \ (not new_too_skinny and var_improves): # flip the edge self.tris.remove(Triangle(current_tri1)) self.tris.remove(Triangle(current_tri2)) self.tris.add(Triangle(new_tri1)) self.tris.add(Triangle(new_tri2)) remove_edge(edge[0], edge[1]) self.add_edge(o_edge[0], o_edge[1], auto_add_to_ie=False) new_internal_edges.append(o_edge) else: new_internal_edges.append(edge) else: new_internal_edges.append(edge) self.internal_edges = new_internal_edges
def _generate_back(self): a = self._l_t + Point3D(z=self._step_count * self._step_height) b = a + Point3D(self._width) self.triangles.append(Triangle(a, b, self._r_t)) self.triangles.append(Triangle(a, self._l_t, self._r_t)) self.edges.append(Edge(a, self._l_t)) self.edges.append(Edge(b, self._r_t))
def main(): sh = Shape() print sh t = Triangle(5, 10) print t.area() print "%s Static Method" % t.static_area(10, 20) s = Square(20) print s.area() print s.perimeter()
def main(args): side1 = int(args[1]) side2 = int(args[2]) side3 = int(args[3]) height = int(args[4]) print("the three sides and height of triangle area %d %d %d and %d" % (side1, side2, side3, height)) t1 = Triangle(side1, side2, side3, height) print("Perimeter: ", t1.perimeter()) print("Area: ", t1.area())
def make_triangles(self, p): # ищем треугольник для вставки внутрь него точки for index in range(len(self.triangles_list)): if self.triangles_list[index].is_point_in(p): insert_index = index break else: print("Точка должна лежать по крайней мере в одном из треугольников.") return None # треугольник, в который вставляем точку insert_triangle = self.triangles_list[insert_index] # создаём 3 новых треугольника p1, p2, p3 = insert_triangle.points() e1 = (p1, p2) e2 = (p2, p3) e3 = (p1, p3) e4 = (p1, p) e5 = (p2, p) e6 = (p3, p) t1 = insert_triangle.get_neigh(e1) t2 = insert_triangle.get_neigh(e2) t3 = insert_triangle.get_neigh(e3) new_t1 = Triangle([[e1, t1], [e4, None], [e5, None]], insert_index) new_t2 = Triangle([[e2, t2], [e5, new_t1], [e6, None]], len(self.triangles_list)) new_t3 = Triangle([[e3, t3], [e4, new_t1], [e6, new_t2]], len(self.triangles_list) + 1) new_t1.set_neigh(e5, new_t2) new_t1.set_neigh(e4, new_t3) new_t2.set_neigh(e6, new_t3) # обновляем соседей треугольника, в который вставили точку if t1 is not None: t1.set_neigh(e1, new_t1) if t2 is not None: t2.set_neigh(e2, new_t2) if t3 is not None: t3.set_neigh(e3, new_t3) # заменяем старый треугольник и добавляем новые self.triangles_list[insert_index] = new_t1 self.triangles_list.append(new_t2) self.triangles_list.append(new_t3) # рёбра для возможного flip - пары [треугольник, проблемное ребро] return deque([[new_t1, e1], [new_t2, e2], [new_t3, e3]])
def _generate_base(self): self._l_t = self._base_point self._r_t = self._l_t + Point3D(self._width) self._r_b = self._r_t + Point3D(y=self._step_count * self._step_length) self._l_b = self._r_b + Point3D(x=-self._width) self.triangles.append(Triangle(self._l_t, self._r_t, self._r_b)) self.triangles.append(Triangle(self._l_t, self._l_b, self._r_b)) self.edges.append(Edge(self._l_t, self._r_t)) self.edges.append(Edge(self._r_t, self._r_b)) self.edges.append(Edge(self._r_b, self._l_b)) self.edges.append(Edge(self._l_b, self._l_t))
def test_one_cell_mesh(): t = Triangle() points = [(0., 0.), (1., 0.), (0., 1.)] markers = [1, 1, 1] t.set_points(points, markers=markers) segments = [(0, 1), (1, 2), (2, 0)] t.set_segments(segments) t.triangulate(area=0.5) cells = t.get_triangles() assert len(cells) == 1
def get_triangles(self, vert): # bottom triangles d = self.density triangles = [] # bottom arc 1-x, top arc 1+d+1 - 1 + 2d # bottom triangles for i in range(d - 2): triangles.append(Triangle(vert[0], vert[i + 1], vert[i + 2])) triangles.append(Triangle( vert[0], vert[d], vert[1])) # we can safely assume vert[1] exists # top triangles for i in range(d - 2): triangles.append( Triangle(vert[d + 1], vert[i + d + 2], vert[i + d + 3])) triangles.append(Triangle(vert[d + 1], vert[2 * d + 1], vert[d + 2])) # side triangles for i in range(d - 1): triangles.append( Triangle(vert[i + 1], vert[i + 2], vert[i + d + 2])) triangles.append( Triangle(vert[i + 2], vert[i + d + 2], vert[i + d + 3])) triangles.append(Triangle(vert[d], vert[1], vert[2 * d + 1])) triangles.append(Triangle(vert[1], vert[2 * d + 1], vert[d + 2])) return triangles
def __init__(self): self.__drawing_top = 0 self.__drawing_bottom = 0 self.__border_rect = Rectangle() self.__radius = 0 self.__center = (0, 0) self.__theta = 0 self.__triangle = Triangle() self.__triangle.edge_color = PALE_GRAY self.__triangle.node_radius = GRID_UNIT / 2 self.__triangle.nodes_color = (PALE_RED, PALE_BLUE, PALE_GREEN ) # 緑と青が逆なのが工夫 self.__triangle.center_color = PALE_GRAY
def main(): """""" stage_color = clutter.Color(0, 0, 0, 255) actor_color = clutter.Color(255, 255, 255, 153) # Get the stage and set its size and color stage = clutter.Stage() stage.set_size(200, 200) stage.set_color(stage_color) # Add our custom actor to the stage actor = Triangle(actor_color) actor.set_size(100, 100) actor.set_position(20, 20) stage.add(actor) actor.show() # Show the stage stage.show() stage.connect('destroy', clutter.main_quit) #actor.set_color('Red') # Start the main loop, so we can respond to events clutter.main() return 0
def _generate_step(self, step_number): a = self._l_b + Point3D(y=-(step_number * self._step_length)) b = a + Point3D(z=self._step_height * (step_number + 1)) c = b + Point3D(y=-self._step_length) d = a + Point3D(y=-self._step_length) f = b + Point3D(z=-self._step_height) a1 = a + Point3D(x=self._width) b1 = b + Point3D(x=self._width) c1 = c + Point3D(x=self._width) d1 = d + Point3D(x=self._width) f1 = f + Point3D(x=self._width) self.triangles.append(Triangle(a, b, c)) self.triangles.append(Triangle(a, d, c)) self.triangles.append(Triangle(a1, b1, c1)) self.triangles.append(Triangle(a1, d1, c1)) self.triangles.append(Triangle(b, f, f1)) self.triangles.append(Triangle(f1, b1, b)) self.triangles.append(Triangle(c, b, b1)) self.triangles.append(Triangle(b1, c1, c)) self.edges.append(Edge(f, b)) self.edges.append(Edge(f1, b1)) self.edges.append(Edge(b, b1)) self.edges.append(Edge(c, c1)) self.edges.append(Edge(b, c)) self.edges.append(Edge(b1, c1))
def update(self, x, y): Box.update(self, x, y) pos = vec2(x, y) self.a, self.b, self.c = a, b, c = self.get_vertices(x, y) self.left_triangle = Triangle(a, b, pos, self.color, self.batch) self.bottom_triangle = Triangle(b, c, pos, self.color, self.batch) self.right_triangle = Triangle(c, a, pos, self.color, self.batch) self.glow = self.batch.add_indexed(6, pyglet.gl.GL_TRIANGLES, None, [0, 1, 3, 1, 4, 3, 1, 2, 4, 2, 5, 4, 2, 0, 5, 0, 3, 5], ('v2f', (a.x-255, a.y+512 , b.x-255, b.y-255, c.x+512, c.y-255, a.x, a.y, b.x, b.y, c.x, c.y)), ('c4f', (self.color+(0.0,))*3+(self.color+(1.0,))*3) ) self.leftattach = (b.x, y) self.bottomattach = (x, b.y) self.rightattach = (x+self.s1, y+self.s1)
def on_pre_render(self): world_matrix = self.transform.get_matrix() tris = [] if ((self.material != None) and (self.mesh)): #distance culling if (self.cull_by_distance): direction_from_camera = self.transform.position - Application.scene.camera.transform.position dist = direction_from_camera.magnitude() if (dist >= Application.scene.camera.culling_distance): return #display each side with a different color (DEBUG) if (self.debug_mode == True): colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (.5, .5, 0), (.5, 0, .5), (0, .5, .5)] i = 0 #Apply transform matrix transformation to triangles for triangle in self.mesh.tris: tpoly = [] for v in triangle.vertices: transformed = vector3.multiply_matrix(v, world_matrix) tpoly.append(transformed) t = Triangle(tpoly[0], tpoly[1], tpoly[2]) center = t.get_center() #calculate lights if (self.debug_mode == False): light_intensity = .05 for light in Application.lights_buffer: light_intensity += light.calculate_intensity( center, t.normal) if (light_intensity > 1): light_intensity = 1 t.color = self.material.color * light_intensity else: j = colors[math.floor(i / 2)] t.color = color(j[0], j[1], j[2], 1) i += 1 tris.append(t) #add triangle to buffer Application.add_triangle_to_buffer(tris)
class AbstractorBox(Box): def __init__(self, x, y): self.topline = None self.rightline = None self.bottomline = None self.color = (1.0, 0.4, 0.8) Box.__init__(self, x, y) def get_vertices(self, centerx, centery): left = centerx-self.s2 right = centerx+self.s1 bottom = centery-self.s2 top = centery+self.s1 return vec2(right, bottom), vec2(right, top), vec2(left, top) def update(self, x, y): Box.update(self, x, y) self.a, self.b, self.c = a, b, c = self.get_vertices(x, y) pos = vec2(x, y) self.leftattach = (b.x, y) self.bottomattach = (x, b.y) self.rightattach = (x+self.s1, y+self.s1) self.right_triangle = Triangle(a, b, pos, self.color, self.batch) self.top_triangle = Triangle(b, c, pos, self.color, self.batch) self.bottom_triangle = Triangle(c, a, pos, self.color, self.batch) self.glow = self.batch.add_indexed(6, pyglet.gl.GL_TRIANGLES, None, [0, 1, 3, 1, 4, 3, 1, 2, 4, 2, 5, 4, 2, 0, 5, 0, 3, 5], ('v2f', (a.x+255, a.y-512 , b.x+255, b.y+255, c.x-512, c.y+255, a.x, a.y, b.x, b.y, c.x, c.y)), ('c4f', (self.color+(0.0,))*3+(self.color+(1.0,))*3) ) self.topattach = (x, a.y) self.bottomattach = (x-self.s1, y-self.s1) self.rightattach = (a.x, y) def draw(self): self.batch.draw() def gethover(self, x, y): hovered = False if self.top_triangle.gethover(vec2(x, y)): hovered = self, self.leftattach if self.bottom_triangle.gethover(vec2(x, y)): hovered = self, self.bottomattach if self.right_triangle.gethover(vec2(x, y)): hovered = self, self.rightattach return hovered def drag_end(self, x, y): pass
def ReadBlend(self, fname): """imports an OBJ file, and populates tris and points """ print("filename",fname) file = open(fname, "r") currentLine = file.readline() while (currentLine): # parse out numbers from the string using Regex pattern language # (from the re package) numbers = re.findall(r'-?\d+(?:\.\d+)?', currentLine) # find 'v' character and populate vertex information if (currentLine[0] == "v" and currentLine[1] == " "): # make a new vertex object out of it self.newVertex = vertex(float(numbers[0]), float(numbers[1]), float(numbers[2])) self.points.append(self.newVertex) # find 'f' character and populate face information elif (currentLine[0] == "f"): self.newTriangle = Triangle(int(numbers[0])-1, int(numbers[3])-1, int(numbers[6])-1) self.tris.append(self.newTriangle) currentLine = file.readline() for point in self.points: point.printXYZ() for tri in self.tris: tri.printIV()
def read_file_into_mesh(file, to_pickle=False): vertex_num = 0 vertices = {} faces = [] vert_key = [] num_lines = len(open(file).readlines()) line_num = 0.0 print('Converting to work format...\n') triangles = [] vectors = [] for line in open(file): line_num += 1.0 split_line = line.split() if split_line[0] == 'vertex': vectors.append( Vector(float(split_line[1]), float(split_line[2]), float(split_line[3]))) elif split_line[0] == 'endloop': triangles.append(Triangle(vectors[0], vectors[1], vectors[2])) vectors = [] amtDone = line_num / num_lines sys.stdout.write("\rProgress: [{0:50s}] {1:.1f}%".format( '#' * int(amtDone * 50), amtDone * 100)) return triangles
def from_obj(file_path, mesh=None): """Load a mesh from an .obj file Arguments: file_path {string} -- the path to the file Keyword Arguments: mesh {Mesh} -- mesh to assign the polygons (default: {None}) Returns: Mesh -- a mesh with the loaded polygons """ if (mesh == None): mesh = Mesh(file_path) vertices = [] file = open(file_path, 'r') for line in file: if (line[0] == 'v'): elements = line.split() p1 = float(elements[1]) p2 = float(elements[2]) p3 = float(elements[3]) vertices.append(vector3(p1, p2, p3)) if (line[0] == 'f'): elements = line.split() v1 = int(elements[1]) - 1 v2 = int(elements[2]) - 1 v3 = int(elements[3]) - 1 triangle = Triangle(vertices[v1], vertices[v2], vertices[v3]) mesh.tris.append(triangle) return mesh
def __init__(self, size=trigon_rules.default_size): self.size = size n = size field = [] for x in range(n): line = [] for y in range(2 * (n + x) + 1): line.append(Triangle(x + 1, y + 1, self.size)) field.append(line) for x in range(n, 2 * n): line = [] for y in range(4 * n - 1 - 2 * (x - n)): line.append(Triangle(x + 1, y + 1, self.size)) field.append(tuple(line)) self.field = tuple(field)
def __init__(self, master): self.dim = 500 #init vars self.got_edge = 0 #self.move_line = 0 #self.move_oval = 0 self.anistack = deque() self.moveanistack = deque() # create paining area self.canv = Canvas(root, width = self.dim, height = self.dim) self.canv.bind("<Button-1>", self.clicked) self.canv.bind("<B1-Motion>", self.moved) self.canv.bind("<ButtonRelease-1>", self.released) self.canv.pack() self.tri = Triangle([50,70],[300,300],[400,100]) self.tri.id = self.canv.create_polygon(self.tri.coo,fill='yellow') frame = Frame(master) frame.pack() self.button = Button(frame, text="QUIT", fg="red", command=frame.quit) self.button.pack(side=LEFT) self.hi_there = Button(frame, text="Reset", command=self.reset) self.hi_there.pack(side=LEFT)
def fan_triangulation(vertices: Iterable[Point], vertex_normals: Iterable[Point], vertex_indices: Iterable[str]) -> Iterable: from triangle import Triangle triangles = [] vertex_1_info = vertex_indices[1].split('/') for index in range(2, len(vertex_indices) - 1): if len(vertex_1_info) == 1: tri = Triangle(vertices[int(vertex_indices[1])], vertices[int(vertex_indices[index])], vertices[int(vertex_indices[index + 1])]) triangles.append(tri) else: vertex_2_info = vertex_indices[index].split('/') vertex_3_info = vertex_indices[index + 1].split('/') tri = SmoothTriangle(vertices[int(vertex_1_info[0])], vertices[int(vertex_2_info[0])], vertices[int(vertex_3_info[0])], vertex_normals[int(vertex_1_info[2])], vertex_normals[int(vertex_2_info[2])], vertex_normals[int(vertex_3_info[2])]) triangles.append(tri) return triangles
def createNewTriangles(self): """createNewTriangles calculates smaller triangles with new corners """ trisnew = [] for t in self.tris: # calculate middle triangle t2 = Triangle(t.ie[0], t.ie[1], t.ie[2]) # calculate triangles around the middle triangle t0 = Triangle(t.ie[1], t.ie[0], t.iv[2]) t1 = Triangle(t.iv[0], t.ie[2], t.ie[1]) t3 = Triangle(t.ie[2], t.iv[1], t.ie[0]) trisnew.append(t0) trisnew.append(t1) trisnew.append(t2) trisnew.append(t3) self.tris = trisnew
class TestTriangle(unittest.TestCase): def setUp(self): self.triangle = Triangle(100, 30) # Return dimension def test_area(self): self.assertEqual(1500, self.triangle.area())
def create_quad(origin, axis0, axis1, mesh): if (mesh == None): mesh = Mesh("UnknownQuad") v1 = origin + axis0 + axis1 v2 = origin + axis0 - axis1 v3 = origin - axis0 - axis1 v4 = origin - axis0 + axis1 t1 = Triangle(v1, v2, v3) t2 = Triangle(v1, v3, v4) mesh.tris.append(t1) mesh.tris.append(t2) return mesh
def read_file_obj(file_obj): first_line = file_obj.readline() items = first_line.split() x, y = [int(a) for a in items[:2]] if len(items) == 3: color_type = items[2] else: color_type = RGB s = Sketch(Point(x, y), color_type) for line in file_obj: items = string_to_ints(line) if color_type == RGB: t = Triangle(items[:6], tuple(items[6:9]), items[9]) else: t = Triangle(items[:6], items[6], items[7]) s.triangles.append(t) return s
def bowyerWatson(points): # https://en.wikipedia.org/wiki/Bowyer%E2%80%93Watson_algorithm # print("Running bowyerWatson on %d points" % len(points)) triangulation = [] # must be large enough to completely contain all the points in pointList P1 = Vec(-1e15, -1e15) P2 = Vec(1e15, -1e15) P3 = Vec(0, 1e15) megaTriangle = Triangle(P1, P2, P3) triangulation.append(megaTriangle) # add all the points one at a time to the triangulation for iP, P in enumerate(points): badTriangles = [] # first find all the triangles that are no longer valid due to the insertion for iT, T in enumerate(triangulation): if distance(P, T.C) < T.R: # If point inside triangle circumcircle badTriangles.append(T) # Triangle is bad # find the boundary of the polygonal hole polygon = [] for T in badTriangles: for V in T.vertices: # for each edge in triangle # if edge is not shared by any other triangles in badTriangles if not any([_T.hasVertex(V) for _T in badTriangles if T != _T]): polygon.append(V) for T in badTriangles: triangulation.remove(T) # re-triangulate the polygonal hole for v1, v2 in polygon: triangulation.append(Triangle(P, v1, v2)) # if triangle contains a vertex from original super-triangle triangulation = [ T for T in triangulation if not T.sharesCornerWith(megaTriangle) ] return triangulation #######################################
def hit(self, ray_in, t_min, t_max): list_of_triangles = [] for face in self.faces: vertices = self.getFaceData(self.faces.index(face)) for triangle_no in range(0, len(vertices) - 2): list_of_triangles.append(Triangle(v = [vertices[0], vertices[triangle_no + 1], vertices[triangle_no + 2]], material = self.material)) hitable_list = Hitable_List(list_of_triangles) return hitable_list.hit(ray_in, t_min, t_max)
def __init__(self, inf = 65536, test = False): self._initTriangle = Triangle(Point2D(-inf, -inf), Point2D(inf, -inf), Point2D(0, inf)) self.neighborhood = {self._initTriangle: {}} self.lock = threading.RLock() self.main_site = None self.fail_site = None self.fail_triangle = None self.fail_witness = None self.version = 0 self.check_triangulation = test
class TriangleTest(unittest.TestCase): def setUp(self): self.triangle = Triangle() def test_get_side1(self): self.assertEqual( self.triangle.get_side1(), self.triangle._Triangle__side1 ) def test_get_side2(self): self.assertEqual( self.triangle.get_side2(), self.triangle._Triangle__side2 ) def test_get_side3(self): self.assertEqual( self.triangle.get_side3(), self.triangle._Triangle__side3 ) def test_get_perimeter(self): self.assertEqual( self.triangle.get_perimeter(), self.triangle._Triangle__side1 + self.triangle._Triangle__side2 + self.triangle._Triangle__side3 ) def test_get_area(self): p = self.triangle.get_perimeter() / 2 area = math.sqrt( p * (p - self.triangle._Triangle__side1) * (p - self.triangle._Triangle__side2) * (p - self.triangle._Triangle__side3) ) self.assertEqual( self.triangle.get_area(), area )
def get_triangles_for_rectangle(self, min_x, max_x, min_y, max_y): """ Args: min_x: int max_x: int min_y: int max_y: int Returns: List(tri_image.triangle.Triangle) of length 2 """ if self.color_type == RGB: c = (0, 0, 0) else: c = 0 t1 = Triangle([min_x, min_y, min_x, max_y, max_x, max_y], c, 255) t1.set_color(self.source_image, self.color_type) t2 = Triangle([min_x, min_y, max_x, min_y, max_x, max_y], c, 255) t2.set_color(self.source_image, self.color_type) return [t1, t2]
class ApplicatorBox(Box): def __init__(self, x, y): self.leftline = None self.rightline = None self.bottomline = None self.color = (0.4, 1.0, 0.8) Box.__init__(self, x, y) def get_vertices(self, centerx, centery): left = centerx-self.s1 right = centerx+self.s2 bottom = centery-self.s1 top = centery+self.s2 return vec2(left, top), vec2(left, bottom), vec2(right, bottom) def update(self, x, y): Box.update(self, x, y) pos = vec2(x, y) self.a, self.b, self.c = a, b, c = self.get_vertices(x, y) self.left_triangle = Triangle(a, b, pos, self.color, self.batch) self.bottom_triangle = Triangle(b, c, pos, self.color, self.batch) self.right_triangle = Triangle(c, a, pos, self.color, self.batch) self.glow = self.batch.add_indexed(6, pyglet.gl.GL_TRIANGLES, None, [0, 1, 3, 1, 4, 3, 1, 2, 4, 2, 5, 4, 2, 0, 5, 0, 3, 5], ('v2f', (a.x-255, a.y+512 , b.x-255, b.y-255, c.x+512, c.y-255, a.x, a.y, b.x, b.y, c.x, c.y)), ('c4f', (self.color+(0.0,))*3+(self.color+(1.0,))*3) ) self.leftattach = (b.x, y) self.bottomattach = (x, b.y) self.rightattach = (x+self.s1, y+self.s1) def draw(self): self.batch.draw() if self.rightline: self.rightline.draw() if self.leftline: self.leftline.draw() def gethover(self, x, y): hovered = False if x > self.a.x and x < self.c.x and y > self.b.y and y < self.a.y: #bounding box check if self.left_triangle.gethover(vec2(x, y)): hovered = self, self.leftattach if self.bottom_triangle.gethover(vec2(x, y)): hovered = self, self.bottomattach if self.right_triangle.gethover(vec2(x, y)): hovered = self, self.rightattach else: self.left_triangle.highlight(False) self.bottom_triangle.highlight(False) self.right_triangle.highlight(False) return hovered def gethover_recursive(self, x, y): hovered = self.gethover(x, y) if hovered: return hovered else: if self.rightline: rightline_hover = self.rightline.gethover_recursive(x, y) if rightline_hover: return rightline_hover else: if self.leftline: leftline_hover = self.leftline.gethover_recursive(x, y) if leftline_hover: return leftline_hover else: return False def drag_end(self, x, y): pass
def setUp(self): path = tempfile.mktemp('.ldb') db = leveldb.LevelDB(path) self.triangle = Triangle(db)
class CoffeeData(flask.views.MethodView): @login_required def get(self): return flask.render_template('coffeedata.html') # Routes app.add_url_rule('/', view_func=Login.as_view('login'), methods=["GET", "POST"]) app.add_url_rule('/remote/', view_func=Remote.as_view('remote'), methods=["GET", "POST"]) app.add_url_rule('/triangle/', view_func=Triangle.as_view('triangle'), methods=["GET", "POST"]) app.add_url_rule('/music/', view_func=Music.as_view('music'), methods=["GET"]) app.add_url_rule('/asteroids/', view_func=Asteroids.as_view('asteroids'), methods=["GET"]) app.add_url_rule('/remotezsnes/', view_func=RemoteZsnes.as_view('remotezsnes'), methods=["GET"]) app.add_url_rule('/asteroids/', view_func=CoffeeData.as_view('coffeedata'), methods=["GET"]) @app.errorhandler(404)
#!/usr/bin/env python import sys import time from triangle import Triangle arr = [[6],[3,5],[9,7,1],[4,6,8,4]] t = time.time() Triangle = Triangle(arr) (sum,path) = Triangle.maximumTotal() t = time.time() - t print("========== results ==========") print(" triangle: %s " % (arr)) print(" maximum total: %d" % (sum)) print(" path: %s " % (path)) print(" execution time: %fs" % (t)) print("=============================")
def main(): Lines=1 Lines_valid=0 total_perimeter=0 total_area=0 largest_perimeter=0 largest_perimeters_area=0 largest_area=0 largest_areas_perimeter=0 triangle_perimeter='' triangle_area='' for line in fo: line = "".join(c for c in line if c not in ('(',')',' ')) linelist=line.strip().replace(' ', '').split(',') print("Line ",Lines,": ",line) sideA=linelist[0] sideB=linelist[1] sideC=linelist[2] triangle=Triangle(sideA,sideB,sideC) if triangle.is_valid()==True: Lines_valid+=1 total_perimeter+=triangle.perimeter() total_area+=triangle.area() if triangle.perimeter()>largest_perimeter: largest_perimeter=triangle.perimeter() largest_perimeters_area=triangle.area() triangle_perimeter=line if triangle.area()>largest_area: largest_area=triangle.area() largest_areas_perimeter=triangle.perimeter() triangle_area=line print("This Triangle's perimeter= {}, and area= {}".format(triangle.perimeter(),triangle.area())) else: print("Triangle is not valid") Lines+=1 print("") print("Total lines processed: ",Lines) print("Total valid triangles processed: ",Lines_valid) avg_perimeter=total_perimeter/Lines_valid avg_area=total_area/Lines_valid print("Average perimeter: ",avg_perimeter) print("Average area: ",avg_area) print("The Triangle with the largest perimeter= ",largest_perimeter," had a area= ",largest_perimeters_area," with sides: ",triangle_perimeter) print("The Triangle with the largest area= ",largest_area," had a perimeter= ",largest_areas_perimeter," with sides: ",triangle_area)
def __init__(self): ShowBase.__init__(self) winProps = WindowProperties() winProps.setTitle("Triangle and SimpleCircle Unittest") # base.win.requestProperties(winProps) (same as below e.g. self == base) self.win.requestProperties(winProps) # 1) create GeomVertexData frmt = GeomVertexFormat.getV3n3cp() vdata = GeomVertexData('triangle_developer', frmt, Geom.UHDynamic) # 2) create Writers/Rewriters (must all be created before any readers and readers are one-pass-temporary) vertex = GeomVertexRewriter(vdata, 'vertex') normal = GeomVertexRewriter(vdata, 'normal') color = GeomVertexRewriter(vdata, 'color') zUp = Vec3(0, 0, 1) wt = Vec4(1.0, 1.0, 1.0, 1.0) gr = Vec4(0.5, 0.5, 0.5, 1.0) # 3) write each column on the vertex data object (for speed, have a different writer for each column) def addPoint(x, y, z): vertex.addData3f(x, y, z) normal.addData3f(zUp) color.addData4f(wt) addPoint(0.0, 0.0, 0.0) addPoint(5.0, 0.0, 0.0) addPoint(0.0, 5.0, 0.0) addPoint(15.0, 15.0, 0.0) # 4) create a primitive and add the vertices via index (not truely associated with the actual vertex table, yet) tris = GeomTriangles(Geom.UHDynamic) t1 = Triangle(0, 1, 2, vdata, tris, vertex) t2 = Triangle(2, 1, 3, vdata, tris, vertex) c1 = t1.getCircumcircle() t1AsEnum = t1.asPointsEnum() r0 = (t1AsEnum.point0 - c1.center).length() r1 = (t1AsEnum.point1 - c1.center).length() r2 = (t1AsEnum.point2 - c1.center).length() assert abs(r0 - r2) < utilities.EPSILON and abs(r0 - r1) < utilities.EPSILON t2AsEnum = t2.asPointsEnum() c2 = t2.getCircumcircle() r0 = (t2AsEnum.point0 - c2.center).length() r1 = (t2AsEnum.point1 - c2.center).length() r2 = (t2AsEnum.point2 - c2.center).length() assert abs(r0 - r2) < utilities.EPSILON and abs(r0 - r1) < utilities.EPSILON assert t1.getAngleDeg0() == 90.0 assert t1.getAngleDeg1() == t1.getAngleDeg2() oldInd0 = t1.pointIndex0 oldInd1 = t1.pointIndex1 oldInd2 = t1.pointIndex2 t1.pointIndex0 = t1.pointIndex1 t1.pointIndex1 = oldInd0 assert t1.pointIndex0 == oldInd1 assert t1.pointIndex1 == oldInd0 assert t1.pointIndex0 != t1.pointIndex1 t1.reverse() assert t1.pointIndex1 == oldInd2 # 5.1) (adding to scene) create a Geom and add primitives of like base-type i.e. triangles and triangle strips geom = Geom(vdata) geom.addPrimitive(tris) # 5.2) create a GeomNode to hold the Geom(s) and add the Geom(s) gn = GeomNode('gnode') gn.addGeom(geom) # 5.3) attache the node to the scene gnNodePath = render.attachNewNode(gn) # setup a wire frame wireNP = render.attachNewNode('wire') wireNP.setPos(0.0, 0.0, .1) wireNP.setColor(0.1, 0.1, 0.1, 1) wireNP.setRenderMode(RenderModeAttrib.MWireframe, .5, 0) gnNodePath.instanceTo(wireNP) # test and draw intersections and circles pt1 = Point3(0.0, 5.0, 0.0) pt2 = Point3(1.0, 5.0, 0.0) intersection = t2.getIntersectionsWithCircumcircle(pt1, pt2) circle = t2.getCircumcircle() cuts = 128 border = circle.getBorder(cuts, closed=True) assert len(border) == cuts or (len(border) == cuts + 1 and border[0] == border[len(border) - 1]) n = len(border) xMid = yMid = 0 for p in border: xMid += p.x yMid += p.y mid = Point3(xMid / n, yMid / n, border[0].z) assert mid.almostEqual(circle.center, 0.06) assert t2.isCcw() assert t1.containsPoint(c1.center) != t1.containsPoint(c1.center, includeEdges=False) circleSegs = LineSegs("circleLines") circleSegs.setColor(1.0, 0.0, 0.0, 1.0) for p in border: circleSegs.drawTo(*p) circleNode = circleSegs.create(False) circleNP = render.attachNewNode(circleNode) circleNP.setZ(-5) originSpot = LineSegs("intersection") originSpot.setColor(1.0, 0.0, 0.0, 1.0) originSpot.setThickness(10) for p in intersection: originSpot.drawTo(p) spotNode = originSpot.create(False) spotNP = render.attachNewNode(spotNode) circleNP.setZ(-0.75) # fix the camera rot/pos PHF.PanditorDisableMouseFunc() camera.setPos(0.0, 0.0, 50.0) camera.lookAt(c2.center) PHF.PanditorEnableMouseFunc()
def testTriangleArea(self): t = Triangle(Node((1,1),(0,0)), Node((0,0),(0,0)), Node((1,0),(0,0))) self.assertEqual(t.getArea(), 0.5)
from triangle import Triangle from camera import Camera from random import random from math import pi, tan from vector3f import Vector3f #cam = Camera() tri = Triangle() vec1 = Vector3f(0.556, 0.401054805321, 0.40692763018) vec2 = Vector3f(-0.745565615449, 0.432850996024, -0.506726680076) print tri.get_intersection(vec1, vec2) tri.get_sample_point().echovec() print tri.area tri.tangent.echovec() tri.normal.echovec()
def test_maximumTotal_return_true_result2(self): triangle = [[6],[3,5]] T = Triangle(triangle) (val, path) = T.maximumTotal() self.assertEqual(val,11) self.assertEqual(path, [0, 1] )
from triangle import Triangle scalene_triangle=Triangle(10.0,4.0,7.0) print('A Triangle with side lengths of: ',scalene_triangle) print('Is this a valid triangle?') print(scalene_triangle.is_valid()) print('') print('Is the Triangle equilateral?') print(scalene_triangle.is_equilateral()) print('Is the Triangle isosceles?') print(scalene_triangle.is_isosceles()) print('Is the Triangle scalene?') print(scalene_triangle.is_scalene()) print('') print('What are the lengths of this Triangle again..?') print(scalene_triangle.sides()) print('What are the interior angles of this triangle?') print(scalene_triangle.angles()) print('What is the perimeter of this triangle?') print(scalene_triangle.perimeter()) print('What is the area of this triangle?') print(scalene_triangle.area())
class Delaunay(object): ''' Delaunay Triangulation ref: http://www.cs.cornell.edu/home/chew/Delaunay.html ''' # INT => MAX=+(pow(2,31) - 1)(2147483647) & MIN=-pow(2,31)(-2147483648) # inf = 1000000 was empirically limited due to pygame simulator # inf = 2^16 was empirically limited due to float point precision def __init__(self, inf = 65536, test = False): self._initTriangle = Triangle(Point2D(-inf, -inf), Point2D(inf, -inf), Point2D(0, inf)) self.neighborhood = {self._initTriangle: {}} self.lock = threading.RLock() self.main_site = None self.fail_site = None self.fail_triangle = None self.fail_witness = None self.version = 0 self.check_triangulation = test def __repr__(self): return 'Triangulation with ' + str(len(self.neighborhood)) + \ ' triangles' def __str__(self): return self.__repr__() def _new_version(self): self.version += 1 # cicle version if self.version > 2147483640: self.version = 0 def updated_since(self, version): return (version != self.version) def has_error(self): return self.fail_site is not None def include(self, site): ''' Add a site to triangulation ''' if self.fail_site is not None: return False with self.lock: triangle = self._find_triangle_circumscribe(site) return self._add(site, triangle) def remove_far_sites(self, from_site): ''' Remove all sites that do not affect a "from site" cell Returns the number of removed sites ''' if self.fail_site is not None: return False with self.lock: from_triangle = self._find_triangle_by_vertex(from_site) if (from_triangle is None): return 0 triangles, points = \ self.surrounding_triangles(from_site, from_triangle) # search irrlevant sites dispensables = [] for triangle in self.neighborhood.keys(): if (not triangle in triangles): dispensable = True for vertex in triangle: if not vertex in points: dispensables.append(vertex) # remove irrlevant sites removed = 0 for site in dispensables: if not self._initTriangle.contains(site): self.remove(site) removed += 1 return removed def include_near(self, site, from_site): ''' Add a site only if it will affect a "from site" cell ''' if self.fail_site is not None: return False with self.lock: triangle = self._find_triangle_by_vertex(from_site) if (triangle is None): raise Exception("'From site' don't found.") triangles, points = \ self.surrounding_triangles(from_site, triangle) # verify site influence for triangle in triangles: if triangle.circumscribe(site): return self._add(site, triangle) return False def remove(self, site): ''' Remove a site from triagulation ''' if self.fail_site is not None: return False with self.lock: triangle = self._find_triangle_by_vertex(site) if triangle is not None: triangles, points = self.surrounding_triangles(site, triangle) self._remove(site, points, triangles) return True return False def _find_triangle_circumscribe(self, site): ''' Search the triangle that circumcircle the point ''' for triangle in self.neighborhood: if triangle.circumscribe(site) or triangle.contains(site): return triangle raise Exception("Site out of the valid area.") def _find_triangle_by_vertex(self, site): ''' Search the triangle that contains the point as a vertex ''' for triangle in self.neighborhood.keys(): if triangle.contains(site): return triangle return None def _cavity(self, site, triangle): ''' Determine the cavity caused by site. ''' encroached = {} toBeChecked = [triangle] marked = {triangle: None} while (len(toBeChecked) > 0): triangle = toBeChecked.pop() # Site outside triangle => triangle not in cavity if not triangle.circumscribe(site): continue encroached[triangle] = None # Check the neighborhood for neighbor in self.neighborhood[triangle]: if neighbor not in marked: marked[neighbor] = None toBeChecked.append(neighbor) return encroached def _add(self, site, triangle): ''' Add a site to triangulation with specific triangle ''' if not triangle.contains(site): cavity = self._cavity(site, triangle) self._insert(site, cavity) return True return False def _add_triangle(self, t1, t2): ''' Add a triangle to neighborhood control ''' if t1 not in self.neighborhood: self.neighborhood[t1] = {t2} else: self.neighborhood[t1][t2] = None def _del_triangle(self, triangle): ''' Remove a triangle from neighborhood control ''' del self.neighborhood[triangle] for neighbor in self.neighborhood.values(): if triangle in neighbor: del neighbor[triangle] def _link_triangles(self, t1, t2): ''' Include mutual neighbor triangles ''' self._add_triangle(t1, t2) self._add_triangle(t2, t1) def _insert(self, site, cavity): ''' Update the triangulation by removing the cavity triangles and then filling the cavity with new triangles. ''' boundary = {} triangles = {} # Find boundary facets and adjacent triangles for triangle in cavity: for neighbor in self.neighborhood[triangle]: # Adj triangles only if neighbor not in cavity: triangles[neighbor] = None for point in triangle: facet = triangle.opposite_facet(point) if facet in boundary: del boundary[facet] else: boundary[facet] = None # Remove the cavity triangles from the triangulation for triangle in cavity: self._del_triangle(triangle) # Build each new triangle and include it to the triangulation new_triangles = {} for facet in boundary.keys(): newTriangle = Triangle(facet[0], facet[1], site) self.neighborhood[newTriangle] = {} new_triangles[newTriangle] = None # Adj triangle + new triangles triangles[newTriangle] = None # Update the graph links for each new triangle for triangle in new_triangles: for other in triangles: if triangle.is_neighbor(other): self._link_triangles(triangle, other) if self.main_site is None: self.main_site = site self._new_version() if self.check_triangulation: if not self.valid(): print "### Including failure" def _remove(self, site, points, triangles): ''' Update the triangulation by removing the surrounding triangles and then filling this cavity with new Delaunay triangles. Challenge: Maintain neighborhood control. Ref: Mir Abolfazl Mostafavi, Christopher Gold, and Maciej Dakowicz. 2003. Delete and insert operations in Voronoi/Delaunay methods and applications. Comput. Geosci. 29, 4 (May 2003), 523-530. DOI=10.1016/S0098-3004(03)00017-7 http://dx.doi.org/10.1016/S0098-3004(03)00017-7 ''' # verify compatibility of surrounding points and old triangles if len(points) != len(triangles): raise Exception("Triangulation has different sizes.") # verify is the triangulation is empty (or insufficient?) if len(points) < 3: return # initialize new triangulation controls i = -1 new_triangles = {} # while there are points to form more than the last triangle while len(points) > 3: # checks the possible triangles considering # all three consecutive points (i, i1, i2 in a cycle) # of surrounding points of the site i += 1 npoints = len(points) if (i >= npoints): raise Exception("Inexists a valid ear? Is it possible?") i1 = (i + 1) % npoints i2 = (i1 + 1) % npoints # verify if points represent a valid triangle to site, # like a ear listen to the site: # 1: gets triangle orientation (CW or CCW) o_ear = Triangle.orientation(points[i], points[i1], points[i2]) # 2: gets direction of triangle to the site (CW or CCW) o_ear_site = Triangle.orientation(points[i], points[i2], site) # 3: if points are collinear, try another edge as a reference # ??why don't take this edge at first place?? if o_ear_site == 0: o_ear_site = Triangle.orientation(points[i], points[i1], site) # 4: the directions is the same? if (o_ear * o_ear_site) > 0: # if so, this a valid ear (possible triangulation) valid_ear = Triangle(points[i], points[i1], points[i2]) # verify if this ear is a Delaunay Triangulation ear_is_delaunay = True # 1. for all other surrounding points for p in points: # 1.1: is this other point (not in ear)? if not valid_ear.contains(p): # verify if ear won't circumcircle it if valid_ear.circumscribe(p): # if circumcircle, ear is not a Delaunay triangle ear_is_delaunay = False break # if it is a Delaunay triangle... if ear_is_delaunay: # include to new triangle control new_triangles[valid_ear] = None # include to neighborhood control self.neighborhood[valid_ear] = {} # link to the opposite triangles from the removed vertices self._link_ear(site, valid_ear, triangles[i], new_triangles) self._link_ear(site, valid_ear, triangles[i1], new_triangles) # change triangle related to vertex by the new one # remove old triangle by switching the diagonal triangles[i] = valid_ear # remove middle point (leave the corners) del points[i1] del triangles[i1] # restart cycle of surrounding points i = -1 # if has only three neighbours remaining in the surrounding points, # merged these three points (triangles) into last triangulation last_ear = Triangle(points[0], points[1], points[2]) self.neighborhood[last_ear] = {} new_triangles[last_ear] = None # last triangle closes the triangulation and # needs update the link with all sides (neighborhood) self._link_ear(site, last_ear, triangles[0], new_triangles) self._link_ear(site, last_ear, triangles[1], new_triangles) self._link_ear(site, last_ear, triangles[2], new_triangles) if self.main_site is not None: if self.main_site == site: self.main_site = None self._new_version() if self.check_triangulation: if not self.valid(): print "### Removing failure" def _link_ear(self, site, ear, triangle, new_triangles): # check if the triangle has neighbor that is opposite from the site neighbor = self.neighbor_opposite(site, triangle) # if not, it's a external triangulation (from initial triangle) # or it's a new triangulation... if neighbor is None: # if the triangle related to the vertex is new if triangle in new_triangles: # update neighborhood with the new triangle self._link_triangles(ear, triangle) else: # otherwise, old triangle doesn't had a neighbor: # ignore its neighborhood and delete it self._del_triangle(triangle) else: # update neighborhood of new triangle (ear) self._link_triangles(ear, neighbor) # delete old voronoi cell triangle self._del_triangle(triangle) def neighbor_opposite(self, site, triangle): ''' Report neighbor opposite the given vertex of triangle. ''' if site not in triangle: return None with self.lock: for neighbor in self.neighborhood[triangle]: if not neighbor.contains(site): return neighbor return None def surrounding_triangles(self, site, triangle): ''' Report triangles and points surrounding site in order (cw or ccw). ''' if site not in triangle: raise Exception("Site not in triangle.") with self.lock: points = [] triangles = [] start = triangle # cw or cww (pay attention) guide = triangle.next_vertex_except({site}) while triangle is not None: triangles.append(triangle) points.append(guide) previous = triangle triangle = self.neighbor_opposite(guide, triangle) guide = previous.next_vertex_except({site, guide}) if (triangle == start): break return triangles, points def voronoi_cells(self): ''' Report polygons of each voronoi cell ''' with self.lock: cells = {} ignore = {} #x:None for x in self._initTriangle} for triangle in self.neighborhood.keys(): for site in triangle: if site in ignore: continue ignore[site] = None triangles, points = self.surrounding_triangles(site, triangle) cell = [] for tri in triangles: cell.append(tri.circumcenter()) cells[site] = cell return cells def voronoi_cell_trinagulation(self, site): ''' Test purpose only ''' with self.lock: triangle = self._find_triangle_by_vertex(site) triangles, points = self.surrounding_triangles(site, triangle) return triangles, triangle def valid(self): for triangle in self.neighborhood.keys(): for other in self.neighborhood.keys(): if (other != triangle): for vertex in other: if not triangle.contains(vertex): if triangle.circumscribe(vertex): self.fail_site = vertex self.fail_triangle = triangle self.fail_witness = other print "Triangle : " + str(triangle) print "Other : " + str(other) print "Other vertex : " + str(vertex) triangle.debug_distance(vertex) return False return True
def setUp(self): self.triangle = Triangle()
def test_if_list_is_empty(self): triangle = [] T = Triangle(triangle) (res) = T.maximumTotal() self.assertEqual(res,False)
class TriangleTest(unittest.TestCase): def setUp(self): path = tempfile.mktemp('.ldb') db = leveldb.LevelDB(path) self.triangle = Triangle(db) def test_it_exists(self): self.assertTrue(self.triangle) def test_insertion(self): wb = mock.Mock() self.triangle.db = mock.Mock() with mock.patch('triangle.leveldb.WriteBatch', return_value=wb): self.triangle.insert(s='Daniel', p='loves', o='Cheese') self.assertEqual( sorted(i[0][0] for i in wb.Put.call_args_list), sorted(['spo::Daniel::loves::Cheese', 'sop::Daniel::Cheese::loves', 'pso::loves::Daniel::Cheese', 'pos::loves::Cheese::Daniel', 'osp::Cheese::Daniel::loves', 'ops::Cheese::loves::Daniel']) ) def test_retreival(self): self.triangle.insert(s='Daniel', p='loves', o='Cheese') self.triangle.insert(s='Daniel', p='loves', o='Sushi') self.assertEqual(set(self.triangle.start(s='Daniel')), { ('Daniel', 'loves', 'Cheese'), ('Daniel', 'loves', 'Sushi') }) self.assertEqual(set(self.triangle.start(o='Sushi')), { ('Daniel', 'loves', 'Sushi') }) def test_retreival_2(self): self.triangle.insert(s='Daniel', p='loves', o='Cheese') self.triangle.insert(s='Daniel', p='loves', o='Sushi') self.assertEqual(set(self.triangle.start(s='Daniel').traverse(o='Cheese')), { ('Daniel', 'loves', 'Cheese'), }) def test_batch_insert(self): with self.triangle.batch_insert() as f: f.insert(s='Daniel', p='loves', o='Cheese') f.insert(s='Daniel', p='loves', o='Sushi') self.assertEqual(set(self.triangle.start(s='Daniel')), { ('Daniel', 'loves', 'Cheese'), ('Daniel', 'loves', 'Sushi') }) def test_exception_rolls_back(self): try: with self.triangle.batch_insert() as f: f.insert(s='Daniel', p='loves', o='Cheese') f.insert(s='Daniel', p='loves', o='Sushi') 0/0 except ZeroDivisionError: pass self.assertEqual(len(set(self.triangle.start(s='Daniel'))), 0) def test_graph_of_the_gods(self): path = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'data/graph_of_the_gods.json' ) with open(path) as f: graph = json.loads(f.read()) vertex_map = {} for v in graph['node']: vertex_map[v['-id']] = v['data'][1]['#text'] + ':' + v['data'][0]['#text'] with self.triangle.batch_insert() as h: for e in graph['edge']: s = vertex_map[e['-source']] o = vertex_map[e['-target']] p = e['-label'] h.insert(s=s, p=p, o=o) # Where do gods live? self.assertEqual( sorted(list(self.triangle.start(s='god').traverse(p='lives'))), sorted([('god:jupiter', 'lives', 'location:sky'), ('god:neptune', 'lives', 'location:sea'), ('god:pluto', 'lives', 'location:tartarus')]) ) # Usually gods live in the sky self.assertEqual( list(self.triangle.start(s='god').traverse(p='lives').traverse(o='location:sky')), [('god:jupiter', 'lives', 'location:sky')] ) result = ( vs(self.triangle.start(s='demigod')) & vs(self.triangle.start(p='mother').traverse(o='human:alcmene')) ) self.assertEqual(result, {'demigod:hercules'})
def _remove(self, site, points, triangles): ''' Update the triangulation by removing the surrounding triangles and then filling this cavity with new Delaunay triangles. Challenge: Maintain neighborhood control. Ref: Mir Abolfazl Mostafavi, Christopher Gold, and Maciej Dakowicz. 2003. Delete and insert operations in Voronoi/Delaunay methods and applications. Comput. Geosci. 29, 4 (May 2003), 523-530. DOI=10.1016/S0098-3004(03)00017-7 http://dx.doi.org/10.1016/S0098-3004(03)00017-7 ''' # verify compatibility of surrounding points and old triangles if len(points) != len(triangles): raise Exception("Triangulation has different sizes.") # verify is the triangulation is empty (or insufficient?) if len(points) < 3: return # initialize new triangulation controls i = -1 new_triangles = {} # while there are points to form more than the last triangle while len(points) > 3: # checks the possible triangles considering # all three consecutive points (i, i1, i2 in a cycle) # of surrounding points of the site i += 1 npoints = len(points) if (i >= npoints): raise Exception("Inexists a valid ear? Is it possible?") i1 = (i + 1) % npoints i2 = (i1 + 1) % npoints # verify if points represent a valid triangle to site, # like a ear listen to the site: # 1: gets triangle orientation (CW or CCW) o_ear = Triangle.orientation(points[i], points[i1], points[i2]) # 2: gets direction of triangle to the site (CW or CCW) o_ear_site = Triangle.orientation(points[i], points[i2], site) # 3: if points are collinear, try another edge as a reference # ??why don't take this edge at first place?? if o_ear_site == 0: o_ear_site = Triangle.orientation(points[i], points[i1], site) # 4: the directions is the same? if (o_ear * o_ear_site) > 0: # if so, this a valid ear (possible triangulation) valid_ear = Triangle(points[i], points[i1], points[i2]) # verify if this ear is a Delaunay Triangulation ear_is_delaunay = True # 1. for all other surrounding points for p in points: # 1.1: is this other point (not in ear)? if not valid_ear.contains(p): # verify if ear won't circumcircle it if valid_ear.circumscribe(p): # if circumcircle, ear is not a Delaunay triangle ear_is_delaunay = False break # if it is a Delaunay triangle... if ear_is_delaunay: # include to new triangle control new_triangles[valid_ear] = None # include to neighborhood control self.neighborhood[valid_ear] = {} # link to the opposite triangles from the removed vertices self._link_ear(site, valid_ear, triangles[i], new_triangles) self._link_ear(site, valid_ear, triangles[i1], new_triangles) # change triangle related to vertex by the new one # remove old triangle by switching the diagonal triangles[i] = valid_ear # remove middle point (leave the corners) del points[i1] del triangles[i1] # restart cycle of surrounding points i = -1 # if has only three neighbours remaining in the surrounding points, # merged these three points (triangles) into last triangulation last_ear = Triangle(points[0], points[1], points[2]) self.neighborhood[last_ear] = {} new_triangles[last_ear] = None # last triangle closes the triangulation and # needs update the link with all sides (neighborhood) self._link_ear(site, last_ear, triangles[0], new_triangles) self._link_ear(site, last_ear, triangles[1], new_triangles) self._link_ear(site, last_ear, triangles[2], new_triangles) if self.main_site is not None: if self.main_site == site: self.main_site = None self._new_version() if self.check_triangulation: if not self.valid(): print "### Removing failure"
""" """ from point import Point from line import Line from triangle import Triangle __author__ = "liuyang" if __name__ == "__main__": points = [] with open("test_case.txt") as f: ps = map(float, filter(str.isdigit, map(str.strip, f.readlines()))) for i in range(0, len(ps), 2): points.append(Point(ps[i], ps[i + 1])) ps = points[9:12] for point in ps: print(point) triangle = Triangle(ps) print(triangle.isTriangle())
def test_maximumTotal_return_true_result(self): triangle = [[6],[3,5],[9,7,1],[4,6,8,4]] T = Triangle(triangle) (val, path) = T.maximumTotal() self.assertEqual(val,26) self.assertEqual(path, [0, 1, 1, 2] )
class App: def __init__(self, master): self.dim = 500 #init vars self.got_edge = 0 #self.move_line = 0 #self.move_oval = 0 self.anistack = deque() self.moveanistack = deque() # create paining area self.canv = Canvas(root, width = self.dim, height = self.dim) self.canv.bind("<Button-1>", self.clicked) self.canv.bind("<B1-Motion>", self.moved) self.canv.bind("<ButtonRelease-1>", self.released) self.canv.pack() self.tri = Triangle([50,70],[300,300],[400,100]) self.tri.id = self.canv.create_polygon(self.tri.coo,fill='yellow') frame = Frame(master) frame.pack() self.button = Button(frame, text="QUIT", fg="red", command=frame.quit) self.button.pack(side=LEFT) self.hi_there = Button(frame, text="Reset", command=self.reset) self.hi_there.pack(side=LEFT) def reset(self): print "reset isn't yet implemented, please just restart :)" def clicked(self, event) : #global xo, yo, got_edge, move_line, move_oval tol = 40 #egde snap tolerance, in sqrt(tol) = radius r = 6 #radius of moving animation #init vars and shortcut self.xo = xo = event.x self.yo = yo = event.y self.p = array([xo,yo]) self.got_edge = 0 tri = self.tri.coo for i in range(3): if (xo-tri[i][0])*(xo-tri[i][0])+(yo-tri[i][1])*(yo-tri[i][1]) < tol: self.got_edge = i+1 #print 'got edge',i # if not clicking on a edge if self.got_edge == 0: isInSide=self.tri.isIn(xo,yo) # collision detection self.ani(xo,yo,isInSide) #move_line = self.canv.create_line(xo, yo, xo, yo) #move_oval = self.canv.create_oval(xo - r, yo - r, xo + r, yo + r) #self.moveanistack.append([move_line, move_oval]) #this is the simplified crossp def cp(self,x,y): return x[0]*y[1]-x[1]*y[0] #collision detection # collision detection moved to triangle class, as for each object different... # def colDet(self,xo,yo): # basic idea: take crossproduct(AP, AC) and crossp(AB, AP) # if they have the same sign, p is inside a cone # do the same with (BP, BA) and (BC, BP) # crossp(A,B) in 2d is simply: Ax*By-Ay*Bx # x,y have same sign <=> x*y>0 use div because of overflowss occuring #create some shortcuts # A=array(self.tri.a) # B=array(self.tri.b) # C=array(self.tri.c) # P=array(self.p) #print self.tri.a, B, C, P #print type(self.tri.a), type(B), type(C), type(P) # if self.cp(P-A,C-A)//self.cp(B-A,P-A)>=0: # if self.cp(P-B,A-B)//self.cp(C-B,P-B)>=0: # return True # return False def moved(self, event) : # coordinates moved to x = event.x y = event.y if self.got_edge == 0:pass #while len(self.moveanistack)>1: # ml, mo = self.moveanistack.popleft() # self.canv.delete(ml) # self.canv.delete(mo) #ml, mo = self.moveanistack.pop() #self.canv.coords(ml,xo,yo,x,y) #self.canv.coords(mo,x - 6, y - 6, x + 6, y + 6) else: self.tri.set_coo([[x,y],self.got_edge-1]) self.canv.delete(self.tri.id) #print '-------------\n',self.tri.coo area = self.tri.getArea() area = area*255//(self.dim*self.dim) if area>255:area=255 #print '-------------\n',area color = "#%02x%02x%02x" % (255, 255-area, 0) self.tri.id = self.canv.create_polygon(self.tri.get_c(),fill=color) self.canv.update() def released(self, event): #if self.got_edge == 0: # while len(self.moveanistack)>0: # ml, mo = self.moveanistack.popleft() # self.canv.delete(ml) # self.canv.delete(mo) self.got_edge = 0 def ani(self,x,y,isOn): #clean up the stack, delete all remaining animation artifacts while len(self.anistack) > 0: self.canv.delete(self.anistack.popleft()) if isOn: color="green" else: color = "red" f = 1 # size factor for i in range(50,0,-1): ani = self.canv.create_oval(x - f*i, y - f*i, x + f*i, y + f*i) self.anistack.append(ani) self.canv.itemconfigure(ani,fill=color) self.canv.update() self.canv.after(5) if len(self.anistack)>0: self.canv.delete(self.anistack.pop())