24a24b25b
| Po Szerokość: | Wysokość: | Rozmiar: 5.1 KiB | 
|  | @ -84,7 +84,7 @@ def keyPressed(): | |||
|     # if key == "g": | ||||
|     #     gif_export(GifMaker, filename=SKETCH_NAME) | ||||
|     if key == "s": | ||||
|         saveFrame(SKETCH_NAME + "#.png") | ||||
|         saveFrame(SKETCH_NAME + ".png") | ||||
|     if key == "t": | ||||
|         Poly.text_on = not Poly.text_on | ||||
| 
 | ||||
|  |  | |||
| Po Szerokość: | Wysokość: | Rozmiar: 9.6 KiB | 
|  | @ -1,4 +1,5 @@ | |||
| from __future__ import division | ||||
| 
 | ||||
| order = 9 | ||||
| 
 | ||||
| def setup(): | ||||
|  | @ -22,10 +23,9 @@ def draw(): | |||
| def draw_trit(trit): | ||||
|     r = 8 | ||||
|     for t in trit: | ||||
|         tn = int(t) | ||||
|         if tn == 0: | ||||
|         if t == '0': | ||||
|             rect(0, 0, r, r) | ||||
|         elif tn == 1: | ||||
|         elif t == '1': | ||||
|             rect(0, 0, r/2, r*2) | ||||
|         else: | ||||
|             rect(0, 0, r*2, r/2) | ||||
|  | @ -49,3 +49,16 @@ def trit(n, pad): | |||
| 
 | ||||
| def keyPressed(): | ||||
|     saveFrame("###.png") | ||||
|      | ||||
| def settings(): | ||||
|     from os import path | ||||
|     global SKETCH_NAME | ||||
|     SKETCH_NAME = path.basename(sketchPath()) | ||||
|     OUTPUT = ".png" | ||||
|     println( | ||||
|         """ | ||||
|  | ||||
| 
 | ||||
| [{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) | ||||
|     ) | ||||
|  |  | |||
|  | @ -0,0 +1,40 @@ | |||
| """ | ||||
| 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=200,            # 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) | ||||
|          | ||||
|     gifExporter.addFrame() | ||||
| 
 | ||||
|     if frames == 0: | ||||
|        if keyPressed and key == "e": | ||||
|            finish = True | ||||
|                  | ||||
|     if finish: | ||||
|         gifExporter.finish() | ||||
|         print("gif saved") | ||||
|         exit() | ||||
|  | @ -0,0 +1,118 @@ | |||
| 
 | ||||
| class Poly(): | ||||
| 
 | ||||
|     text_on = False | ||||
|     drag = -1 | ||||
|     drag_hole = -1 | ||||
|     drag_drag_pt = -1 | ||||
| 
 | ||||
|     def __init__(self, outer_pts, holes=[[(0, 0)]]): | ||||
|         self.outer_pts = outer_pts | ||||
|         self.holes = holes | ||||
|      | ||||
|     @classmethod | ||||
|     def setup_grid(cls, cell_size, order, x_offset, y_offset): | ||||
|         cls.cell_size = cell_size | ||||
|         cls.order = order | ||||
|         cls.x_offset, cls.y_offset = x_offset, y_offset | ||||
| 
 | ||||
|     def plot(self): | ||||
|         pushStyle() | ||||
|         if len(self.outer_pts) >= 3: | ||||
|             fill(255) | ||||
|             beginShape() | ||||
|             for x, y in self.outer_pts: | ||||
|                 stroke(0) | ||||
|                 sx = (x + Poly.x_offset) * Poly.cell_size | ||||
|                 sy = (y + Poly.y_offset) * Poly.cell_size | ||||
|                 vertex(sx, sy) | ||||
|             for h in self.holes: | ||||
|                 beginContour() | ||||
|                 for x, y in h: | ||||
|                     sx = (x + Poly.x_offset) * Poly.cell_size | ||||
|                     sy = (y + Poly.y_offset) * Poly.cell_size | ||||
|                     vertex(sx, sy) | ||||
|                 endContour() | ||||
|             endShape(CLOSE) | ||||
|         Poly.annotate_pts(self.outer_pts, color(200, 0, 0), 5) | ||||
|         Poly.annotate_pts(self.holes[0], color(0, 0, 200), 5) | ||||
|         popStyle() | ||||
| 
 | ||||
|     def remove_pt(self): | ||||
|         snap = Poly.mouse_snap() | ||||
|         if snap: | ||||
|           for pt in self.outer_pts: | ||||
|             if pt == snap: | ||||
|                 self.outer_pts.remove(pt) | ||||
|                 return True | ||||
|             for h in self.holes: | ||||
|                 for pt in h: | ||||
|                     if pt == snap: | ||||
|                         h.remove(pt) | ||||
|                         return True | ||||
| 
 | ||||
|     def set_drag(self): #, io, jo): | ||||
|         snap = Poly.mouse_snap() | ||||
|         if snap: | ||||
|             for ipt, pt in enumerate(self.outer_pts): | ||||
|                 if pt == snap: #(io, jo): | ||||
|                     Poly.drag_pt = ipt | ||||
|                     return True | ||||
|             for ih, h in enumerate(self.holes): | ||||
|                 for ipt, pt in enumerate(h): | ||||
|                     if pt == snap: #(io, jo): | ||||
|                         Poly.drag_hole = ih | ||||
|                         Poly.drag_pt = ipt | ||||
|                         return True | ||||
|         return False | ||||
|      | ||||
|     @classmethod | ||||
|     def annotate_pts(cls, pts, c, scale_m=1): | ||||
|         if Poly.text_on: | ||||
|             strokeWeight(5) | ||||
|             textSize(12) | ||||
|             fill(c) | ||||
|             stroke(c) | ||||
|             for i, j in pts: | ||||
|                 x = (i + cls.x_offset) * cls.cell_size | ||||
|                 y = (j + cls.y_offset) * cls.cell_size | ||||
|                 point(x, y) | ||||
|                 text(str((i * scale_m, j * scale_m)), x, y) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def draw_grid(cls): | ||||
|         stroke(128) | ||||
|         noFill() | ||||
|         for x in range(cls.order): | ||||
|             for y in range(cls.order): | ||||
|                 rect(x * cls.cell_size, y * cls.cell_size, | ||||
|                      cls.cell_size, cls.cell_size) | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def clockwise_sort(xy_pairs): | ||||
|         # https://stackoverflow.com/questions/51074984/sorting-according-to-clockwise-point-coordinates | ||||
|         data_len = len(xy_pairs) | ||||
|         if data_len > 2: | ||||
|             x, y = zip(*xy_pairs) | ||||
|         else: | ||||
|             return xy_pairs | ||||
|         centroid_x, centroid_y = sum(x) / data_len, sum(y) / data_len | ||||
|         xy_sorted = sorted(xy_pairs, | ||||
|                            key=lambda p: atan2((p[1] - centroid_y), (p[0] - centroid_x))) | ||||
|         xy_sorted_xy = [ | ||||
|             coord for pair in list(zip(*xy_sorted)) for coord in pair] | ||||
|         half_len = int(len(xy_sorted_xy) / 2) | ||||
|         return list(zip(xy_sorted_xy[:half_len], xy_sorted_xy[half_len:])) | ||||
|      | ||||
|     @classmethod | ||||
|     def mouse_snap(cls): | ||||
|         for i in range(Poly.order): | ||||
|             x = i * Poly.cell_size | ||||
|             for j in range(Poly.order): | ||||
|                 y = j * Poly.cell_size | ||||
|                 io, jo = i - Poly.x_offset, j - Poly.y_offset  # grid origin correction | ||||
|                 if dist(mouseX, mouseY, x, y) < Poly.cell_size / 2: | ||||
|                     return (io, jo) | ||||
|         return None | ||||
|                  | ||||
|      | ||||
|  | @ -0,0 +1,102 @@ | |||
| # Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day | ||||
| """ | ||||
| A minimal poly editor | ||||
| - Add points | ||||
| """ | ||||
| 
 | ||||
| from poly import Poly | ||||
| # add_library('GifAnimation') | ||||
| # from gif_exporter import gif_export | ||||
| 
 | ||||
| # f_pts = [map(lambda x: x / 5 - 12, pair) for pair in f_pts] | ||||
| polys = [Poly([(2, 2), (2, 4), (4, 4), (4, 2)]), | ||||
|          Poly([(5, 5), (5, 7), (3, 3)]), | ||||
|          Poly([(-8, -7), (-1, 0), (1, -9)], | ||||
|               holes=[[(-4, -4), (-6, -6), (-1, -7)], ]), | ||||
|          ] | ||||
| 
 | ||||
| def setup(): | ||||
|     size(500, 500, P2D) | ||||
|     CELL_SIZE = 25 | ||||
|     order = width / CELL_SIZE | ||||
|     x_offset = y_offset = int(order / 2) | ||||
|     Poly.setup_grid(CELL_SIZE, order, x_offset, y_offset) | ||||
|     Poly.text_on = False | ||||
|     strokeJoin(ROUND) | ||||
|     f = createFont("Fira Mono Bold", 16) | ||||
|     textFont(f) | ||||
| 
 | ||||
| def draw(): | ||||
|     background(230) | ||||
|     # grade | ||||
|     Poly.draw_grid() | ||||
|     # polígonos | ||||
|     for p in polys: | ||||
|         p.plot() | ||||
| 
 | ||||
| def mousePressed(): | ||||
|     if keyPressed and keyCode == CONTROL: | ||||
|         for p in polys: | ||||
|             if p.remove_pt():  # io, jo): | ||||
|                 return | ||||
|     else: | ||||
|         for ip, p in enumerate(polys): | ||||
|             if p.set_drag():  # io, jo): | ||||
|                 Poly.drag = ip | ||||
|                 return | ||||
| 
 | ||||
| def mouseDragged(): | ||||
|     if Poly.drag >= 0 and not keyPressed: | ||||
|         # a Poly point has been selected to be dragged | ||||
|         # and no modifier key is pressed... | ||||
|         if Poly.drag_hole == -1:  # if no hole wase selected | ||||
|             polys[Poly.drag].outer_pts[Poly.drag_pt] = ( | ||||
|                 int(mouseX / Poly.cell_size) - Poly.x_offset, | ||||
|                 int(mouseY / Poly.cell_size) - Poly.y_offset) | ||||
|         else: | ||||
|             polys[Poly.drag].holes[Poly.drag_hole][Poly.drag_pt] = ( | ||||
|                 int(mouseX / Poly.cell_size) - Poly.x_offset, | ||||
|                 int(mouseY / Poly.cell_size) - Poly.y_offset) | ||||
| 
 | ||||
| def mouseReleased(): | ||||
|     if Poly.drag >= 0 and keyPressed and keyCode == SHIFT: | ||||
|         # a Poly point has been selected to be dragged | ||||
|         # and SHIFT key is pressed... | ||||
|         if Poly.drag_hole == -1:  # if no hole wase selected | ||||
|             polys[Poly.drag].outer_pts.insert( | ||||
|                 Poly.drag_pt, (int(mouseX / Poly.cell_size) - Poly.x_offset, | ||||
|                                int(mouseY / Poly.cell_size) - Poly.y_offset)) | ||||
|         else: | ||||
|             polys[Poly.drag].holes[Poly.drag_hole].insert( | ||||
|                 Poly.drag_pt, (int(mouseX / Poly.cell_size) - Poly.x_offset, | ||||
|                                int(mouseY / Poly.cell_size) - Poly.y_offset)) | ||||
| 
 | ||||
|     Poly.drag = -1  # No poly selected | ||||
|     Poly.drag_hole = -1  # No hole selected | ||||
|     Poly.drag_pt = -1  # No point selected | ||||
| 
 | ||||
| def keyPressed(): | ||||
|     if key == " ": | ||||
|         for p in polys: | ||||
|             p.outer_pts[:] = Poly.clockwise_sort(p.outer_pts) | ||||
|             for h in p.holes: | ||||
|                 h[:] = Poly.clockwise_sort(h)[::-1] | ||||
|     # if key == "g": | ||||
|     #     gif_export(GifMaker, filename=SKETCH_NAME) | ||||
|     if key == "s": | ||||
|         saveFrame(SKETCH_NAME + "#.png") | ||||
|     if key == "t": | ||||
|         Poly.text_on = not Poly.text_on | ||||
| 
 | ||||
| def settings(): | ||||
|     from os import path | ||||
|     global SKETCH_NAME | ||||
|     SKETCH_NAME = path.basename(sketchPath()) | ||||
|     OUTPUT = ".png" | ||||
|     println( | ||||
|         """ | ||||
|  | ||||
| 
 | ||||
| [{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) | ||||
|     ) | ||||
| Po Szerokość: | Wysokość: | Rozmiar: 17 KiB | 
| Po Szerokość: | Wysokość: | Rozmiar: 15 KiB | 
| Po Szerokość: | Wysokość: | Rozmiar: 18 KiB | 
| Po Szerokość: | Wysokość: | Rozmiar: 16 KiB | 
|  | @ -0,0 +1,101 @@ | |||
| from __future__ import division | ||||
| 
 | ||||
| order = 9 | ||||
| p = 4 | ||||
| alt = False | ||||
| 
 | ||||
| 
 | ||||
| def setup(): | ||||
|     size(700, 700) | ||||
|     noFill()  # fill(0) | ||||
|     textAlign(CENTER, CENTER) | ||||
|     rectMode(CENTER) | ||||
|     strokeWeight(2) | ||||
|     colorMode(HSB) | ||||
| 
 | ||||
| def draw(): | ||||
|     background(240) | ||||
|     siz = width / order | ||||
|     if alt: | ||||
|         grid(siz, draw_tritB) | ||||
|     else: | ||||
|         grid(siz, draw_tritA) | ||||
| 
 | ||||
| def grid(siz, func): | ||||
|     i = 0 | ||||
|     for x in range(order): | ||||
|         for y in range(order): | ||||
|             with pushMatrix(): | ||||
|                 translate(siz / 2 + x * siz, | ||||
|                           siz / 2 + y * siz) | ||||
|                 #text(trit(i, pad=4), 0, 0) | ||||
|                 func(trit(i, pad=p)) | ||||
|             i += 1 | ||||
| 
 | ||||
| def draw_tritA(trit): | ||||
|     r = 32 | ||||
|     for t in trit: | ||||
|         if t == '0': | ||||
|             stroke(0, 255, 128) | ||||
|             rect(0, 0, r, r) | ||||
|         elif t == '1': | ||||
|             stroke(256 / 3 * 2, 255, 128) | ||||
|             rect(0, 0, r / 2, r * 2) | ||||
|         else: | ||||
|             stroke(256 / 3, 255, 128) | ||||
|             rect(0, 0, r * 2, r / 2) | ||||
|         r -= 8 | ||||
| 
 | ||||
| def draw_tritB(trit): | ||||
|     r = 32 | ||||
|     for t in trit: | ||||
|         stroke(8 + r * 7, 255, 128) | ||||
|         if t == '0': | ||||
|             rect(0, 0, r, r) | ||||
|         elif t == '1': | ||||
|             rect(0, 0, r / 2, r * 2) | ||||
|         else: | ||||
|             rect(0, 0, r * 2, r / 2) | ||||
|         r -= 8 | ||||
| 
 | ||||
| def to_base(num, base): | ||||
|     # inverse of int(str, base) | ||||
|     BS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||||
|     result = "" | ||||
|     while num: | ||||
|         result += BS[num % base] | ||||
|         num //= base | ||||
|     return result[::-1] or "0" | ||||
| 
 | ||||
| def trit(n, pad): | ||||
|     s = to_base(n, 3) | ||||
|     while len(s) < pad: | ||||
|         s = "0" + s | ||||
|     return s[::-1] | ||||
| 
 | ||||
| 
 | ||||
| def keyPressed(): | ||||
|     global alt, p | ||||
| 
 | ||||
|     if key == "s": | ||||
|         saveFrame("###.png") | ||||
| 
 | ||||
|     if key == "a": | ||||
|         alt = not alt | ||||
|          | ||||
|     if key == "p": | ||||
|         p = (p - 1) % 5 | ||||
| 
 | ||||
| 
 | ||||
| def settings(): | ||||
|     from os import path | ||||
|     global SKETCH_NAME | ||||
|     SKETCH_NAME = path.basename(sketchPath()) | ||||
|     OUTPUT = ".png" | ||||
|     println( | ||||
|         """ | ||||
|  | ||||
| 
 | ||||
| [{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) | ||||
|     ) | ||||
							
								
								
									
										20
									
								
								README.md
								
								
								
								
							
							
						
						|  | @ -21,6 +21,26 @@ Get updates from my sort-of-weekly newsletter: [[sketch-mail](https://villares.o | |||
| --- | ||||
| 
 | ||||
| ## 2019 | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| [sketch_190425b](https://github.com/villares/sketch-a-day/tree/master/2019/sketch_190425b)  [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| [sketch_190424b](https://github.com/villares/sketch-a-day/tree/master/2019/sketch_190424b) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| [sketch_190424a](https://github.com/villares/sketch-a-day/tree/master/2019/sketch_190424a) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
|  | ||||
|  |  | |||
| Po Szerokość: | Wysokość: | Rozmiar: 113 KiB | 
 villares
						villares