def get_shapes(self, tolerance=8, get_contours=True): """Get the shapes' vertices in the binarized image. Update the *self.triangles* attribute. The shape is obtained using the *Marching Cubes Algorithm*. Once obtained, the vertices are calculated using the *Ramer-Douglas-Peucker Algorithm*. Both are implemented on the *skimage* library, and there is more information on its docs. if the kwarg *get_contours* if False, it is assumed that the contours are already known (stored in variable *self.contours*). If this is the case, the marching cubes algorithm is omitted. :param float tolerance: minimum distance between an observed pixel and the previous vertices pixels required to add the first one to the vertices list. :param bool get_contours: specify if the *Marching Cubes Algorithm* is applied to the binarized image. Specifically set to False when the binarization algorithm is implemented in the external device (i.e. the FPGA). :return: vertices of the N shapes detected on the image. each element contains an Mx2 *np.rray* with the coordinates of the M vertices of the shape. :rtype: list """ logger.debug("Getting the shapes' vertices in the image") # Obtain a list with all the contours in the image, separating each # shape in a different element of the list if get_contours: self.contours = skimage.measure.find_contours(self._binarized, 200) self.triangles = [] # Get the vertices of each shape in the image. for cnt in self.contours: coords = skimage.measure.approximate_polygon(cnt, tolerance) max_coords = np.array(self.image.shape) - 1 # Sometimes, the initial vertex is repeatead at the end. # Thus, if len is 3 and vertex is NOT repeated, it is a triangle if len(coords) == 3 and (not np.array_equal(coords[0], coords[-1])): triangle = geometry.Triangle( np.clip(coords, [0,0], max_coords)) self.triangles.append(triangle) # If len is 4 and vertex IS repeated, it is a triangle if len(coords) == 4 and np.array_equal(coords[0], coords[-1]): triangle = geometry.Triangle(np.clip(coords[1:], [0,0], max_coords)) self.triangles.append(triangle) logger.debug("A {}-vertices shape was found".format(len(coords))) return self.triangles
def update_triangulation(self, trios): """ Update the triangulation for a new arrangement of trios """ pairs = [] # Triangles triangles = {} for trio in trios: trio = tuple(sorted(trio)) triangle = geo.Triangle(self.points, indices=trio, fas=None) triangles[trio] = triangle # Compute the resistors for each side of the triangle for i, pair in enumerate(triangle.pairs): # We do not want to repeat pairs, right? pair = tuple(sorted(pair)) if pair not in pairs: pairs.append(pair) pairs = np.array(pairs) self.pairs = pairs self.triangles = triangles trios = np.sort(trios) self.trios = trios
def main(): """ main function contains only printing methods, and user inputs for choosing action """ shapes = geometry.ShapeList() # object containing all shapes added by the user while True: os.system('clear') print( "LEARN GEOMETRY\n\n" "What do you want to do?\n" "\t(1) Add new shape\n" "\t(2) Show all shapes\n" "\t(3) Show shape with the largest perimeter\n" "\t(4) Show shape with the largest area\n" "\t(5) Show formulas\n" "\t(0) Exit program\n" ) option = input("Select an option: ") if option == "1": os.system('clear') print_list_of_shapes() user_choice = input('Select an option: ') if user_choice == '1': os.system('clear') print('Enter the length of circle radius: ') radius = input_value() circle = geometry.Circle(radius) shapes.add_shape(circle) elif user_choice == '2': os.system('clear') print('Enter length of first side of triangle: ') first_side = input_value() print('Enter length of second side of triangle: ') second_side = input_value() print('Enter length of third side of triangle: ') third_side = input_value() try: triangle = geometry.Triangle(first_side, second_side, third_side) shapes.add_shape(triangle) except ValueError: input("Wrong value. Triangle cant be build with that length of sides {}, {}, {}." .format(first_side, second_side, third_side)) elif user_choice == '3': os.system('clear') print('Enter length of equilateral triangle side:') triangle_side = input_value() equilateral_triangle = geometry.EquilateralTriangle(triangle_side) shapes.add_shape(equilateral_triangle) elif user_choice == '4': os.system('clear') print('Enter length of first side of rectangle: ') first_side_of_rectangle = input_value() print('Enter length of secound side of rectangle: ') second_side_of_rectangle = input_value() rectangle = geometry.Rectangle(first_side_of_rectangle, second_side_of_rectangle) shapes.add_shape(rectangle) elif user_choice == '5': os.system('clear') print('Enter length of side of square: ') square_side = input_value() square = geometry.Square(square_side) shapes.add_shape(square) elif user_choice == '6': os.system('clear') print('Enter length of side of regular pentagon: ') pentagon_side = input_value() pentagon = geometry.RegularPentagon(pentagon_side) shapes.add_shape(pentagon) elif user_choice == '0': main() else: raise ValueError("Wrong input") elif option == "2": os.system('clear') if len(shapes.shapes) == 0: input('First add some shapes!\n\n Enter to back to menu') else: print(shapes.get_shapes_table()) input('\nEnter = main menu') elif option == "3": os.system('clear') if len(shapes.shapes) == 0: input('First add some shapes! \n Enter to back to menu') else: print('Shape with the largest perimeter:\n' + str(shapes.get_largest_shape_by_perimeter()) + '\tperimeter:', round(shapes.get_largest_shape_by_perimeter().get_perimeter(), 1)) input('\nEnter to back to menu') elif option == "4": os.system('clear') if len(shapes.shapes) == 0: input('First add some shapes! \n Enter to back menu') else: print('Shape with the largest area:\n' + str(shapes.get_largest_shape_by_area()) + '\tarea:', round(shapes.get_largest_shape_by_area().get_area(), 1)) input('\nEnter to back to menu') elif option == "5": os.system('clear') print_list_of_shapes() show_formulas = input("Enter number to get a shape formulas: ") if show_formulas == '1': shape = 'Circle' area = geometry.Circle.get_area_formula() perimeter = geometry.Circle.get_perimeter_formula() elif show_formulas == '2': shape = 'Triangle' area = geometry.Triangle.get_area_formula() perimeter = geometry.Triangle.get_perimeter_formula() elif show_formulas == '3': shape = 'Equilateral Triangle' area = geometry.EquilateralTriangle.get_area_formula() perimeter = geometry.Triangle.get_perimeter_formula() elif show_formulas == '4': shape = 'Rectangle' area = geometry.Rectangle.get_area_formula() perimeter = geometry.Rectangle.get_perimeter_formula() elif show_formulas == '5': shape = 'Square' area = geometry.Square.get_area_formula() perimeter = geometry.Square.get_perimeter_formula() elif show_formulas == '6': shape = 'Regular Pentagon' area = geometry.RegularPentagon.get_area_formula() perimeter = geometry.RegularPentagon.get_perimeter_formula() elif show_formulas == '0': main() os.system('clear') print('\n{}\n\nFormulas:\nArea: {}\nPerimeter: {}'.format(shape, area, perimeter)) input('\nEnter to back to menu') elif option == "0": sys.exit()
def read(self, filename, model, params): input_file = open(filename, 'r') triangle = geometry.Triangle() materials = [] while True: line = input_file.readline() # eof if len(line) == 0: break # comments are ignored if line[0] == '#': continue # remove eol if line[len(line) - 1] == '\n': line = line[:len(line) - 1] values = line.split(' ') cmd = values[0] if cmd == 'version': model.version = int(values[1]) elif cmd == 'triangles': continue elif cmd == 'p1': triangle.vertices[0] = parse_vertex(values) elif cmd == 'p2': triangle.vertices[1] = parse_vertex(values) elif cmd == 'p3': triangle.vertices[2] = parse_vertex(values) elif cmd == 'mat': triangle.material = parse_material(values) elif cmd == 'tex1': triangle.material.texture = values[1] elif cmd == 'tex2': triangle.material.texture2 = values[1] elif cmd == 'var_tex2': continue elif cmd == 'lod_level': triangle.material.lod = int(values[1]) elif cmd == 'state': triangle.material.state = int(values[1]) mat_final = None for mat in materials: if triangle.material == mat: mat_final = mat if mat_final is None: mat_final = triangle.material materials.append(mat_final) triangle.material = mat_final model.triangles.append(triangle) triangle = geometry.Triangle() input_file.close() return True
def read(self, filename, model, params): input_file = open(filename, 'rb') # read header version_major = struct.unpack('=i', input_file.read(4))[0] version_minor = struct.unpack('=i', input_file.read(4))[0] triangle_count = struct.unpack('=i', input_file.read(4))[0] if version_major != 1 or version_minor != 2: print('Unsupported format version: {}.{}'.format( version_major, version_minor)) return False # read and ignore padding input_file.read(40) materials = [] for index in range(triangle_count): triangle = geometry.Triangle() # used, selected, 2 byte padding input_file.read(4) for vertex in triangle.vertices: # position, normal, uvs floats = struct.unpack('=ffffffffff', input_file.read(40)) vertex.x = floats[0] vertex.y = floats[1] vertex.z = floats[2] vertex.nx = floats[3] vertex.ny = floats[4] vertex.nz = floats[5] vertex.u1 = floats[6] vertex.v1 = floats[7] vertex.u2 = floats[8] vertex.v2 = floats[9] # material colors floats = struct.unpack('=fffffffffffffffff', input_file.read(17 * 4)) mat = triangle.material for i in range(4): mat.diffuse[i] = floats[0 + i] mat.ambient[i] = floats[4 + i] mat.specular[i] = floats[8 + i] # texture name chars = input_file.read(20) for i in range(20): if chars[i] == '\0': mat.texture = struct.unpack('={}s'.format(i), chars[:i])[0] break values = struct.unpack('=ffiHHHH', input_file.read(20)) mat.state = values[2] dirt = values[3] if dirt != 0: mat.texture2 = 'dirty{:02d}.png'.format(dirt) # optimizing materials replaced = False for material in materials: if mat == material: triangle.material = material replaced = True break if not replaced: materials.append(mat) model.triangles.append(triangle) # end of triangle input_file.close() return True
def test_triangle_perimetre(self): t = geometry.Triangle(self.p1, self.p2, self.p3) self.assertEqual(t.perimetre(),self.p1.distance(self.p2) + self.p1.distance(self.p3) + self.p2.distance(self.p3))
def test_triangle_position(self): t = geometry.Triangle(self.p1, self.p2, self.p3) self.assertEqual(t.position(),[self.p1, self.p2, self.p3])