Last active
June 16, 2016 06:52
-
-
Save Sorseg/02668758ba45626b3afa9b52172939ac to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import turtle | |
from collections import namedtuple | |
from math import sin | |
from random import choice, randint as ri | |
import time | |
WIDTH_BASE = [1, 10] | |
WIDTH_PERIOD = [1, 100] | |
WIDTH_AMP = [0, 20] | |
def get_random_period(): | |
return float(choice([13, 17, 19, 23, 29, 31, 37, 41, 43, 47, | |
53, 59, 61, 67, 71, 73, 79, 83, 89, 97, | |
101, 103, 107, 109, 113, 127, 131, 137, | |
139, 149, 151])) | |
COLOR_DIA = [0, 0] | |
COLOR_AMP = 255 | |
class Osc(namedtuple('Osc', ['width', 'period', 'amp'])): | |
def val(self, phase): | |
return int(self.width + (1 + sin(phase / float(self.period))) * self.amp / 2.0) | |
class Plotter(object): | |
def __init__(self, scale=5): | |
self.width = 1000 | |
self.height = 600 | |
self.periods = Periodizer() | |
self.pen = None | |
self.color = None | |
self.scale = scale | |
def init(self): | |
turtle.speed(0) | |
turtle.colormode(255) | |
self.randomize(False) | |
def randomize(self, pos=True, phase=0): | |
if pos: | |
turtle.setpos(ri(-self.width / 2, self.width / 2), ri(-self.height / 2, self.height / 2)) | |
self.periods.randomize() | |
self.pen = Osc(width=ri(*WIDTH_BASE), period=ri(*WIDTH_PERIOD), amp=ri(*WIDTH_AMP)) | |
self.color = [Osc(width=ri(*COLOR_DIA), period=ri(1, 100), amp=ri(0, COLOR_AMP)) for _ in range(3)] | |
self.update_pen(phase) | |
def update_pen(self, phase): | |
turtle.pensize(self.pen.val(phase)) | |
turtle.pencolor([c.val(phase) for c in self.color]) | |
def iterate(self, phase): | |
slight_drift = int(sin(phase / 6410.0) * 360 + sin(phase / 9970.0) * 360) | |
sped_up_phase = phase * self.scale | |
angle = int(sin(sped_up_phase / self.periods[0]) * 360 + | |
sin(sped_up_phase / self.periods[1]) * 40 + | |
sin(sped_up_phase / self.periods[2]) * 100 + | |
sin(sped_up_phase / self.periods[3]) * sin(sped_up_phase / self.periods[4]) * 300) + \ | |
slight_drift | |
thrust = max(10, int(abs(sin(phase / self.periods[3]) * 7) + sin(phase / self.periods[4]) * 4)) | |
turtle.setheading(angle) | |
turtle.forward(thrust) | |
self.update_pen(phase) | |
x, y = turtle.pos() | |
if abs(x) > self.width / 2 or abs(y) > self.height / 2: | |
turtle.penup() | |
self.randomize(phase=phase) | |
turtle.pendown() | |
class Periodizer(object): | |
def __init__(self): | |
self.periods = [] | |
def __getitem__(self, item): | |
while len(self.periods) <= item: | |
self.periods.append(get_random_period()) | |
# print ', '.join('{}:{}'.format(i, p) for i, p in enumerate(self.periods)) | |
return self.periods[item] | |
def randomize(self): | |
self.periods = [get_random_period() for p in self.periods] | |
print ', '.join('{}:{}'.format(i, p) for i, p in enumerate(self.periods)) | |
p = Plotter(scale=4) | |
p.init() | |
phase = 1 | |
# N = 100 | |
# times = [0]*N | |
while True: | |
# t = time.time() | |
p.iterate(phase) | |
phase += 1 | |
# times[phase % N] = time.time() - t | |
# if not phase % N: | |
# print "avg frame time", sum(times) / N | |
turtle.exitonclick() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment