Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
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
Esempio n. 6
0
 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))
Esempio n. 7
0
 def test_triangle_position(self):
     t = geometry.Triangle(self.p1, self.p2, self.p3)
     self.assertEqual(t.position(),[self.p1, self.p2, self.p3])