Skip to content

Instantly share code, notes, and snippets.

@bencrowder
Last active September 5, 2016 03:30
Show Gist options
  • Save bencrowder/b8f90e3058e8cf67edaf116033d1a2dd to your computer and use it in GitHub Desktop.
Save bencrowder/b8f90e3058e8cf67edaf116033d1a2dd to your computer and use it in GitHub Desktop.
Line generation
#!/usr/bin/env python
# Code for https://blogs.bencrowder.net/cg/2012/line-art-experiments/
# Uses PIL (pip install pillow)
import random, math
from PIL import Image, ImageDraw
image_size = 4800
num_lines = 80
line_size = 2
start_angle = 2.094
angle_diff = 0.08
max_angle = start_angle + angle_diff
min_angle = start_angle - angle_diff
change_chance = 10
class Line:
x = 0
y = 0
angle = 0
canvas = None
type = 0 # 0 = top, 1 = right
start_loc = 0 # where we're starting (x or y, depends on type)
target_loc = 0 # the target
def __init__(self, canvas, type, start_loc, target_loc):
self.canvas = canvas
self.type = type
self.start_loc = start_loc
self.target_loc = target_loc
if self.type == 0: # top
self.x = self.start_loc
self.y = 0
elif self.type == 1: # right
self.x = image_size
self.y = self.start_loc
self.angle = start_angle + random.random() * angle_diff
def update(self):
# Only change angles once in a while
change_angle = random.randint(0, change_chance)
if change_angle == 0:
# Modify the angle
self.angle += (random.random() * angle_diff) - (angle_diff / 2)
# Cap the angle
if self.angle > max_angle:
self.angle = max_angle
if self.angle < min_angle:
self.angle = min_angle
# Move the location by the angle
self.x = 1 * math.cos(self.angle) + self.x
self.y = 1 * math.sin(self.angle) + self.y
def draw(self):
x1 = self.x - (line_size / 2)
x2 = self.x + (line_size / 2)
y1 = self.y - (line_size / 2)
y2 = self.y + (line_size / 2)
self.canvas.ellipse((x1, y1, x2, y2), fill="black")
def run(self):
if self.type == 0: # top
while (self.x > 0):
self.update()
self.draw()
elif self.type == 1: # right
while (self.y < image_size):
self.update()
self.draw()
# Create the image
img = Image.new('RGB', (image_size, image_size), (255, 255, 255))
canvas = ImageDraw.Draw(img)
# Initialize the lines
top_line_locs = []
right_line_locs = []
for i in range(0, num_lines):
top_line_locs.append(random.random() * image_size)
if i < num_lines / 2:
right_line_locs.append(random.random() * image_size)
top_line_locs.sort()
right_line_locs.sort()
# Now create each line, setting its target appropriately
top_lines = []
right_lines = []
for i in range(0, num_lines):
# For the top, set the target to the equivalent right_lines[]
top_lines.append(Line(canvas, 0, top_line_locs[i], 5))
# For the right, set the target to the equivalent top_lines[]
if i < num_lines / 2:
right_lines.append(Line(canvas, 1, right_line_locs[i], top_line_locs[i]))
# Now go through the image and draw
for line in top_lines:
line.run()
for line in right_lines:
line.run()
img.save("output.png", "PNG")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment