Skip to content

Instantly share code, notes, and snippets.

@glider-gun
Created October 25, 2018 16:34
Show Gist options
  • Save glider-gun/58c9491ce0e923e73026ec291bb96e55 to your computer and use it in GitHub Desktop.
Save glider-gun/58c9491ce0e923e73026ec291bb96e55 to your computer and use it in GitHub Desktop.
gray_scott.py
#!python3
from __future__ import print_function
import numpy as np
try:
from scene import *
ios = True
except:
ios = False
#ios = False
f, k = 0.022, 0.051 # stripe
#f, k = 0.035, 0.065 # spot
f, k = 0.04, 0.06 # amorphus
#f, k = 0.012, 0.05 # wandering bubbles
#f, k = 0.025, 0.05 # waves
class Sim:
def __init__(self, rows, cols, f=0.022, k=0.051, dx=0.01, dt=1,Du=2e-5, Dv=1e-5, sqsize=10):
self.shape = (rows,cols)
self.us = np.ones((rows, cols))
self.vs = np.zeros((rows, cols))
self.sqsize = sqsize
self.us[rows//2-sqsize//2:rows//2+sqsize//2,
cols//2-sqsize//2:cols//2+sqsize//2] = 0.5
self.vs[rows//2-sqsize//2:rows//2+sqsize//2,
cols//2-sqsize//2:cols//2+sqsize//2] = 0.5
self.us += np.random.randn(rows, cols)*0.1
self.vs += np.random.randn(rows, cols)*0.1
self.dt = dt
self.dx = dx
self.f = f
self.k = k
self.Du = Du
self.Dv = Dv
def step(self, n=1):
for i in range(n):
u = self.us
v = self.vs
lu = (np.roll(u,1,axis=0)+np.roll(u,-1,axis=0)
+np.roll(u,1,axis=1)+np.roll(u,-1,axis=1)-4*u)/(self.dx*self.dx)
lv = (np.roll(v,1,axis=0)+np.roll(v,-1,axis=0)
+np.roll(v,1,axis=1)+np.roll(v,-1,axis=1)-4*v)/(self.dx*self.dx)
dudt = self.Du*lu-u*v*v+self.f*(1-u)
dvdt = self.Dv*lv+u*v*v-(self.f+self.k)*v
self.us += dudt*self.dt
self.vs += dvdt*self.dt
def set(self, x, y, u, v):
self.us[y,x]=u
self.vs[y,x]=v
if ios:
def clip(x, min, max):
return np.minimum(max, np.maximum(min, x))
def draw_grids(size,rows,cols):
fill(0,0,0)
stroke(0,0,0)
stroke_weight(1)
for i in range(0,cols+1):
line(i*size,0,i*size,rows*size)
for i in range(0,rows+1):
line(0,i*size,cols*size,i*size)
def draw_elem(x,y,size,rows,cols, color):
fill(*color)
#print (color, end=',')
# ellipse(x*size+size/4.0,y*size+size/4.0,size/2.0,size/2.0)
rect(x*size,y*size,size,size)
class GridScene(Scene):
def __init__(self, wait, cellsize):
super(GridScene, self).__init__()
self.wait = wait
self.cellsize = cellsize
self.sim =None
def setup(self):
self.cols = int(self.size.w/self.cellsize)
self.rows = int(self.size.h/self.cellsize)
self.sim = Sim(self.rows, self.cols, f, k)
self.prev_draw_time = 0
self.hw = int(self.size.w/2)
self.hh = int(self.size.h/2)
self.locs = {}
def coord_screen_to_board(self,loc):
x, y = int(loc.x/self.cellsize), \
int(loc.y/self.cellsize)
return x,y
def touch_began(self, touch):
loc = touch.location
x, y = self.coord_screen_to_board(loc)
self.sim.set(x, y, 0.5, 0.5)
self.locs[touch.touch_id] = loc
def touch_moved(self, touch):
prex, prey = self.coord_screen_to_board(
self.locs[touch.touch_id])
curx, cury = self.coord_screen_to_board(touch.location)
dx, dy = curx - prex, cury - prey
l = max(abs(dx),abs(dy))
if l != 0:
fx, fy = float(dx)/l, float(dy)/l
for i in range(l):
self.sim.set(prex + int(fx*i), prey + int(fy*i), 0.5, 0.5)
self.sim.set(curx, cury, 0.5, 0.5)
self.locs[touch.touch_id] = touch.location
def touch_ended(self, touch):
if touch.touch_id in self.locs: del self.locs[touch.touch_id]
def draw(self):
background('white')
if self.sim:
for y in range(self.rows):
for x in range(self.cols):
c = [self.sim.us[y,x], self.sim.us[y,x], self.sim.us[y, x]]
draw_elem(x, y, self.cellsize, self.rows, self.cols, c)
#if self.t - self.prev_draw_time > self.wait and len(self.touches) == 0:
if self.t - self.prev_draw_time > self.wait:
self.prev_draw_time = self.t
self.sim.step(8)
run(GridScene(0.1, 4))
else:
import matplotlib.pyplot as plt
rows, cols = 128,128
sim = Sim(rows, cols, f, k)
for i in range(1000):
fig = plt.figure()
plt.axis('off')
plt.imshow(sim.us, cmap='gray')
plt.show()
plt.close(fig)
#print(sim.us)
sim.step(16)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment