Пример #1
0
def line(ctx, y, line_interval, color, x_increment=(IMG_WIDTH // 40)):
    line_width = line_interval // 20
    x = 0
    ctx.move_to(x, y)
    nodes = []
    while x < IMG_WIDTH:
        x += random.randint(x_increment // 2, x_increment)
        y_offset = random.randint(0, line_interval // 2 - SPACING)
        y_offset = y_offset if random.random() < 0.5 else -1 * y_offset
        nodes.append((x, y + y_offset))
        ctx.line_to(x, y + y_offset)
    ctx.set_source_rgb(*color)
    ctx.set_line_width(line_width)
    ctx.stroke()
    for node in nodes:
        (node_x, node_y) = node
        r = random.randint(line_width * 2, line_width * 4)
        ctx.arc(node_x, node_y, r, 0, 2 * math.pi)
        ctx.set_source_rgb(*color)
        ctx.fill()
        # Ring around the node
        ctx.arc(node_x, node_y, r, 0, 2 * math.pi)
        ctx.set_source_rgb(*random.choice(colors.shades(color, 5)))
        ctx.set_line_width(line_width)
        ctx.stroke()
Пример #2
0
def pyramid(ctx, x, y, width, height, color, random_center=True):
    if random_center:
        center = (random.randint(x + 3, x + width - 3),
                  random.randint(y + 3, y + height - 3))
    else:
        center = (x + width // 2, y + height // 2)
    tl = (x, y)
    tr = (x + width, y)
    bl = (x, y + height)
    br = (x + width, y + height)
    cols = colors.shades(color, 5)
    triangle(ctx, tl, tr, center, cols[0])
    triangle(ctx, tr, br, center, cols[1])
    triangle(ctx, br, bl, center, cols[2])
    triangle(ctx, bl, tl, center, cols[3])
Пример #3
0
def draw_line(ctx, x, y, x2, y2, line_width, color):
    def draw_it(width, col):
        ctx.move_to(x, y)
        ctx.line_to(x2, y2)

        ctx.set_line_width(width)
        ctx.set_line_cap(cairo.LineCap.ROUND)
        ctx.set_source_rgb(*col)
        ctx.stroke()

    outline_col = colors.shades(color, 3)[-2]
    outline_width = max(2, line_width / 8)

    # Draw slightly thicker "outline" first, then thinner "inner" line
    draw_it(line_width, outline_col)
    draw_it(line_width - outline_width, color)
Пример #4
0
def sphere(ctx,
           color,
           img_width,
           img_height,
           existing_shapes,
           min_radius=10,
           max_attempts=100):
    def getStartXY():
        x = random.randint(min_radius, img_width - min_radius)
        y = random.randint(min_radius, img_height - min_radius)
        return (x, y)

    # 1. Get a start point that doesn't overlap with anything we already have.
    (start_x, start_y) = getStartXY()
    sphere = Point(start_x, start_y).buffer(min_radius, resolution=8)
    for _ in range(max_attempts * 100):
        if not existing_shapes.intersects(sphere):
            break
        (start_x, start_y) = getStartXY()
        sphere = Point(start_x, start_y).buffer(min_radius, resolution=8)
    # For the rare case that we did not find a working point.
    if existing_shapes.intersects(sphere):
        print("Could not find valid start point!")
        return existing_shapes

    # 2. Grow the sphere as far as possible, randomly.
    failed_attempts = 0
    max_increment = 500
    radius = min_radius
    while failed_attempts < max_attempts:
        new_radius = radius + max_increment
        new_sphere = Point(start_x, start_y).buffer(new_radius, resolution=12)
        if not existing_shapes.intersects(new_sphere) and within_canvas(
                start_x, start_y, img_width, img_height, new_radius):
            radius = new_radius
            sphere = new_sphere
        else:
            failed_attempts += 1
            max_increment = int(max_increment * 3 / 4)
            if max_increment < 1:
                break

    # 3. Draw the sphere
    color_t = palettes.hex_to_tuple(color)
    tints = colors.tints(color_t, 5)
    shades = colors.shades(color_t, 3)

    ctx.arc(start_x, start_y, radius, 0, 2 * math.pi)

    gradient = cairo.RadialGradient(start_x - (1 / 2) * radius,
                                    start_y + (1 / 2) * radius, 0,
                                    start_x - (1 / 4) * radius,
                                    start_y + (1 / 4) * radius,
                                    radius * (5 / 4))
    gradient.add_color_stop_rgb(0, 1, 1, 1)
    gradient.add_color_stop_rgb(0.9, *tints[-1])
    gradient.add_color_stop_rgb(1, *shades[-1])
    ctx.set_source(gradient)
    ctx.fill()

    buffered_sphere = Point(start_x, start_y).buffer(radius + 5, resolution=12)
    return existing_shapes.union(buffered_sphere)
Пример #5
0
def bar(ctx,
        color,
        line_width,
        img_width,
        img_height,
        existing_shapes,
        max_attempts=100):
    def getStartXY():
        x = random.randint(line_width, img_width - line_width)
        y = random.randint(line_width, img_height - line_width)
        return (x, y)

    # 1. Get a start point that doesn't overlap with anything we already have.
    (start_x, start_y) = getStartXY()
    startPoint = Point(start_x, start_y).buffer(line_width // 2, resolution=8)
    for _ in range(max_attempts * 100):
        if not existing_shapes.intersects(startPoint):
            break
        (start_x, start_y) = getStartXY()
        startPoint = Point(start_x, start_y).buffer(line_width // 2,
                                                    resolution=8)
    # For the rare case that we did not find a working point.
    if existing_shapes.intersects(startPoint):
        print("Could not find valid start point!")
        return existing_shapes

    end_x = start_x
    end_y = start_y
    bar = LineString([(start_x, start_y),
                      (start_x, start_y)]).buffer(line_width)

    # 2. Grow the bar as far as possible, randomly.
    failed_attempts = 0
    max_increment = 500
    while failed_attempts < max_attempts:
        new_end_x = end_x
        new_end_y = end_y
        increment = random.randint(1, max_increment)
        if random.random() < 0.5:
            increment = -1 * increment
        if random.random() < 0.5:
            new_end_x += increment
        else:
            new_end_y += increment
        new_bar = LineString([(start_x, start_y),
                              (new_end_x, new_end_y)]).buffer(line_width)
        if not existing_shapes.intersects(new_bar) and within_canvas(
                new_end_x, new_end_y, img_width, img_height, line_width):
            end_x = new_end_x
            end_y = new_end_y
            bar = new_bar
        else:
            failed_attempts += 1
            max_increment = int(max_increment * 3 / 4)
            if max_increment < 1:
                break

    if end_x == start_x and end_y == start_y:
        print("Couldn't grow bar")
        return existing_shapes

    # 3. Draw the bar
    color_t = palettes.hex_to_tuple(color)
    tints = colors.tints(color_t, 5)
    shades = colors.shades(color_t, 3)

    ctx.move_to(start_x, start_y)
    ctx.line_to(end_x, end_y)
    ctx.set_line_width(line_width)
    ctx.set_line_cap(cairo.LineCap.ROUND)

    # Compute vector for highlight vector
    dx = end_x - start_x
    dy = end_y - start_y
    length = math.sqrt(pow(end_x - start_x, 2) + pow(end_y - start_y, 2))
    # Center point of the bar
    center_x = start_x + (dx / 2)
    center_y = start_y + (dy / 2)
    # Start and end of highlight vector -- perpendicular to bar
    grad_start_x = (center_x + (dy / length) * line_width / 2)
    grad_start_y = (center_y + (-1) * (dx / length) * line_width / 2)
    grad_end_x = (center_x + (-1) * (dy / length) * (line_width / 2))
    grad_end_y = (center_y + (dx / length) * (line_width / 2))

    gradient = cairo.LinearGradient(grad_start_x, grad_start_y, grad_end_x,
                                    grad_end_y)
    gradient.add_color_stop_rgb(0, *shades[-2])
    gradient.add_color_stop_rgb(0.7, *tints[-1])
    gradient.add_color_stop_rgb(0.7, *tints[-1])
    gradient.add_color_stop_rgb(0.75, 1, 1, 1)
    gradient.add_color_stop_rgb(0.75, 1, 1, 1)
    gradient.add_color_stop_rgb(0.8, *tints[-1])
    gradient.add_color_stop_rgb(1, *shades[-1])
    ctx.set_source(gradient)
    ctx.stroke()

    return existing_shapes.union(bar)