def draw_square_blackhole():
    img = SVGImage(1000,
                   800,
                   center_origin=True,
                   show_borders_and_origin=False,
                   animate=False,
                   animation_speed=0.01)

    o = [[-200, -200, 200, -200], [200, -200, 200, 200], [200, 200, -200, 200],
         [-200, 200, -200, -200]]
    angle = 10
    sx = 1.1
    sy = 0.8
    origin = [0, 0]
    iterations = 60

    for _ in range(iterations):
        for i, line in enumerate(o):
            x1, y1, x2, y2 = line
            img.add_line(x1, y1, x2, y2, width=2)
            x1, y1 = rotate((x1, y1), angle, origin)
            x2, y2 = rotate((x2, y2), angle, origin)
            x1, y1 = scale((x1, y1), sx, sy)
            x2, y2 = scale((x2, y2), sx, sy)
            o[i] = [x1, y1, x2, y2]
    img.save("img/square_blackhole.svg")
def draw_square_snail():
    img = SVGImage(1000,
                   800,
                   center_origin=True,
                   show_borders_and_origin=False,
                   animate=False,
                   animation_speed=0.01)

    o = [[0, 0, 10, 0], [10, 0, 10, 10], [10, 10, 0, 10], [0, 10, 0, 0]]
    angle = 25
    sx = 1.1
    sy = 1.1
    tx = 1
    ty = 2
    origin = [0, 0]
    iterations = 37

    for _ in range(iterations):
        for i, line in enumerate(o):
            x1, y1, x2, y2 = line
            img.add_line(x1, y1, x2, y2, width=2)
            x1, y1 = rotate((x1, y1), angle, origin)
            x2, y2 = rotate((x2, y2), angle, origin)
            x1, y1 = scale((x1, y1), sx, sy)
            x2, y2 = scale((x2, y2), sx, sy)
            x1, y1 = translate((x1, y1), tx, ty)
            x2, y2 = translate((x2, y2), tx, ty)
            o[i] = [x1, y1, x2, y2]
    img.save("img/square_snail.svg")
def draw_square_shaered():
    img = SVGImage(1200,
                   400,
                   center_origin=True,
                   show_borders_and_origin=False,
                   animate=False,
                   animation_speed=0.01)

    o = [[-50, -50, 50, -50], [50, -50, 50, 50], [50, 50, -50, 50],
         [-50, 50, -50, -50]]
    angle = -10
    sx = 0.9
    sy = 0.9
    sh = 1.3
    tx = 50
    ty = 50
    origin = [0, 0]
    iterations = 40

    for _ in range(iterations):
        for i, line in enumerate(o):
            x1, y1, x2, y2 = line
            img.add_line(x1, y1, x2, y2, width=2)
            x1, y1 = shear((x1, y1), sh)
            x2, y2 = shear((x2, y2), sh)
            x1, y1 = rotate((x1, y1), angle, origin)
            x2, y2 = rotate((x2, y2), angle, origin)
            x1, y1 = scale((x1, y1), sx, sy)
            x2, y2 = scale((x2, y2), sx, sy)
            x1, y1 = translate((x1, y1), tx, ty)
            x2, y2 = translate((x2, y2), tx, ty)
            o[i] = [x1, y1, x2, y2]
    img.save("img/square_sheared.svg")
def pentagram_absolute():
    img = SVGImage(center_origin=True,
                   show_borders_and_origin=False,
                   animate=True,
                   animation_speed=0.5)

    def draw_polygon_pentagram_absolute(img, line_width=1):
        n = 5
        center_to_side = 200
        center_angle = 360 / n
        offset_angle = 90 - center_angle

        x = 0
        y = 0
        points = [(x, y)]
        ## Draw polygon
        for i in range(1, n + 2):
            nx = math.cos(
                math.radians(i * center_angle + offset_angle)) * center_to_side
            ny = math.sin(
                math.radians(i * center_angle + offset_angle)) * center_to_side
            points.append((nx, ny))
            if i != 1:
                img.add_line(x, y, nx, ny, width=line_width)
            x = nx
            y = ny
        # remove center and last duplicate
        points = points[1:-1]

        ## draw pentagram
        last = 0
        for _ in range(n):
            point_1 = points[last]
            point_2 = points[(last + 2) % n]
            last = (last + 2) % n
            img.add_line(point_1[0],
                         point_1[1],
                         point_2[0],
                         point_2[1],
                         width=line_width)

    draw_polygon_pentagram_absolute(img, 5)
    img.save("img/pentagram_absolute_animated.svg")
Example #5
0
def draw_lines_and_intersects():
    img = SVGImage(IMG_WIDTH, IMG_HEIGHT, center_origin=False, show_borders_and_origin=False, animate=False, animation_speed=ANIMATION_SPEED)
    lines = []

    ## draw lines
    for i in range(LINE_COUNT):
        line = get_random_line(LINE_LENGTH)
        lines.append(line)
        img.add_line(*line, width=LINE_WIDTH)

    ## draw intersections
    for line in lines:
        for i in lines:
            if line == i:
                continue
            if intersect(line, i):
                px, py = get_intersect(line, i)
                img.add_circle(px, py, INTERSECT_RADIUS, color="black", fill="red")

    img.save("img/line_intersections.svg")
Example #6
0
def draw_star():
    def draw_star_part(y1, y1_step, x2_step, x2_is_negative=False):
        x2 = 0
        while x2 <= HEIGHT:
            img.add_line(0, y1, -x2 if x2_is_negative else x2, 0)
            y1 += y1_step
            x2 += x2_step

    img = SVGImage(W,
                   H,
                   center_origin=True,
                   show_borders_and_origin=False,
                   animate=False,
                   animation_speed=0.01)
    draw_star_part(HEIGHT, -4, 4)
    draw_star_part(HEIGHT, -8, 8, x2_is_negative=True)
    draw_star_part(-HEIGHT, 16, 16, x2_is_negative=True)
    draw_star_part(-HEIGHT, 32, 32)

    img.save("img/test_svg_star.svg")
Example #7
0
def draw_rectangle():
    # non-abstracted code for rectangle
    rect_img = SVGImage(W,
                        H,
                        center_origin=True,
                        show_borders_and_origin=False,
                        animate=False,
                        animation_speed=0.05)

    x1 = -HEIGHT
    y2 = HEIGHT
    while x1 <= HEIGHT:
        rect_img.add_line(x1, HEIGHT, HEIGHT, y2)
        x1 += 8
        y2 -= 8

    x1 = HEIGHT
    y2 = HEIGHT
    while -x1 <= HEIGHT:
        rect_img.add_line(x1, HEIGHT, -HEIGHT, y2)
        x1 -= 13
        y2 -= 13

    x1 = -HEIGHT
    y2 = HEIGHT
    while x1 <= HEIGHT:
        rect_img.add_line(x1, -HEIGHT, -HEIGHT, y2)
        x1 += 21
        y2 -= 21

    x1 = -HEIGHT
    y2 = -HEIGHT
    while x1 <= HEIGHT:
        rect_img.add_line(x1, -HEIGHT, HEIGHT, y2)
        x1 += 34
        y2 += 34

    rect_img.save("img/test_svg_rect.svg")
Example #8
0
def draw_maze(filename,
              maze_side,
              missing_walls,
              show_start_end=True,
              animate=False,
              img_size=500,
              line_width=2):
    """ Draws maze into svg image.
    Checks if there should not be missing wall in @missing_walls.
    """
    size = img_size
    width = line_width
    img = SVGImage(size,
                   size,
                   center_origin=False,
                   show_borders_and_origin=False,
                   animate=animate,
                   animation_speed=0.05)

    # draw borders
    img.add_line(0, 0, 0, size, width=2 * width)
    img.add_line(0, size, size, size, width=2 * width)
    img.add_line(size, size, size, 0, width=2 * width)
    img.add_line(size, 0, 0, 0, width=2 * width)

    # draw start and end
    # start is always upper-top and end always bottom-right
    if show_start_end:
        img.add_circle(size / maze_side / 2,
                       size / maze_side / 2,
                       size / maze_side / 4,
                       fill="green")
        img.add_circle(maze_side * (size / maze_side) - (size / maze_side / 2),
                       maze_side * (size / maze_side) - (size / maze_side / 2),
                       size / maze_side / 4,
                       fill="red")

    # draw vertical walls
    for row in range(maze_side):
        for col in range(maze_side - 1):
            current_wall = ((row, col), (row, col + 1))
            if current_wall in missing_walls or current_wall[::
                                                             -1] in missing_walls:
                continue
            x0 = (col + 1) * (size / maze_side)
            y0 = row * (size / maze_side)
            x1 = x0
            y1 = (row + 1) * (size / maze_side)
            img.add_line(x0, y0, x1, y1, width=width)

    # draw horizontal walls
    for row in range(maze_side - 1):
        for col in range(maze_side):
            current_wall = ((row, col), (row + 1, col))
            if current_wall in missing_walls or current_wall[::
                                                             -1] in missing_walls:
                continue
            x0 = col * (size / maze_side)
            y0 = (row + 1) * (size / maze_side)
            x1 = (col + 1) * (size / maze_side)
            y1 = y0
            img.add_line(x0, y0, x1, y1, width=width)
    img.save(filename)
Example #9
0
class Turtle(object):
    def __init__(self,
                 width=800,
                 height=600,
                 center_origin=False,
                 show_borders_and_origin=False,
                 animate=False,
                 animation_speed=0.1):
        self.img = SVGImage(width,
                            height,
                            center_origin=center_origin,
                            show_borders_and_origin=show_borders_and_origin,
                            animate=animate,
                            animation_speed=animation_speed)
        # current turtle state
        self.x = 0
        self.y = 0
        # angle in degrees
        self.angle = 0
        self.is_pendown = True

    def save(self, path):
        self.img.save(path)

    def reset(self):
        self.x = 0
        self.y = 0
        self.angle = 0

    def reset_angle(self):
        self.angle = 0

    def set_x(self, x):
        self.x = x

    def set_y(self, y):
        self.y = y

    def set_angle(self, angle):
        self.angle = angle

    def get_x(self):
        return self.x

    def get_y(self):
        return self.y

    def get_angle(self):
        return self.angle

    def forward(self, steps, color="black", width=1, debug=False):
        """ steps: in pixels
        """
        print(self.x, self.y, self.angle) if debug else None
        nx = self.x + math.cos(math.radians(self.angle)) * steps
        ny = self.y + math.sin(math.radians(self.angle)) * steps
        if self.is_pendown:
            self.img.add_line(self.x, self.y, nx, ny, color=color, width=width)
        self.x = nx
        self.y = ny
        print(self.x, self.y, self.angle) if debug else None

    def back(self, steps, color="black", width=1, debug=False):
        """ steps: in pixels
        """
        print(self.x, self.y, self.angle) if debug else None
        self.forward(-steps, color=color, width=width)
        print(self.x, self.y, self.angle) if debug else None

    def right(self, angle):
        """ angle: in degrees
        """
        self.angle -= angle

    def left(self, angle):
        """ angle: in degrees
        """
        self.angle += angle

    def penup(self):
        """ stop drawing
        """
        self.is_pendown = False

    def pendown(self):
        """ start drawing
        """
        self.is_pendown = True
Example #10
0
def draw_convex_hull():
    def generate_points(number):
        points = []
        for _ in range(number):
            x = get_random_number(BUFFER, IMG_WIDTH - BUFFER)
            y = get_random_number(BUFFER, IMG_HEIGHT - BUFFER)
            points.append((x, y))
        return points

    def get_lines(points):
        if len(points) < 1:
            return []
        ## final lines to be drawn
        lines = []

        ## get the leftmost and rightmost point
        first = points[0]
        last = points[0]
        for point in points:
            if point[0] < first[0]:
                first = point
            if point[0] > last[0]:
                last = point

        point1 = first
        direction = "right"
        while True:
            candidate = None
            candidate_angle = 360
            for point2 in points:
                if point1 == point2:
                    continue
                angle = get_angle(point1, point2, direction)

                if angle <= candidate_angle:
                    candidate = point2
                    candidate_angle = angle
            lines.append(candidate + point1)
            point1 = candidate
            if candidate == last and direction == "right":
                direction = "left"
            if candidate == first and direction == "left":
                break
        return lines

    def draw_points(points):
        for point in points:
            img.add_circle(point[0],
                           point[1],
                           POINTS_RADIUS,
                           color="black",
                           fill="red")

    def draw_lines(lines):
        for line in lines:
            img.add_line(*line, width=LINE_WIDTH)

    ## Draw the stuff
    img = SVGImage(IMG_WIDTH,
                   IMG_HEIGHT,
                   center_origin=False,
                   show_borders_and_origin=False,
                   animate=True,
                   animation_speed=ANIMATION_SPEED)

    points = generate_points(POINTS_NUM)
    draw_points(points)
    print(points)

    while len(points) > 0:
        lines = get_lines(points)
        draw_lines(lines)

        ## remove used points
        for line in lines:
            x1, y1, _, _ = line
            print(line)
            points.remove((x1, y1))
            print(points)

    img.save("img/convex_hull_concentric_animate.svg")
Example #11
0
def draw_maze(img_file,
              no_wallss,
              img_size=400,
              animate=True,
              levels=4,
              side_length=50):
    """ Draws maze.
    """
    def draw_triangle(img,
                      x=0,
                      y=0,
                      side_length=50,
                      drop_ab=False,
                      drop_bc=False,
                      drop_ca=False):
        """ Draws triangle with side @side_length.
        Bottom left corner is at the @x,@y coordinates.
        Able to not draw specific side of triangle by setting @drop_* to True.
        """
        ax = x
        ay = y
        bx = x + side_length
        by = y
        cx = x + side_length / 2
        cy = y - (math.sqrt(3) / 2) * side_length
        if not drop_ab:
            img.add_line(ax, ay, bx, by)
        if not drop_bc:
            img.add_line(bx, by, cx, cy)
        if not drop_ca:
            img.add_line(cx, cy, ax, ay)

    img = SVGImage(img_size,
                   img_size,
                   center_origin=False,
                   show_borders_and_origin=False,
                   animate=animate,
                   animation_speed=0.05)
    x = img_size / 2 - side_length / 2
    y = (math.sqrt(3) / 2) * side_length

    current_node_id = 1  # node id of the triangle we are drawing

    for level in range(levels + 1):
        current_x = x
        for triangle in range(level + 1):
            # draw only walls that are not in @no_walls
            drop_ab, drop_bc, drop_ca = False, False, False
            for wall in no_walls:
                node_id, neighbor_id = wall
                if node_id == current_node_id:
                    if node_id == neighbor_id + 1:
                        # dropping wall to the left (ac)
                        drop_ca = True
                    if node_id == neighbor_id - 1:
                        # dropping wall to the right (bc)
                        drop_bc = True
                    if node_id + 1 < neighbor_id:
                        # dropping wall to the bottom (ab)
                        drop_ab = True
            draw_triangle(img,
                          x=current_x,
                          y=y,
                          side_length=side_length,
                          drop_ab=drop_ab,
                          drop_bc=drop_bc,
                          drop_ca=drop_ca)
            current_x += side_length
            if triangle < level:
                current_node_id += 2
        x -= side_length / 2
        y += (math.sqrt(3) / 2) * side_length
        current_node_id += 1

    img.save(img_file)
Example #12
0
def draw_triangulation():
    img = SVGImage(IMG_WIDTH,
                   IMG_HEIGHT,
                   center_origin=False,
                   show_borders_and_origin=True,
                   animate=True,
                   animation_speed=ANIMATION_SPEED)

    def generate_points(number):
        points = []
        for i in range(number):
            x = get_random_number(BUFFER, IMG_WIDTH - BUFFER)
            y = get_random_number(BUFFER, IMG_HEIGHT - BUFFER)
            points.append((x, y))
        return points

    points = generate_points(POINTS_NUM)
    #points = [(200, 200), (400, 150), (500, 400), (450, 700), (300, 600)]
    #points = [(200, 200), (400, 150), (500, 400), (450, 700)]
    #points = [(341, 518), (653, 605), (363, 476), (676, 308)]

    print(points)

    def shorten_line(line, step=10):
        x1, y1, x2, y2 = list(line)
        if x2 > x1:
            x = x2 - x1
            x1 += x / step
            x2 -= x / step
        else:
            x = x1 - x2
            x1 -= x / step
            x2 += x / step
        if y2 > y1:
            y = y2 - y1
            y1 += y / step
            y2 -= y / step
        else:
            y = y1 - y2
            y1 -= y / step
            y2 += y / step
        return (x1, y1, x2, y2)

    def intersect_some_collected(line, collected):
        for i in collected:
            a = shorten_line(i)
            b = shorten_line(line)

            if intersect(a, b):
                print("III", line, i)
                return True
        return False

    def get_lines(points):
        collected = []
        for point1 in points:
            for point2 in points:
                if point1 == point2:
                    continue
                if point1 + point2 in collected:
                    continue
                if point2 + point1 in collected:
                    continue
                line = point1 + point2

                if not intersect_some_collected(line, collected):
                    collected.append(line)
                print(collected)
        return collected

    lines = get_lines(points)
    """
    lines = [ (200, 200, 450, 700)]
    x = (300, 600, 400, 150)
    print(intersect_some_collected(x, lines))
    print(intersect(lines[0], x))
    img.add_line(*x, width=LINE_WIDTH*4)
    img.add_circle(330.7692307692308, 461.53846153846155, POINTS_RADIUS, fill="red")
    """

    ## draw points
    for point in points:
        img.add_circle(point[0],
                       point[1],
                       POINTS_RADIUS,
                       color="black",
                       fill="red")

    ## draw lines
    for line in lines:
        img.add_line(*line, width=LINE_WIDTH)

    img.save("img/triangulation_animate.svg")
Example #13
0
group_set.append(init_group)
sx = 0.9
sy = 0.9
iterations = 30

pp(group_set)
for _ in range(iterations):
    new_group_set = []
    while len(group_set) > 0:
        group = group_set.pop()
        new_group = []
        for item in group:
            new_item = {"lines": [], "attractor": None}
            for line in item["lines"]:
                img.add_line(*line)
                x1, y1, x2, y2 = line
                # TODO: second retangle is scaling by different point
                x1, y1 = lingebra.scale((x1, y1), sx, sy, item["attractor"])
                x2, y2 = lingebra.scale((x2, y2), sx, sy, item["attractor"])
                new_line = [x1, y1, x2, y2]
                new_item["lines"].append(new_line) ## set the new lines
            new_item["attractor"] = item["attractor"] ## keep the original attractor
            new_group.append(new_item)
        new_group_set.append(new_group)
    group_set = new_group_set
pp(group_set)



img.save("img/mrcm_test.svg")