# Near Grid / Quase grade (v2021_05) - Alexandre B A Villares # Running on Processing Python mode, or pyp5js/pyodide in the browser from itertools import product from random import sample change_b = False def setup(): global grid, points_a, points_b size(700, 700) grid = list(product(range(100, width, 125), repeat=2)) points_a = sample(grid, 24) points_b = sample(grid, 24) for _ in range(12): Element() def draw(): global change_b background(240) t = brutal_sigmoid(radians(millis() / 100 % 360)) points = iter(lerp_tuple(points_a, points_b, t)) for e in Element.elements: e_start, e_end = next(points), next(points) e.update(e_start, e_end) for e in Element.elements: e.display() if t == 0 and change_b: points_b[:] = sample(grid, 24) change_b = False elif t == 1: points_a[:] = sample(grid, 24) change_b = True class Element: elements = [] def __init__(self): self.elements.append(self) def update(self, e_start, e_end, divisions=16): self.points = [lerp_tuple(e_start, e_end, i / float(divisions)) for i in range(divisions)] + [e_end] def display(self): for self_p in self.points : for other in reversed(self.elements): if other == self: break for other_p in other.points: d = dist(self_p[0], self_p[1], other_p[0], other_p[1]) if d <= 125: stroke(0, 0, d, 155 - d) line(self_p[0], self_p[1], other_p[0], other_p[1]) fill(0) noStroke() circle(self_p[0], self_p[1], 4) def lerp_tuple(a, b, t): return tuple(lerp_tuple(ca, cb, t) if isinstance(ca, tuple) else lerp(ca, cb, t) for ca, cb in zip(a, b)) def brutal_sigmoid(angle): m = cos(angle) * 10 r = 1 / (1 + exp(-m)) if r < 0.001: return 0 elif r > 0.999: return 1 else: return r