Skip to content

Instantly share code, notes, and snippets.

@fogleman
Created February 2, 2019 22:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fogleman/60ace074221806986bf9290d997e3a24 to your computer and use it in GitHub Desktop.
Save fogleman/60ace074221806986bf9290d997e3a24 to your computer and use it in GitHub Desktop.
import cairocffi as cairo
import numpy as np
import random
def random_coefs(order, sigma):
return [random.gauss(0, sigma) for _ in range(order)]
def random_transform():
y_dx = random_coefs(5, 0.3)
y_dy = random_coefs(5, 0.3)
x_angle = random_coefs(5, 0.5)
x_dx = random_coefs(5, 0.3)
x_dy = random_coefs(5, 0.3)
def transform(x, y):
a = np.polyval(x_angle, x)
dx = np.polyval(x_dx, x)
dy = np.polyval(x_dy, x)
s = np.sin(a)
c = np.cos(a)
x += np.polyval(y_dx, y)
y += np.polyval(y_dy, y)
tx = c * x - s * y + dx
ty = c * y + s * x + dy
return (tx, ty)
return transform
def draw_one(cr, bx0, by0, bx1, by1):
n = 100
transform = random_transform()
points = {}
for y in range(-n, n+1):
for x in range(-n, n+1):
tx, ty = transform(x / n, y / n)
points[(x, y)] = (tx, ty)
x0 = min(x for x, y in points.values())
x1 = max(x for x, y in points.values())
y0 = min(y for x, y in points.values())
y1 = max(y for x, y in points.values())
dx = x1 - x0
dy = y1 - y0
sx = (bx1 - bx0) / dx
sy = (by1 - by0) / dy
s = min(sx, sy) * 0.75
cx = (x0 + x1) / 2
cy = (y0 + y1) / 2
cr.identity_matrix()
cr.translate((bx0 + bx1) / 2, (by0 + by1) / 2)
cr.scale(s)
cr.translate(-cx, -cy)
for i in range(-n, n):
for j in range(-n, n+1, 10):
cr.move_to(*points[(j, i+0)])
cr.line_to(*points[(j, i+1)])
cr.move_to(*points[(i+0, j)])
cr.line_to(*points[(i+1, j)])
cr.set_line_width(2 / s)
cr.set_source_rgb(0, 0, 0)
cr.stroke()
cr.set_source_rgba(0, 0, 0, 0.25)
for y in range(-n, n):
for x in range(-n, n):
cr.move_to(*points[(x+0, y+0)])
cr.line_to(*points[(x+1, y+0)])
cr.line_to(*points[(x+1, y+1)])
cr.line_to(*points[(x+0, y+1)])
cr.close_path()
cr.fill()
def main():
w = h = 1600
surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)
cr = cairo.Context(surface)
cr.set_source_rgb(1, 1, 1)
cr.paint()
draw_one(cr, 0, 0, w, h)
surface.write_to_png('out.png')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment