gui
Felix Pankratz 3 years ago
parent eedf8e7ac5
commit 3a31879d70

@ -10,19 +10,23 @@ WIDTH, HEIGHT = 1000, 1000
ANGLE_RANDOM_MIN = -0.6 ANGLE_RANDOM_MIN = -0.6
ANGLE_RANDOM_MAX = 0.6 ANGLE_RANDOM_MAX = 0.6
# how much to shrink each consecutive circle # how much to shrink each consecutive circle
SHRINK = 0.00004 SHRINK = 0.00002
class Branch(): class Branch():
def __init__(self, idx, ctx, x, y, r, ang): def __init__(self, idx, ctx, x, y, r, ang):
ctx.set_source_rgb(255, 0, 0) #ctx.set_source_rgb(255, 0, 0)
self.nodes = [Node(ctx, x, y, r, ang, dry=True)] self.nodes = [Node(ctx, x, y, r, ang, dry=True)]
ctx.set_source_rgb(0,0, 0) #ctx.set_source_rgb(0,0, 0)
self.idx = idx self.idx = idx
self.ctx = ctx self.ctx = ctx
self.ended = False self.ended = False
self.ignores = []
self.first = True
def _last_node(self): def _last_node(self):
return self.nodes[-1] return self.nodes[-1]
def set_ignores(self, ignores):
self.ignores = ignores
def place_next(self, branches): def place_next(self, branches):
if not self.ended: if not self.ended:
last = self._last_node() last = self._last_node()
@ -34,7 +38,8 @@ class Branch():
self.ended = True self.ended = True
return False return False
# did we hit canvas edge? # did we hit canvas edge?
if next_x + next_r > 1 or next_x - next_r < 0: # if next_x + next_r > 1 or next_x - next_r < 0:
if (math.pow(next_x - 0.5, 2) + math.pow(next_y - 0.5, 2)) > math.pow(0.4, 2):
self.ended = True self.ended = True
return False return False
if next_y + next_r > 1 or next_y - next_r < 0: if next_y + next_r > 1 or next_y - next_r < 0:
@ -44,14 +49,18 @@ class Branch():
# did we hit another circle? # did we hit another circle?
for branch in branches: for branch in branches:
for node in branch.nodes: for node in branch.nodes:
if node not in last_nodes: #!= last and node != self.nodes[-2]: if node not in last_nodes and node not in self.ignores: #!= last and node != self.nodes[-2]:
if circles_intersect(node.x, node.y, node.r, if circles_intersect(node.x, node.y, node.r,
next_x, next_y, next_r): next_x, next_y, next_r):
self.ended = True self.ended = True
return False return False
next_ang = last.ang + random.uniform(ANGLE_RANDOM_MIN, ANGLE_RANDOM_MAX) next_ang = last.ang + (random.uniform(ANGLE_RANDOM_MIN, ANGLE_RANDOM_MAX) * (1 - 40*last.r))
self.nodes.append(Node(self.ctx, next_x, next_y, next_r, next_ang)) self.nodes.append(Node(self.ctx, next_x, next_y, next_r, next_ang))
if self.first:
self.first = False
first = self.nodes[0]
circle_fill(self.ctx, first.x, first.y, first.r)
return True return True
def circles_intersect(x1, y1, r1, x2, y2, r2): def circles_intersect(x1, y1, r1, x2, y2, r2):
@ -72,31 +81,35 @@ class Node():
return self.x != other.x or self.y != other.y or self.r != other.r or self.ang != other.ang return self.x != other.x or self.y != other.y or self.r != other.r or self.ang != other.ang
def grow_subs(ctx, subs, branches): def grow_subs(ctx, subs, branches):
source = ctx.get_source()
new_subs = [] new_subs = []
created = False created = False
for branch in subs: for branch in subs:
# create a sub branch based on length # create a sub branch based on length
sub_branches = len(branch.nodes) // 10 sub_branches = len(branch.nodes) // 7 * 2
print(f'creating {sub_branches} subs')
if sub_branches > 1: if sub_branches > 1:
created = True created = True
for i in range(sub_branches): for i in range(sub_branches):
for n in range(15): # attempts at growing branches for n in range(60): # attempts at growing branches
start_node = random.choice(branch.nodes) start_node = random.choice(branch.nodes)
# start perpendicular to our last angle # start perpendicular to our last angle
start_angle = start_node.ang + random.choice([90, -90]) + random.uniform(-5, 5) start_angle = start_node.ang + random.choice([90, -90]) + random.uniform(-30, 30)
start_x = start_node.r * math.sin(start_angle) + start_node.x start_x = (start_node.r * 1.2) * math.sin(start_angle) + start_node.x
start_y = start_node.r * math.cos(start_angle) + start_node.y start_y = (start_node.r * 1.2) * math.cos(start_angle) + start_node.y
start_r = start_node.r - 0.002 start_r = start_node.r * 0.8
new_branch = Branch(i, ctx, start_x, start_y, start_r, start_angle) new_branch = Branch(i, ctx, start_x, start_y, start_r, start_angle)
if new_branch.place_next(branches): if new_branch.place_next(branches):
break break
new_branch.set_ignores(branch.nodes)
branches.append(new_branch) branches.append(new_branch)
new_subs.append(new_branch) new_subs.append(new_branch)
if not created: if not created:
return return
while not all([branch.ended for branch in new_subs]): while not all([branch.ended for branch in new_subs]):
for branch in new_subs: for branch in new_subs:
branch.place_next(branches) branch.place_next([b for b in branches if b != branch])
return new_subs return new_subs
def main(): def main():
@ -110,7 +123,7 @@ def main():
#for b in range(6): #for b in range(6):
# start_x = random.uniform(0.2, 0.8) # start_x = random.uniform(0.2, 0.8)
# start_y = random.uniform(0.2, 0.8) # start_y = random.uniform(0.2, 0.8)
start_r = 0.015 start_r = 0.01
# start_angle = random.randint(0, 360) # start_angle = random.randint(0, 360)
# branches.append(Branch(b, ctx, start_x, start_y, start_r, start_angle)) # branches.append(Branch(b, ctx, start_x, start_y, start_r, start_angle))
branches.append(Branch(0, ctx, 0.5, 0.4, start_r, 180)) branches.append(Branch(0, ctx, 0.5, 0.4, start_r, 180))
@ -128,6 +141,7 @@ def main():
for x in range(8): for x in range(8):
if subs == None: if subs == None:
return return
ctx.set_source_rgb(0.0, 0.0, 0.1*x)
subs = grow_subs(ctx, subs, branches) subs = grow_subs(ctx, subs, branches)
surface.write_to_png("out/hyphae.png") # Output to PNG surface.write_to_png("out/hyphae.png") # Output to PNG
input('next') input('next')

@ -33,7 +33,7 @@ def days_color(date):
days_in_year = 365 + calendar.isleap(year) days_in_year = 365 + calendar.isleap(year)
# between 0 and 1, how far through the year are we? # between 0 and 1, how far through the year are we?
progress = today/days_in_year progress = today/days_in_year
return colorsys.hsv_to_rgb(progress, 1, 1) return colorsys.hsv_to_rgb(progress, 1, 0.9)
def days_amp(date, waves): def days_amp(date, waves):
day = date.day day = date.day
@ -44,17 +44,17 @@ def days_amp(date, waves):
def days_count(date): def days_count(date):
return date.month return date.month
def main(): def create_wpotd(output):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx = cairo.Context(surface) ctx = cairo.Context(surface)
ctx.scale(WIDTH, HEIGHT) # Normalizing the canvas ctx.scale(WIDTH, HEIGHT) # Normalizing the canvas
#ctx.set_antialias(cairo.Antialias.BEST)
step_size = 1/PRECISION step_size = 1/PRECISION
lastpoints = [(x/PRECISION, 0) for x in range(PRECISION+1)] lastpoints = [(x/PRECISION, 0) for x in range(PRECISION+1)]
#date = datetime.datetime.strptime('2021-01-01', '%Y-%m-%d') #date = datetime.datetime.strptime('2021-06-30', '%Y-%m-%d')
date = datetime.datetime.today() date = datetime.datetime.today()
frequency = random.randint(10, 40) frequency = random.randint(10, 40)
if DATE_BASED_COUNT: if DATE_BASED_COUNT:
@ -65,11 +65,6 @@ def main():
amplitude = days_amp(date, waves) amplitude = days_amp(date, waves)
else: else:
amplitude = 25 amplitude = 25
if DARK_BG:
# make bg black
ctx.rectangle(0, 0, 1, 1)
ctx.set_source_rgb(0, 0, 0)
ctx.fill()
if MONOCHROME: if MONOCHROME:
if DATE_BASED_COLOR: if DATE_BASED_COLOR:
@ -77,6 +72,11 @@ def main():
else: else:
r, g, b = random_color() r, g, b = random_color()
alpha_step = 1/waves alpha_step = 1/waves
if DARK_BG:
# make bg black
ctx.rectangle(0, 0, 1, 1)
ctx.set_source_rgb(0, 0, 0)
ctx.fill()
wave_height = 1/waves wave_height = 1/waves
for num in range(waves+1): for num in range(waves+1):
@ -86,9 +86,9 @@ def main():
x = 0 x = 0
while x < 1: while x < 1:
y = amplitude * math.sin(frequency * x + (num * WAVE_OFFSET) ) y = amplitude * math.sin(frequency * x + (num * WAVE_OFFSET) )
points.append((x, ( (y) + ((0.5+num)*wave_height)))) points.append((x, ( y + (0.5+num)*wave_height)))
x += step_size x += step_size
print(f'Draw {len(points)} points for curve {num}') #print(f'Draw {len(points)} points for curve {num}')
if not MONOCHROME: if not MONOCHROME:
ctx.set_source_rgb(r, g, b) ctx.set_source_rgb(r, g, b)
else: else:
@ -97,14 +97,18 @@ def main():
ctx.move_to(*points[0]) ctx.move_to(*points[0])
for p in points[1:]: for p in points[1:]:
ctx.line_to(*p) ctx.line_to(*p)
ctx.set_line_width(0.0004)
ctx.stroke_preserve()
for p in reversed(lastpoints): for p in reversed(lastpoints):
ctx.line_to(*p) ctx.line_to(*p)
ctx.line_to(*points[0]) ctx.line_to(*points[0])
ctx.fill() ctx.fill()
lastpoints = points lastpoints = points
surface.write_to_png(output) # Output to PNG
surface.write_to_png("out/waves.png") # Output to PNG def main():
create_wpotd('out/waves.png')
if __name__ == '__main__': if __name__ == '__main__':
main() main()

@ -0,0 +1,4 @@
#!/usr/bin/env python3
print('Content-Type: image/png')
print(open('out/waves.png', 'rb').read())
Loading…
Cancel
Save