diff --git a/2019/sketch_190513a/bar.py b/2019/sketch_190513a/bar.py new file mode 100644 index 00000000..8140cee3 --- /dev/null +++ b/2019/sketch_190513a/bar.py @@ -0,0 +1,20 @@ +def bar(x1, y1, z1, x2, y2, z2, weight=10): + """ + from code by James Carruthers found on + https://forum.processing.org/two/discussion/21400/how-to-rotate-a-3d-line-like-a-2d-line + """ + p1 = PVector(x1, y1, z1) + p2 = PVector(x2, y2, z2) + v1 = PVector(x2 - x1, y2 - y1, z2 - z1) + rho = sqrt(v1.x ** 2 + v1.y ** 2 + v1.z ** 2) + phi = acos(v1.z / rho) + the = atan2(v1.y, v1.x) + v1.mult(0.5) + with pushMatrix(): + translate(x1, y1, z1) + translate(v1.x, v1.y, v1.z) + rotateZ(the) + rotateY(phi) + # box(weight,weight,p1.dist(p2)*1.2) + box(weight, weight, p1.dist(p2) * 1.0) + diff --git a/2019/sketch_190513a/cell.py b/2019/sketch_190513a/cell.py new file mode 100644 index 00000000..2c238cdc --- /dev/null +++ b/2019/sketch_190513a/cell.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +from random import choice +from bar import bar + +class Cell(): + border = 0 + RES = 4. + grid = dict() + debug_mode = False + # ortho neighbours + ONL = ((+0, -1, +0), + (-1, +0, +0), # (+0, +0, +0), + (+1, +0, +0), + (+0, +1, +0), + (+0, +0, -1), (+0, +0, +1), + ) + # diagonal neighbours + DNL = ((+1, +1, +0), + (-1, -1, +0), # (+0, +0, +0), + (+1, -1, +0), + (-1, +1, +0), + (+0, -1, +1), + (-1, +0, +1), + (+1, +0, +1), + (+0, +1, +1), + (+0, -1, -1), + (-1, +0, -1), + (+1, +0, -1), + (+0, +1, -1), + ) + + def __init__(self, index, cell_size, state=False): + self.index = index + self.state = state + self.size_ = cell_size + self.mouse_down = False + self.variation = "a" + self.ang = choice((0, 1, 2, 3)) + self.calculate_pos() + + def calculate_pos(self): + i, j, k = self.index + self.pos = PVector(Cell.border + self.size_ / 2 + i * self.size_ - width / 2, + Cell.border + self.size_ / 2 + + j * self.size_ - height / 2, + k * self.size_) + + def update(self, mx, my): + # mouse over & selection treatment + hs = self.size_ / 2 + px, py = self.pos.x + width / 2, self.pos.y + height / 2 + self.mouse_on = (px - hs < mx < px + hs and + py - hs < my < py + hs) + if self.mouse_on and mousePressed: + self.mouse_down = True + + elif self.mouse_down: + self.state = not self.state + self.mouse_down = False + + def plot(self, mode): + """ draws node """ + siz = self.size_ + if self.state: + + pushMatrix() + translate(self.pos.x, self.pos.y, self.pos.z) + if Cell.debug_mode: + fill(255, 0, 100) + text(self.module, 0, 0) + noFill() # stroke(0) + + i, j, k = self.index + for (ni, nj, nk) in Cell.ONL: + nb = Cell.grid.get((i + ni, j + nj, k + nk), None) + if nb and nb.state: + stroke(128, 0, 0) + bar(0, 0, 0, + ni * siz / 2, nj * siz / 2, nk * siz / 2) + stroke(0, 0, 128) + for (ni, nj, nk) in Cell.DNL: + nb = Cell.grid.get((i + ni, j + nj, k + nk), None) + if nb and nb.state: + bar(0, 0, 0, + ni * siz / 2, nj * siz / 2, nk * siz / 2, 5) + popMatrix() diff --git a/2019/sketch_190513a/gif_exporter.py b/2019/sketch_190513a/gif_exporter.py new file mode 100644 index 00000000..bb246585 --- /dev/null +++ b/2019/sketch_190513a/gif_exporter.py @@ -0,0 +1,41 @@ +""" +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/ + +# add at the start of your sketch: + add_library('gifAnimation') + from gif_exporter import gif_export +# add at the end of draw(): + gif_export(GifMaker) +""" + +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=255, # quality range 0 - 255 + delay=900, # this is quick + # 0 will stop on keyPressed or frameCount >= 100000 + frames=0, + finish=False): # force stop + global gifExporter + try: + gifExporter + except NameError: + gifExporter = GifMaker(this, filename + ".gif") + gifExporter.setRepeat(repeat) + gifExporter.setQuality(quality) + gifExporter.setDelay(delay) + + gifExporter.addFrame() + + if frames == 0: + if keyPressed and key == "e": + finish = True + + if finish: + gifExporter.finish() + print("gif saved") + exit() diff --git a/2019/sketch_190513a/sketch_190513a.gif b/2019/sketch_190513a/sketch_190513a.gif new file mode 100644 index 00000000..be7c2cb8 Binary files /dev/null and b/2019/sketch_190513a/sketch_190513a.gif differ diff --git a/2019/sketch_190513a/sketch_190513a.pyde b/2019/sketch_190513a/sketch_190513a.pyde new file mode 100644 index 00000000..d2cabb5b --- /dev/null +++ b/2019/sketch_190513a/sketch_190513a.pyde @@ -0,0 +1,107 @@ +# Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day +# based on "sketch_190125a" + +from cell import Cell +from random import choice +add_library('GifAnimation') +add_library('peasycam') +from gif_exporter import gif_export + +CELL_SIZE = 50 +modulus = 3 +mode = 0 +save_frame = False +frame_saved = 0 + +def setup(): + hint(ENABLE_DEPTH_SORT) + size(600, 600, P3D) + global grid_size + grid_size = width / CELL_SIZE + println(grid_size) + rectMode(CENTER) + strokeCap(SQUARE) + cam = PeasyCam(this, 700) + + +def init_grid(f=None): + # default grid is with random state for cells + if f == None: + f = lambda i, j: choice((True, False)) + # number of collums and rows -2 for default cell sized border + w = int(width // CELL_SIZE) # - 2 + h = int(height // CELL_SIZE) # - 2 + z = 3 + # print(w, h) + for i in range(w): + for j in range(h): + for k in range(z): + Cell.grid[(i, j, k)] = Cell((i, j, k), CELL_SIZE, f(i, j)) + +def draw(): + global save_frame, frame_saved + background(200) + #ortho() + for c in Cell.grid.values(): + c.update(mouseX, mouseY) + for c in Cell.grid.values(): + c.plot(mode) + + if save_frame: + save_frame = False + frame_saved += 1 + gif_export(GifMaker, SKETCH_NAME) + println(frame_saved) + +def keyPressed(): + global modulus, save_frame + if key == "g": + save_frame = True + if key == "G": + gif_export(GifMaker, SKETCH_NAME, finish=True) + if key == "r": + init_grid() + if key == "x": + init_grid(lambda i, j: (i + j) % modulus) + if key == "<" and modulus > 2: + modulus -= 1 + if key == ">": + modulus += 1 + if key == "z": + move_grid() + if keyCode == RIGHT: + move_grid(x=1, y=0) + if keyCode == LEFT: + move_grid(x=-1, y=0) + if keyCode == UP: + move_grid(x=0, y=-1) + if keyCode == DOWN: + move_grid(x=0, y=1) + +def move_grid(x=1, y=1): + w, h = width // CELL_SIZE, height // CELL_SIZE + new_grid = dict() + for i in range(w): + for j in range(h): + for k in range(h): + c = Cell.grid.get((i, j, k), None) + if c: + c.index = ((i + x) % w, (j + y) % h, k) + c.calculate_pos() + new_grid[c.index] = c + Cell.grid = new_grid + + +# print text to add to the project's README.md +def settings(): + from os import path + global SKETCH_NAME + SKETCH_NAME = path.basename(sketchPath()) + OUTPUT = ".png" + println( + """ +![{0}](2019/{0}/{0}{1}) + +[{0}](https://github.com/villares/sketch-a-day/tree/master/2019/{0}) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] +""".format(SKETCH_NAME, OUTPUT) + ) diff --git a/README.md b/README.md index 471b8113..c3f419df 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,14 @@ Get updates from my sort-of-weekly newsletter: [[sketch-mail](https://villares.o --- +![sketch_190513a](2019/sketch_190513a/sketch_190513a.png) + +[sketch_190513a](https://github.com/villares/sketch-a-day/tree/master/2019/sketch_190513a) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] + +A rework of sketch_190125a + +--- + ![s190512a](2019/s190512a/s190512a.gif) [s190512a](https://github.com/villares/sketch-a-day/tree/master/2019/s190512a) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)]