Skip to content

Instantly share code, notes, and snippets.

@deniska
Created November 4, 2024 20:57
Show Gist options
  • Save deniska/04652ce7d8db617843cc511051f4802e to your computer and use it in GitHub Desktop.
Save deniska/04652ce7d8db617843cc511051f4802e to your computer and use it in GitHub Desktop.
import random
import math
import PIL.Image
funcs = [
('add', 2, 1),
('mult', 2, 1),
#('atan2', 2, 1),
#('floor', 1, 1),
#('ceil', 1, 1),
#('sin', 1, 1),
#('logistics', 1, 1),
#('sqrt_squared', 1, 1),
('if_then_else', 3, 1),
('dist', 2, 1),
('copysign', 2, 1),
]
funcs.append(('terminator', 0, sum(f[2] for f in funcs) / 4))
evaluators = {
'add': lambda x, y: x + y,
'mult': lambda x, y: x * y,
'sin': lambda x: math.sin(x),
'sqrt_squared': lambda x: math.sqrt(x**2),
'if_then_else': lambda x, y, z: y if x > 0 else z,
'logistics': lambda x: 1 / (1 + math.exp(-1)),
'dist': lambda x, y: math.sqrt(x**2 + y**2),
'atan2': lambda x, y: math.atan2(y, x),
'floor': math.floor,
'ceil': math.ceil,
'copysign': math.copysign,
}
def generate(depth):
while depth > 0 and random.random() < 0.5:
depth -= 1
func = random.choices(funcs, weights=[f[2] for f in funcs])[0]
if depth <= 0:
func = funcs[-1]
if func[0] == 'terminator':
return random.choice(['x', 'y', random.uniform(-1, 1)])
ret = [func[0]]
for i in range(func[1]):
ret.append(generate(depth-1))
return ret
def evaluate(expr, x, y):
if isinstance(expr, list):
args = []
for a in expr[1:]:
args.append(evaluate(a, x, y))
return evaluators[expr[0]](*args)
elif expr == 'x':
return x
elif expr == 'y':
return y
else:
return expr
DEPTH = 15
MODE = 'HSV' # RGB
WIDTH = 400
HEIGHT = 400
def main():
r_expr = generate(DEPTH)
g_expr = generate(DEPTH)
b_expr = generate(DEPTH)
print(f'{r_expr = }')
print(f'{g_expr = }')
print(f'{b_expr = }')
img = bytearray()
for y_px in range(HEIGHT):
y = (y_px / HEIGHT) * 2 - 1
for x_px in range(WIDTH):
x = (x_px / WIDTH) * 2 - 1
r = int(((evaluate(r_expr, x, y) + 1) / 2) * 255) % 256
g = int(((evaluate(g_expr, x, y) + 1) / 2) * 255) % 256
b = int(((evaluate(b_expr, x, y) + 1) / 2) * 255) % 256
img.append(r)
img.append(g)
img.append(b)
out = PIL.Image.frombytes(MODE, (WIDTH, HEIGHT), img)
out.convert('RGB').save('output.png')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment