Skip to content

Instantly share code, notes, and snippets.

@nazfox
Created December 5, 2021 01:02
Show Gist options
  • Save nazfox/238fb038c84e1c163f26e44f36dd222b to your computer and use it in GitHub Desktop.
Save nazfox/238fb038c84e1c163f26e44f36dd222b to your computer and use it in GitHub Desktop.
import colorsys
import math
import random
import cairo
random.seed(10)
WIDTH = 500
HEIGHT = 500
MAX_ITER = 8
LINE_WIDTH = 0.002
LINE_LEN_MIN = 0.01
LINE_LEN_MAX = 0.2
LINE_DECAY = 0.8
ANGLE_SHIFT_MIN = 0.2 * -math.pi
ANGLE_SHIFT_MAX = 0.2 * math.pi
INIT_LENGTH = 0.05
SPLIT_MIN = 2
SPLIT_MAX = 4
mana_prob = 0.1
def draw_line(ctx, x1, y1, x2, y2, rgb, line_width):
ctx.move_to(x1, y1)
ctx.line_to(x2, y2)
ctx.set_source_rgb(rgb[0], rgb[1], rgb[2])
ctx.set_line_width(line_width)
ctx.stroke()
def draw_gem(ctx, x1, y1):
ctx.move_to(x1, y1)
ctx.line_to(x1, y1 - 0.01)
ctx.set_source_rgb(0, 1, 0)
ctx.set_line_width(0.002)
ctx.stroke()
ctx.arc(x1, y1 - 0.01, 0.005, 0, math.pi * 2)
ctx.set_source_rgb(1, 1, 0)
ctx.fill()
def fractal_tree(
ctx, x1, y1, length, rad,
line_len_min=0.0,
line_len_max=1.0,
angle_shift_min=0.2,
angle_shift_max=0.8,
split_min=2,
split_max=4,
iter=10
):
x2 = x1 + math.cos(rad) * length
y2 = y1 + math.sin(rad) * length
draw_line(ctx, x1, y1, x2, y2, (1,1,1), LINE_WIDTH)
num_split = int((split_max - split_min) * random.random() + split_min)
if iter > 0:
for i in range(num_split):
new_len = (line_len_max - line_len_min) * random.random() + line_len_min
new_rad = rad + (angle_shift_max - angle_shift_min) * random.random() + angle_shift_min
fractal_tree(
ctx, x2, y2, new_len, new_rad,
line_len_min=line_len_min * LINE_DECAY,
line_len_max=line_len_max * LINE_DECAY,
angle_shift_min=angle_shift_min,
angle_shift_max=angle_shift_max,
split_min=split_min,
split_max=split_max,
iter=iter-1
)
else:
p = random.random()
if p < mana_prob:
draw_gem(ctx, x2, y2)
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx = cairo.Context(surface)
ctx.scale(WIDTH, HEIGHT)
ctx.translate(0.5, 0.5)
ctx.rotate(math.pi)
ctx.translate(-0.5, -0.5)
x0 = 0.5
y0 = 0
rad = math.pi / 2
fractal_tree(
ctx, x0, y0, INIT_LENGTH, rad,
line_len_min=LINE_LEN_MIN,
line_len_max=LINE_LEN_MAX,
angle_shift_min=ANGLE_SHIFT_MIN,
angle_shift_max=ANGLE_SHIFT_MAX,
split_min=SPLIT_MIN,
split_max=SPLIT_MAX,
iter=MAX_ITER
)
surface.write_to_png('logo.png')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment