diff --git a/2020/sketch_2020_04_23a/gif_animation_helper.py b/2020/sketch_2020_04_23a/gif_animation_helper.py new file mode 100644 index 00000000..13fc00f8 --- /dev/null +++ b/2020/sketch_2020_04_23a/gif_animation_helper.py @@ -0,0 +1,44 @@ +""" +Alexandre B A Villares http://abav.lugaralgum.com - GPL v3 + +A helper for the Processing gifAnimation library https://github.com/extrapixel/gif-animation/tree/3.0 +Download from https://github.com/villares/processing-play/blob/master/export_GIF/unzip_and_move_to_libraries_GifAnimation.zip +This helper was inspired by an example by Art Simon https://github.com/APCSPrinciples/AnimatedGIF/ + +v2019_09_23 + +# add at the start of your sketch: + add_library('gifAnimation') + from gif_animation_helper import gif_export +# add at the end of draw(): + gif_export(GifMaker, "filename") +""" + +def gif_export(GifMaker, # gets a reference to the library + filename="exported", # .gif will be added + repeat=0, # 0 makes it an "endless" animation + quality=100, # quality range 0 - 255 + delay=500, # this is quick + frames=0, # 0 will stop on keyPressed or frameCount >= 100000 + finish=False): # force stop + global gifExporter + try: + gifExporter + except NameError: + gifExporter = GifMaker(this, filename + ".gif") + gifExporter.setRepeat(repeat) + gifExporter.setQuality(quality) + gifExporter.setDelay(delay) + print("gif recording started") + + + gifExporter.addFrame() + + if (frames == 0 and keyPressed and key == "e" or + frames != 0 and frameCount >= frames): + finish = True + + if finish: + gifExporter.finish() + print("gif saved, exit") + exit() diff --git a/2020/sketch_2020_04_23a/sketch_2020_04_23a.gif b/2020/sketch_2020_04_23a/sketch_2020_04_23a.gif new file mode 100644 index 00000000..31bc1276 Binary files /dev/null and b/2020/sketch_2020_04_23a/sketch_2020_04_23a.gif differ diff --git a/2020/sketch_2020_04_23a/sketch_2020_04_23a.pyde b/2020/sketch_2020_04_23a/sketch_2020_04_23a.pyde new file mode 100644 index 00000000..64a39d9b --- /dev/null +++ b/2020/sketch_2020_04_23a/sketch_2020_04_23a.pyde @@ -0,0 +1,139 @@ +""" +"Based on traditional Japanese stitching, +this is a riff on hitomezashi patterns." Annie Perikins @anniek_p +https://twitter.com/anniek_p/status/1244220881347502080?s=20 +""" +from random import choice + +add_library('GifAnimation') +from gif_animation_helper import gif_export +sketch_name = 'sketch_2020_04_22a' + +tam = 8 +mtm = tam / 2 # meio tamanho +grid = dict() +chains = [] + +def setup(): + global cols, rows + size(320, 320) + colorMode(HSB) + strokeWeight(2) + cols, rows = width / mtm - 1, height / tam + init() + + +def draw(): + background(0) + noFill() + for i in range(cols): + x = i * mtm + mtm + for j in range(rows): + y = j * tam + mtm + chain_i = in_chains(i, j) + if chain_i >= 0: + ln = len(chains[chain_i]) / 2 + stroke((ln * 4) % 220, 200, 200) + else: + stroke(255) + if grid[(i, j)]: + rectMode(CENTER) + if i % 2 == 0: + # line(x, y - mtm, x, y + mtm) + square(x, y, mtm) + else: + # line(x - mtm, y - mtm, x + mtm, y - mtm) + square(x, y - mtm, mtm) + # line(x - mtm, y - mtm, x + mtm, y - mtm) + # else: + # line(x, y + mtm, x, y - mtm) + for _ in range(10): + pick_one() + add_to_chains() + +def pick_one(): + found = False + tested = [] + for y in range(rows): + for x in range(cols): + if grid[(x, y)] and in_chains(x, y) == -1: + t = x, y + chains.append(set([t])) + return + +def print_chains(): + for c in chains: + print(len(c)) + +def add_to_chains(): + for chain in chains: + s = 0 + while len(chain) != s: + s = len(chain) + for t in chain: + for n in active_ngbs(*t): + if n not in chain: + chain.add(n) + +def in_chains(x, y): + for i, chain in enumerate(chains): + if (x, y) in chain: + return i + return -1 + +def keyPressed(): + if key == 'a': + pick_one() + add_to_chains() + print(len(chains)) + if key == 'p': + gif_export(GifMaker, sketch_name) + if key == 'q': + gif_export(GifMaker, "animation", finish=True) + if key == ' ': + init() + chains[:] = [] + if key == 's': + shuff() + + +def shuff(): + for y in range(0, rows, 2): + on = choice((True, False)) + for x in range(cols): + if x % 2 == 1: + if x % 4: + on = not on + grid[(x, y)] = on + +def init(): + for y in range(rows): + on = choice((True, False)) + for x in range(cols): + if x % 2 == 1: + if x % 4: + on = not on + grid[(x, y)] = on + for x in range(cols): + on = choice((True, False)) + for y in range(rows): + if x % 2 == 0: + on = not on + grid[(x, y)] = on + + +def active_ngbs(x, y): + return [n for n in ngbs(x, y) + if grid[n]] + +def ngbs(x, y): + nbs = [] + if x % 2 == 0: + nb_list = ((-1, 0), (-1, 1), (1, 0), (1, 1)) + else: + nb_list = ((-1, 0), (-1, -1), (1, 0), (1, -1)) + for nx, ny in nb_list: + nb = x + nx, y + ny + if grid.get(nb) is not None: + nbs.append(nb) + return nbs