kopia lustrzana https://github.com/villares/sketch-a-day
				
				
				
			
			
			
			
				main
			
			
		
		
							rodzic
							
								
									d5e382da26
								
							
						
					
					
						commit
						3ef56667a7
					
				
							
								
								
									
										11
									
								
								README.md
								
								
								
								
							
							
						
						
									
										11
									
								
								README.md
								
								
								
								
							|  | @ -6,6 +6,13 @@ Hi! I'm [Alexandre Villares](https://abav.lugaralgum.com), let's see if I can ma | |||
| 
 | ||||
| If you enjoy this, be a [patreon](https://patreon.com/arteprog) or make a donation [here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HCGAKACDMVNV2)  | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 316: [code](https://github.com/villares/sketch-a-day/tree/master/s316) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] | ||||
| 
 | ||||
| A 3D take on 314 | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
|  | @ -13,12 +20,16 @@ If you enjoy this, be a [patreon](https://patreon.com/arteprog) or make a donati | |||
| 
 | ||||
| 315: [GIF](s315/s315.gif) [code](https://github.com/villares/sketch-a-day/tree/master/s315) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] | ||||
| 
 | ||||
| Horizontaly connected 314 | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 314: [code](https://github.com/villares/sketch-a-day/tree/master/s314) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] | ||||
| 
 | ||||
| Isolating elements from 313 | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
|  | ||||
|  |  | |||
|  | @ -0,0 +1,42 @@ | |||
| """ | ||||
| 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 or frameCount >= 100000: | ||||
|            finish = True | ||||
|     elif frameCount >= frames: | ||||
|         finish = True | ||||
|                  | ||||
|     if finish: | ||||
|         gifExporter.finish() | ||||
|         print("gif saved") | ||||
|         exit() | ||||
|  | @ -0,0 +1,147 @@ | |||
| 
 | ||||
| def create_points(non_intersecting=True): | ||||
|     background(200) | ||||
|     done = False | ||||
|     while not done: | ||||
|         poly_points = [PVector(random(BORDER, width - BORDER), | ||||
|                                random(BORDER, height - BORDER) | ||||
|                                ) | ||||
|                        for _ in range(NUM)] | ||||
|         ed = edges(poly_points) | ||||
|         done = True | ||||
|         if non_intersecting: | ||||
|             for p1, p2 in ed[::-1]: | ||||
|                 for p3, p4 in ed[2::]: | ||||
|                     # test only non consecutive edges | ||||
|                     if (p1 != p3) and (p2 != p3) and (p1 != p4): | ||||
|                         if line_instersect(Line(p1, p2), Line(p3, p4)): | ||||
|                             done = False | ||||
|                             break | ||||
|     return poly_points | ||||
|       | ||||
| def is_inside(x, y, poly_points):    | ||||
|     min_, max_ = min_max(poly_points) | ||||
|     if x < min_.x or y < min_.y or x > max_.x or y > max_.y: | ||||
|         return False | ||||
|      | ||||
|     a = PVector(x, min_.y) | ||||
|     b = PVector(x, max_.y) | ||||
|     v_lines = inter_lines(Line(a, b), poly_points) | ||||
|     if not v_lines: | ||||
|         return False | ||||
|          | ||||
|     a = PVector(min_.x, y) | ||||
|     b = PVector(max_.x, y) | ||||
|     h_lines = inter_lines(Line(a, b), poly_points) | ||||
|     if not h_lines: | ||||
|         return False | ||||
|                  | ||||
|     for v in v_lines: | ||||
|         for h in h_lines: | ||||
|             if line_instersect(v, h): | ||||
|                 return True    | ||||
|                           | ||||
|     return False | ||||
| 
 | ||||
| 
 | ||||
| def inter_lines(L, poly_points): | ||||
|     inter_points = [] | ||||
|     for p1, p2 in edges(poly_points): | ||||
|         inter = line_instersect(Line(p1, p2), L) | ||||
|         if inter: | ||||
|             inter_points.append(inter) | ||||
|     if  not inter_points: | ||||
|         return [] | ||||
|     inter_lines = [] | ||||
|     if len(inter_points) > 1: | ||||
|         inter_points.sort() | ||||
|         pairs = zip(inter_points[::2], inter_points[1::2]) | ||||
|         for p1, p2 in pairs: | ||||
|             if p2: | ||||
|                 inter_lines.append(Line(PVector(p1.x, p1.y), | ||||
|                                         PVector(p2.x, p2.y)))  | ||||
|     return inter_lines | ||||
| 
 | ||||
|          | ||||
| class Line(): | ||||
|     """ I should change this to a named tuple... """ | ||||
|     def __init__(self, p1, p2): | ||||
|         self.p1 = p1 | ||||
|         self.p2 = p2 | ||||
|          | ||||
|     def plot(self): | ||||
|         line(self.p1.x, self.p1.y, self.p1.z, | ||||
|              self.p2.x, self.p2.y, self.p2.z) | ||||
|      | ||||
|     def lerp(self, other, t): | ||||
|         p1 = PVector.lerp(self.p1, other.p1, t) | ||||
|         p2 = PVector.lerp(self.p2, other.p2, t) | ||||
|         return Line(p1, p2) | ||||
|      | ||||
| def line_instersect(line_a, line_b):      | ||||
|     """ | ||||
|     code adapted from Bernardo Fontes  | ||||
|     https://github.com/berinhard/sketches/ | ||||
|     """ | ||||
|         | ||||
|     x1, y1 = line_a.p1.x, line_a.p1.y | ||||
|     x2, y2 = line_a.p2.x, line_a.p2.y | ||||
|     x3, y3 = line_b.p1.x, line_b.p1.y | ||||
|     x4, y4 = line_b.p2.x, line_b.p2.y | ||||
|          | ||||
|     try: | ||||
|         uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1)); | ||||
|         uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1)); | ||||
|     except ZeroDivisionError: | ||||
|         return | ||||
|          | ||||
|     if not(0 <= uA <= 1 and 0 <= uB <= 1): | ||||
|         return | ||||
|          | ||||
|     x = line_a.p1.x + uA * (line_a.p2.x - line_a.p1.x) | ||||
|     y = line_a.p1.y + uA * (line_a.p2.y - line_a.p1.y) | ||||
|          | ||||
|     return PVector(x, y) | ||||
| 
 | ||||
| 
 | ||||
| def edges(poly_points): | ||||
|     return pairwise(poly_points) + [(poly_points[-1], poly_points[0])]    | ||||
| 
 | ||||
| def pairwise(iterable): | ||||
|     import itertools | ||||
|     "s -> (s0,s1), (s1,s2), (s2, s3), ..." | ||||
|     a, b = itertools.tee(iterable) | ||||
|     next(b, None) | ||||
|     return zip(a, b)  | ||||
| 
 | ||||
| def min_max(points): | ||||
|         points = iter(points) | ||||
|         try: | ||||
|             p = points.next() | ||||
|             min_x, min_y = max_x, max_y = p.x, p.y | ||||
|         except StopIteration: | ||||
|             raise ValueError, "min_max requires at least one point" | ||||
|         for p in points: | ||||
|             if p.x < min_x: | ||||
|                 min_x = p.x | ||||
|             elif p.x > max_x: | ||||
|                 max_x = p.x | ||||
|             if p.y < min_y: | ||||
|                 min_y = p.y | ||||
|             elif p.y > max_y: | ||||
|                 max_y = p.y | ||||
|         return (PVector(min_x, min_y), | ||||
|                 PVector(max_x, max_y)) | ||||
|          | ||||
| def par_hatch(points, divisions, *sides): | ||||
|         vectors = [PVector(p.x, p.y, p.z) for p in points] | ||||
|         lines = [] | ||||
|         if not sides: sides = [0] | ||||
|         for s in sides: | ||||
|             a, b = vectors[-1 + s], vectors[+0 + s] | ||||
|             d, c = vectors[-2 + s], vectors[-3 + s] | ||||
|             for i in range(1, divisions): | ||||
|                 s0 = PVector.lerp(a, b, i/float(divisions)) | ||||
|                 s1 = PVector.lerp(d, c, i/float(divisions)) | ||||
|                 lines.append(Line(s0, s1))  | ||||
|         return lines | ||||
										
											Plik binarny nie jest wyświetlany.
										
									
								
							| Po Szerokość: | Wysokość: | Rozmiar: 722 KiB | 
|  | @ -0,0 +1,166 @@ | |||
| # Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day | ||||
| SKETCH_NAME = "s316"  # 20181109 | ||||
| OUTPUT = ".png" | ||||
| GRID_SIZE = 36 | ||||
| 
 | ||||
| from line_geometry import Line | ||||
| from line_geometry import par_hatch | ||||
| add_library('gifAnimation') | ||||
| from gif_exporter import gif_export | ||||
| 
 | ||||
| # this rule was used to choose nodes that would move on  | ||||
| # earlier regular grid deformation sketches (now it's just a random selection) | ||||
| rule = lambda x, y: random(40) < 20 | ||||
| 
 | ||||
| def setup(): | ||||
|     strokeCap(SQUARE) | ||||
|     size(700, 700, P3D) | ||||
|     init_grid(GRID_SIZE) | ||||
|     background(200) | ||||
|     ortho() | ||||
|      | ||||
| def draw(): | ||||
|     f = frameCount/5. | ||||
|     #translate(-width/2, height/2) | ||||
|     background(200) | ||||
| 
 | ||||
|     t = cos(f)/2 | ||||
|      | ||||
|     for c in Cell.cells: | ||||
|         with pushMatrix(): | ||||
|                 translate(0, c.py) | ||||
|                 rotateX(f) | ||||
|                 translate(0, -c.py) | ||||
|                 for i in range(32): | ||||
|                     c.plot(cos(i/5.)/2) | ||||
| 
 | ||||
|     # if frameCount % 10 == 0: | ||||
|     #     print(t) | ||||
|     #     for c in Cell.cells: | ||||
|     #         c.plot(t)   | ||||
|              | ||||
|     if 0 < f < TWO_PI: | ||||
|         pass | ||||
|         gif_export(GifMaker, SKETCH_NAME) | ||||
|     else: | ||||
|         # for i in range(60): | ||||
|         #     gif_export(GifMaker, SKETCH_NAME) | ||||
|         noLoop() | ||||
|         pass | ||||
| 
 | ||||
| def init_grid(grid_size): | ||||
|     Cell.border = 100. | ||||
|     Cell.spacing = (width - Cell.border *2) / grid_size | ||||
|     Cell.cells = [] | ||||
|     randomSeed(1000) | ||||
|     for x in range(0, grid_size, 4): | ||||
|         for y in range(0, grid_size, 4): | ||||
|                 new_cell = Cell(x, y) | ||||
|                 Cell.cells.append(new_cell) | ||||
|                 Cell.grid[x, y] = new_cell | ||||
|                  | ||||
|     randomSeed(frameCount+2)  | ||||
|     for x in range(-1, grid_size+1, 2): | ||||
|         for y in range(-1, grid_size+1, 2): | ||||
|                 Node.grid0[x, y] = Node(x, y)   # extrarir do dict | ||||
|                 Node.grid1[x, y] = Node(x, y)   # extrarir do dict | ||||
| 
 | ||||
| 
 | ||||
|     for c in Cell.cells: | ||||
|         c.update_vers() | ||||
|     | ||||
| class Node(): | ||||
|     grid0 = dict() | ||||
|     grid1 = dict() | ||||
| 
 | ||||
|     def __init__(self, x, y): | ||||
|         mx, my = width/2, height/2 | ||||
|         self.ix = x | ||||
|         self.iy = y | ||||
|         self.px = Cell.border + Cell.spacing + x * Cell.spacing   | ||||
|         self.py = Cell.border + Cell.spacing + y * Cell.spacing  | ||||
|         self.pz = 0 | ||||
|         if rule(x, y): | ||||
|            self.px += (self.px - mx) * 0.12  | ||||
|            self.py += (self.py - my) * 0.12 | ||||
|            self.pz = (self.px - mx) * 0.12 - (self.py - my) * 0.12 | ||||
|         self.x = self.px | ||||
|         self.y = self.py | ||||
|         self.py = 0 | ||||
|         self.z = self.pz | ||||
| 
 | ||||
| class Cell(): | ||||
|     cells = [] | ||||
|     grid = dict() | ||||
| 
 | ||||
|     def __init__(self, x, y): | ||||
|         self.ix = x | ||||
|         self.iy = y | ||||
|         self.px = Cell.border + Cell.spacing  + x * Cell.spacing  | ||||
|         self.py = Cell.border + Cell.spacing  + y * Cell.spacing  | ||||
|         self.pz = 0 | ||||
|         self.vers = [] | ||||
|         self.num_hatches = int(random(3, 6))#int(random(5, 12)) | ||||
|         self.type_hatches = random(10)       | ||||
|        | ||||
|     def plot(self, t):     | ||||
|         L0, V0 = self.lines, self.vers | ||||
|         L1, V1 = self.lines_f, self.vers_f | ||||
| 
 | ||||
|         strokeWeight(1) | ||||
|         c = lerpColor(color(160, 0, 0), | ||||
|                       color(0, 0, 100), t) | ||||
|         stroke(c)  | ||||
|         for l0, l1 in zip(L0, L1): | ||||
|             l = l0.lerp(l1, t) | ||||
|             l.plot() | ||||
|         beginShape() | ||||
|         noFill() | ||||
|         #strokeWeight(1) | ||||
|         #stroke(100, 0, 100) | ||||
|         for p0, p1 in zip(V0, V1): | ||||
|             vertex(lerp(p0.x, p1.x, t), lerp(p0.y, p1.y, t), lerp(p0.z, p1.z, t) ) | ||||
|         endShape(CLOSE) | ||||
|          | ||||
|     def update_vers(self): | ||||
|         self.v0 = Node.grid0.get((self.ix-1, self.iy-1)) | ||||
|         self.v1 = Node.grid0.get((self.ix-1, self.iy+1)) | ||||
|         self.v3 = Node.grid0.get((self.ix+1, self.iy-1)) | ||||
|         self.v2 = Node.grid0.get((self.ix+1, self.iy+1)) | ||||
|         self.vers = [self.v0, self.v1, self.v2, self.v3] | ||||
|         self.v0f = Node.grid1.get((self.ix-1, self.iy-1)) | ||||
|         self.v1f = Node.grid1.get((self.ix-1, self.iy+1)) | ||||
|         self.v3f = Node.grid1.get((self.ix+1, self.iy-1)) | ||||
|         self.v2f = Node.grid1.get((self.ix+1, self.iy+1)) | ||||
|         self.vers_f = [self.v0f, self.v1f, self.v2f, self.v3f] | ||||
|         self.hatch() | ||||
|          | ||||
|     def hatch(self): | ||||
|         self.lines = [] | ||||
|         self.lines_f = [] | ||||
|         n = self.num_hatches | ||||
|         r = self.type_hatches | ||||
|         if r > 2:                         | ||||
|             self.lines.extend(par_hatch(self.vers, n, 0)) | ||||
|             self.lines_f.extend(par_hatch(self.vers_f, n, 0)) | ||||
|         if r < 8: | ||||
|             self.lines.extend(par_hatch(self.vers, n, 1)) | ||||
|             self.lines_f.extend(par_hatch(self.vers_f, n, 1)) | ||||
|          | ||||
| def keyPressed(): | ||||
|     if key == "n" or key == CODED: | ||||
|         init_grid(GRID_SIZE) | ||||
|         background(200) | ||||
|         loop() | ||||
|         #saveFrame("###.png") | ||||
|     if key == "s": saveFrame("###.png") | ||||
| 
 | ||||
| # print text to add to the project's README.md              | ||||
| def settings(): | ||||
|     println( | ||||
| """ | ||||
|  | ||||
| 
 | ||||
| {1}: [code](https://github.com/villares/sketch-a-day/tree/master/{0}) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] | ||||
| """.format(SKETCH_NAME, SKETCH_NAME[1:], OUTPUT) | ||||
|     ) | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 Alexandre B A Villares
						Alexandre B A Villares