kopia lustrzana https://github.com/villares/sketch-a-day
				
				
				
			190307
							rodzic
							
								
									abc03011c2
								
							
						
					
					
						commit
						d4c18092d3
					
				|  | @ -0,0 +1,165 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| ROTATION = {0: 0, | ||||
|             BOTTOM: 0, | ||||
|             DOWN: 0, | ||||
|             1: HALF_PI, | ||||
|             LEFT: HALF_PI, | ||||
|             2: PI, | ||||
|             TOP: PI, | ||||
|             UP: PI, | ||||
|             3: PI + HALF_PI, | ||||
|             RIGHT: PI + HALF_PI, | ||||
|             BOTTOM + RIGHT: 0, | ||||
|             DOWN + RIGHT: 0, | ||||
|             DOWN + LEFT: HALF_PI, | ||||
|             BOTTOM + LEFT: HALF_PI, | ||||
|             TOP + LEFT: PI, | ||||
|             UP + LEFT: PI, | ||||
|             TOP + RIGHT: PI + HALF_PI, | ||||
|             UP + RIGHT: PI + HALF_PI, | ||||
|             } | ||||
| 
 | ||||
| def quarter_circle(x, y, radius, quadrant): | ||||
|     circle_arc(x, y, radius, ROTATION[quadrant], HALF_PI) | ||||
| 
 | ||||
| def half_circle(x, y, radius, quadrant): | ||||
|     circle_arc(x, y, radius, ROTATION[quadrant], PI) | ||||
| 
 | ||||
| def circle_arc(x, y, radius, start_ang, sweep_ang): | ||||
|     arc(x, y, radius * 2, radius * 2, start_ang, start_ang + sweep_ang) | ||||
| 
 | ||||
| def poly_arc(x, y, radius, start_ang, sweep_ang, num_points=2): | ||||
|     angle = sweep_ang / int(num_points) | ||||
|     a = start_ang | ||||
|     with beginShape(): | ||||
|         while a <= start_ang + sweep_ang: | ||||
|             sx = x + cos(a) * radius | ||||
|             sy = y + sin(a) * radius | ||||
|             vertex(sx, sy) | ||||
|             a += angle | ||||
| 
 | ||||
| def arc_poly(x, y, d, _, start_ang, end_ang, num_points=5): | ||||
|     sweep_ang = end_ang - start_ang | ||||
|     angle = sweep_ang / int(num_points) | ||||
|     a = start_ang | ||||
|     with beginShape(): | ||||
|         while a <= end_ang: | ||||
|             sx = x + cos(a) * d / 2 | ||||
|             sy = y + sin(a) * d / 2 | ||||
|             vertex(sx, sy) | ||||
|             a += angle | ||||
| 
 | ||||
| def poly_rounded2(p_list, r_list): | ||||
|     """ | ||||
|     draws a 'filleted' polygon with variable radius | ||||
|     dependent on roundedCorner() | ||||
|     """ | ||||
|     with pushStyle(): | ||||
|         noStroke() | ||||
|         beginShape() | ||||
|         for p0, p1 in zip(p_list, [p_list[-1]] + p_list[:-1]): | ||||
|             m = (PVector(p0.x, p0.y) + PVector(p1.x, p1.y)) / 2 | ||||
|             vertex(m.x, m.y) | ||||
|         endShape(CLOSE) | ||||
|     for p0, p1, p2, r in zip(p_list, | ||||
|                              [p_list[-1]] + p_list[:-1], | ||||
|                              [p_list[-2]] + [p_list[-1]] + p_list[:-2], | ||||
|                              [r_list[-1]] + r_list[:-1] | ||||
|                              ): | ||||
|         m1 = (PVector(p0.x, p0.y) + PVector(p1.x, p1.y)) / 2 | ||||
|         m2 = (PVector(p2.x, p2.y) + PVector(p1.x, p1.y)) / 2 | ||||
|         roundedCorner(p1, m1, m2, r) | ||||
| 
 | ||||
| 
 | ||||
| def roundedCorner(pc, p1, p2, r): | ||||
|     """ | ||||
|     Based on Stackoverflow C# rounded corner post  | ||||
|     https://stackoverflow.com/questions/24771828/algorithm-for-creating-rounded-corners-in-a-polygon | ||||
|     """ | ||||
|     # Vector 1 | ||||
|     dx1 = pc.x - p1.x | ||||
|     dy1 = pc.y - p1.y | ||||
| 
 | ||||
|     # Vector 2 | ||||
|     dx2 = pc.x - p2.x | ||||
|     dy2 = pc.y - p2.y | ||||
| 
 | ||||
|     # Angle between vector 1 and vector 2 divided by 2 | ||||
|     angle = (atan2(dy1, dx1) - atan2(dy2, dx2)) / 2 | ||||
| 
 | ||||
|     # The length of segment between angular point and the | ||||
|     # points of intersection with the circle of a given radius | ||||
|     tng = abs(tan(angle)) | ||||
|     segment = r / tng if tng != 0 else r | ||||
| 
 | ||||
|     # Check the segment | ||||
|     length1 = GetLength(dx1, dy1) | ||||
|     length2 = GetLength(dx2, dy2) | ||||
| 
 | ||||
|     min_len = min(length1, length2) | ||||
| 
 | ||||
|     if segment > min_len: | ||||
|         segment = min_len | ||||
|         max_r = min_len * abs(tan(angle)) | ||||
|     else: | ||||
|         max_r = r | ||||
| 
 | ||||
|     # Points of intersection are calculated by the proportion between | ||||
|     # the coordinates of the vector, length of vector and the length of the | ||||
|     # segment. | ||||
|     p1Cross = GetProportionPoint(pc, segment, length1, dx1, dy1) | ||||
|     p2Cross = GetProportionPoint(pc, segment, length2, dx2, dy2) | ||||
| 
 | ||||
|     # Calculation of the coordinates of the circle | ||||
|     # center by the addition of angular vectors. | ||||
|     dx = pc.x * 2 - p1Cross.x - p2Cross.x | ||||
|     dy = pc.y * 2 - p1Cross.y - p2Cross.y | ||||
| 
 | ||||
|     L = GetLength(dx, dy) | ||||
|     d = GetLength(segment, max_r) | ||||
| 
 | ||||
|     circlePoint = GetProportionPoint(pc, d, L, dx, dy) | ||||
| 
 | ||||
|     # StartAngle and EndAngle of arc | ||||
|     startAngle = atan2(p1Cross.y - circlePoint.y, p1Cross.x - circlePoint.x) | ||||
|     endAngle = atan2(p2Cross.y - circlePoint.y, p2Cross.x - circlePoint.x) | ||||
| 
 | ||||
|     # Sweep angle | ||||
|     sweepAngle = endAngle - startAngle | ||||
| 
 | ||||
|     # Some additional checks | ||||
|     if sweepAngle < 0: | ||||
|         startAngle, endAngle = endAngle, startAngle | ||||
|         sweepAngle = -sweepAngle | ||||
| 
 | ||||
|     if sweepAngle > PI: | ||||
|         startAngle, endAngle = endAngle, startAngle | ||||
|         sweepAngle = TWO_PI - sweepAngle | ||||
| 
 | ||||
|     # Draw result using graphics | ||||
|     # noStroke() | ||||
|     with pushStyle(): | ||||
|         noStroke() | ||||
|         beginShape() | ||||
|         vertex(p1.x, p1.y) | ||||
|         vertex(p1Cross.x, p1Cross.y) | ||||
|         vertex(p2Cross.x, p2Cross.y) | ||||
|         vertex(p2.x, p2.y) | ||||
|         endShape(CLOSE) | ||||
| 
 | ||||
|     line(p1.x, p1.y, p1Cross.x, p1Cross.y) | ||||
|     line(p2.x, p2.y, p2Cross.x, p2Cross.y) | ||||
|     arc(circlePoint.x, circlePoint.y, 2 * max_r, 2 * max_r, | ||||
|         startAngle, startAngle + sweepAngle, OPEN) | ||||
| 
 | ||||
| def GetLength(dx, dy): | ||||
|     return sqrt(dx * dx + dy * dy) | ||||
| 
 | ||||
| def GetProportionPoint(pt, segment, L, dx, dy): | ||||
|     # factor = segment / L if L != 0 else 0 | ||||
|     factor = float(segment) / L if L != 0 else segment | ||||
|     return PVector( | ||||
|         (pt.x - dx * factor), | ||||
| 
 | ||||
|         (pt.y - dy * factor)) | ||||
|  | @ -0,0 +1,43 @@ | |||
| """ | ||||
| Alexandre B A Villares http://abav.lugaralgum.com - GPL v3  | ||||
| 
 | ||||
| A helper for the Processing gifAnimation library (https://github.com/jordanorelli) | ||||
| ported to Processing 3 by 01010101 (https://github.com/01010101) | ||||
| Download the library from https://github.com/01010101/GifAnimation/archive/master.zip | ||||
| This helper was inspired by an example by Art Simon https://github.com/APCSPrinciples/AnimatedGIF/ | ||||
| 
 | ||||
| Put  at the start of your sketch: | ||||
|    add_library('gifAnimation') | ||||
|    from gif_exporter import gif_export | ||||
| and 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=170,            # this is quick | ||||
|                frames=0):            # 0 will stop on keyPressed or frameCount >= 100000 | ||||
|     global gifExporter | ||||
|     try: | ||||
|         gifExporter | ||||
|     except NameError: | ||||
|         gifExporter = GifMaker(this, filename + ".gif") | ||||
|         gifExporter.setRepeat(repeat) | ||||
|         gifExporter.setQuality(quality) | ||||
|         gifExporter.setDelay(delay) | ||||
|         gif_export._frame = frameCount | ||||
|         print("gif start") | ||||
| 
 | ||||
|     gifExporter.addFrame() | ||||
| 
 | ||||
|     if (frames == 0 and keyPressed or frameCount - gif_export._frame >= 100000) \ | ||||
|             or (frames != 0 and frameCount - gif_export._frame >= frames): | ||||
|         gifExporter.finish() | ||||
|         background(255) | ||||
|         print("gif saved") | ||||
|         del(gifExporter) | ||||
|         return False | ||||
|     else: | ||||
|         return True | ||||
|  | @ -0,0 +1,102 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from random import choice | ||||
| from arcs import * | ||||
| 
 | ||||
| TAM_PONTO = 30  # TAM_PONTO dos Pontos  | ||||
| 
 | ||||
| class Ponto(): | ||||
|     VEL_MAX = 5 | ||||
|     SET = set() | ||||
| 
 | ||||
|     " Pontos num grafo, VEL_MAX inicial sorteada, criam Arestas com outros Pontos " | ||||
| 
 | ||||
|     def __init__(self, x, y, cor=color(0)): | ||||
|         VEL_MAX = Ponto.VEL_MAX | ||||
|         self.x = x | ||||
|         self.y = y | ||||
|         self.z = 0  # para compatibilidade com PVector... | ||||
|         self.vx = random(-VEL_MAX, VEL_MAX) | ||||
|         self.vy = random(-VEL_MAX, VEL_MAX) | ||||
|         colorMode(HSB) | ||||
|         self.cor = color(random(256), 255, 255) | ||||
|         self.cria_arestas() | ||||
|         self.r = choice((10, 20, 40)) | ||||
|          | ||||
|     def __getitem__(self, i): | ||||
|         return (self.x, self.y, self.z)[i] | ||||
| 
 | ||||
|     def desenha(self): | ||||
|         pass | ||||
|         # noStroke() | ||||
|         # stroke(255) | ||||
|         # noFill() | ||||
|         # ellipse(self.x, self.y, TAM_PONTO, TAM_PONTO) | ||||
| 
 | ||||
|     def move(self, VEL_MAX): | ||||
|         Ponto.VEL_MAX = VEL_MAX | ||||
|         self.x += self.vx | ||||
|         self.y += self.vy | ||||
|         if not (0 < self.x < width): | ||||
|             self.vx = -self.vx | ||||
|         if not (0 < self.y < height): | ||||
|             self.vy = -self.vy | ||||
|         self.vx = self.limitar(self.vx, VEL_MAX) | ||||
|         self.vy = self.limitar(self.vy, VEL_MAX) | ||||
| 
 | ||||
|     def cria_arestas(self): | ||||
|             lista_pontos = list(Ponto.SET) | ||||
|             if len(lista_pontos) > 1: | ||||
|                 rnd_ponto = choice(lista_pontos) | ||||
|                 while rnd_ponto == self: | ||||
|                     rnd_ponto = choice(lista_pontos) | ||||
|              | ||||
|                 Aresta.ARESTAS.append(Aresta(rnd_ponto, self)) | ||||
| 
 | ||||
|     def limitar(self, v, v_max): | ||||
|         if v > v_max: | ||||
|             return v_max | ||||
|         elif v < -v_max: | ||||
|             return -v_max | ||||
|         else: | ||||
|             return v | ||||
| 
 | ||||
| 
 | ||||
| class Aresta(): | ||||
| 
 | ||||
|     """ Arestas contém só dois Pontos """             | ||||
| 
 | ||||
|     ARESTAS = [] | ||||
| 
 | ||||
|     def __init__(self, p1, p2): | ||||
|         self.p1 = p1 | ||||
|         self.p2 = p2 | ||||
| 
 | ||||
|     def desenha(self): | ||||
|         strokeWeight(2) | ||||
|         fill(lerpColor(self.p1.cor, self.p2.cor, 0.5)) | ||||
|         stroke(0) | ||||
|         var_bar(self.p1.x, self.p1.y, self.p2.x, self.p2.y, | ||||
|                 self.p1.r, self.p2.r) | ||||
|         noStroke() | ||||
|         fill(0) | ||||
|         # fill(self.p1.cor) | ||||
|         ellipse(self.p1.x, self.p1.y, TAM_PONTO / 4, TAM_PONTO / 4) | ||||
|         # fill(self.p2.cor) | ||||
|         ellipse(self.p2.x, self.p2.y, TAM_PONTO / 4, TAM_PONTO / 4) | ||||
| 
 | ||||
|     def puxa_empurra(self, TAM_BARRA): | ||||
|         d = dist(self.p1.x, self.p1.y, self.p2.x, self.p2.y) | ||||
|         delta = TAM_BARRA - d | ||||
|         dir = PVector.sub(self.p1, self.p2) | ||||
|         dir.mult(delta / 1000) | ||||
|         self.p1.vx = self.p1.vx + dir.x | ||||
|         self.p1.vy = self.p1.vy + dir.y | ||||
|         self.p2.vx = self.p2.vx - dir.x | ||||
|         self.p2.vy = self.p2.vy - dir.y | ||||
| 
 | ||||
| # def rnd_choice(collection): | ||||
| #     if collection: | ||||
| #         i = int(random(len(collection))) | ||||
| #         return collection[i] | ||||
| #     else: | ||||
| #         return None | ||||
|  | @ -0,0 +1,195 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| from javax.swing import JOptionPane | ||||
| 
 | ||||
| """ | ||||
| This will hpefully switch between Arduino (Firmata) variable input and | ||||
| nice sliders based on Peter Farell's Sliders htts://twitter.com/hackingmath | ||||
| https://github.com/hackingmath/python-sliders http://farrellpolymath.com/ | ||||
| """ | ||||
| class Input: | ||||
| 
 | ||||
|     def __init__(self, Arduino=None): | ||||
|         if Arduino: | ||||
|             self.select_source(Arduino) | ||||
|         else: | ||||
|             self.source = 0 | ||||
|         if self.source > 0: | ||||
|             self.arduino = Arduino(this, Arduino.list()[self.source], 57600) | ||||
|         else: | ||||
|             # start, end, default | ||||
|             A = Slider(0, 1023, 32) | ||||
|             B = Slider(0, 1023, 32) | ||||
|             C = Slider(0, 1023, 32) | ||||
|             D = Slider(0, 1023, 32) | ||||
|             A.position(40, height - 70) | ||||
|             B.position(40, height - 30) | ||||
|             C.position(width - 140, height - 70) | ||||
|             D.position(width - 140, height - 30) | ||||
|             self.sliders = {1: A, 2: B, 3: C, 4: D} | ||||
| 
 | ||||
|     def analog(self, pin): | ||||
|         if self.source: | ||||
|             return self.arduino.analogRead(pin) | ||||
|         else: | ||||
|             return self.sliders[pin].val | ||||
| 
 | ||||
|     def update(self): | ||||
|         if not self.source: | ||||
|             for pin, slider in self.sliders.iteritems(): | ||||
|                 slider.update() | ||||
| 
 | ||||
|     def keyPressed(self): | ||||
|         if key == 'a': | ||||
|             self.sliders[1].down = True | ||||
|         if key == 'd': | ||||
|             self.sliders[1].up = True | ||||
|         if key == 's': | ||||
|             self.sliders[2].down = True | ||||
|         if key == 'w': | ||||
|             self.sliders[2].up = True | ||||
|         if keyCode == LEFT: | ||||
|             self.sliders[3].down = True | ||||
|         if keyCode == RIGHT: | ||||
|             self.sliders[3].up = True | ||||
|         if keyCode == DOWN: | ||||
|             self.sliders[4].down = True | ||||
|         if keyCode == UP: | ||||
|             self.sliders[4].up = True | ||||
| 
 | ||||
|     def keyReleased(self): | ||||
|         if key == 'a': | ||||
|             self.sliders[1].down = False | ||||
|         if key == 'd': | ||||
|             self.sliders[1].up = False | ||||
|         if key == 's': | ||||
|             self.sliders[2].down = False | ||||
|         if key == 'w': | ||||
|             self.sliders[2].up = False | ||||
|         if keyCode == LEFT: | ||||
|             self.sliders[3].down = False | ||||
|         if keyCode == RIGHT: | ||||
|             self.sliders[3].up = False | ||||
|         if keyCode == DOWN: | ||||
|             self.sliders[4].down = False | ||||
|         if keyCode == UP: | ||||
|             self.sliders[4].up = False | ||||
| 
 | ||||
|     def digital(self, pin): | ||||
|         space_pressed = keyPressed and key == ' ' | ||||
|         if self.source: | ||||
|             if pin == 13: | ||||
|                 return self.arduino.digitalRead(13) or space_pressed | ||||
|             else: | ||||
|                 return arduino.digitalRead(pin) | ||||
|         else: | ||||
|             return space_pressed | ||||
| 
 | ||||
|     def select_source(self, Arduino): | ||||
|         # Input.Arduino = Arduino  # to make available on this module | ||||
|         port_list = [str(num) + ": " + port for num, port | ||||
|                      in enumerate(Arduino.list())] | ||||
|         if not port_list: | ||||
|             port_list.append(None) | ||||
|         self.source = option_pane("O seu Arduino está conectado?", | ||||
|                                   "Escolha a porta ou pressione Cancel\npara usar 'sliders':", | ||||
|                                   port_list, | ||||
|                                   -1)  # index for default option | ||||
|         self.help() | ||||
| 
 | ||||
|     def help(self): | ||||
|         if self.source: | ||||
|             message = """   Teclas: | ||||
|             'h' para esta ajuda | ||||
|             'p' para salvar uma imagem | ||||
|             'g' para salvar um GIF | ||||
|             Tombe a lousa para lousa para limpar o desenho!""" | ||||
|         else: | ||||
|             message = """    Teclas: | ||||
|             'h' para esta ajuda | ||||
|             'p' para salvar uma imagem | ||||
|             'g' para salvar um GIF | ||||
|             'a' (-) ou 'd' (+) para o slider 1 | ||||
|             's' (-) ou 'w' (+) para o slider 2 | ||||
|              ←(-) ou  → (+) para o slider 3 | ||||
|              ↓  (-) ou  ↑  (+) para o slider 4 | ||||
|             [barra de espaço] para limpar o desenho""" | ||||
|         ok = JOptionPane.showMessageDialog(None, message) | ||||
| 
 | ||||
| 
 | ||||
| def option_pane(title, message, options, default=None, index_only=True): | ||||
| 
 | ||||
|     if default == None: | ||||
|         default = options[0] | ||||
|     elif index_only: | ||||
|         default = options[default] | ||||
| 
 | ||||
|     selection = JOptionPane.showInputDialog( | ||||
|         frame, | ||||
|         message, | ||||
|         title, | ||||
|         JOptionPane.INFORMATION_MESSAGE, | ||||
|         None,  # for Java null | ||||
|         options, | ||||
|         default)  # must be in options, otherwise 1st is shown | ||||
|     if selection: | ||||
|         if index_only: | ||||
|             return options.index(selection) | ||||
|         else: | ||||
|             return selection | ||||
| 
 | ||||
| class Slider: | ||||
| 
 | ||||
|     SLIDERS = [] | ||||
| 
 | ||||
|     def __init__(self, low, high, default): | ||||
|         '''slider has range from low to high | ||||
|         and is set to default''' | ||||
|         self.low = low | ||||
|         self.high = high | ||||
|         self.val = default | ||||
|         self.clicked = False | ||||
|         self.up, self.down = False, False | ||||
|         Slider.SLIDERS.append(self) | ||||
| 
 | ||||
|     def position(self, x, y): | ||||
|         '''slider's position on screen''' | ||||
|         self.x = x | ||||
|         self.y = y | ||||
|         # the position of the rect you slide: | ||||
|         self.rectx = self.x + map(self.val, self.low, self.high, 0, 120) | ||||
|         self.recty = self.y - 10 | ||||
| 
 | ||||
|     def update(self): | ||||
|         '''updates the slider''' | ||||
|         pushStyle() | ||||
|         rectMode(CENTER) | ||||
|         # black translucid rect behind slider | ||||
|         fill(0, 100) | ||||
|         noStroke() | ||||
|         rect(self.x + 60, self.y, 130, 20) | ||||
|         # gray line behind slider | ||||
|         strokeWeight(4) | ||||
|         stroke(200) | ||||
|         line(self.x, self.y, self.x + 120, self.y) | ||||
|         # press mouse to move slider | ||||
|         if (self.x < mouseX < self.x + 120 and | ||||
|                 self.y < mouseY < self.y + 20): | ||||
|             fill(250) | ||||
|             textSize(10) | ||||
|             text(str(int(self.val)), self.rectx, self.recty + 35) | ||||
|             if mousePressed: | ||||
|                 self.rectx = mouseX | ||||
|         # key usage | ||||
|         if self.up: | ||||
|             self.rectx += 1 | ||||
|         if self.down: | ||||
|             self.rectx -= 1 | ||||
|         # constrain rectangle | ||||
|         self.rectx = constrain(self.rectx, self.x, self.x + 120) | ||||
|         # draw rectangle | ||||
|         strokeWeight(1) | ||||
|         fill(255) | ||||
|         rect(self.rectx, self.recty + 10, 10, 20) | ||||
|         self.val = map(self.rectx, self.x, self.x + 120, self.low, self.high) | ||||
|         popStyle() | ||||
										
											Plik binarny nie jest wyświetlany.
										
									
								
							| Po Szerokość: | Wysokość: | Rozmiar: 1.1 MiB | 
|  | @ -0,0 +1,116 @@ | |||
| # Alexandre B A Villares - https://abav.lugaralgum.com/sketch-a-day | ||||
| SKETCH_NAME = "sketch_190307a"  # based on s096 of 180406 | ||||
| 
 | ||||
| add_library('GifAnimation') | ||||
| 
 | ||||
| from gif_exporter import * | ||||
| from graphs import * | ||||
| from inputs import Input | ||||
| from arcs import poly_rounded2 | ||||
| 
 | ||||
| def setup(): | ||||
|     global input, GIF_EXPORT | ||||
|     size(600, 600) | ||||
|     frameRate(30) | ||||
|     GIF_EXPORT = False | ||||
|     # Ask user for Arduino port, uses slider if none is selected` | ||||
|     input = Input() | ||||
| 
 | ||||
|     Ponto.SET = set() | ||||
|     NUM_PONTOS = int(input.analog(2) / 4) | ||||
|     for _ in range(NUM_PONTOS): | ||||
|         Ponto.SET.add(Ponto(width / 2, height / 2)) | ||||
| 
 | ||||
| def draw(): | ||||
|     background(200) | ||||
| 
 | ||||
|     TAM_ARESTA = input.analog(1) / 4 | ||||
|     NUM_PONTOS = int(input.analog(2) / 4) | ||||
|     VEL_MAX = input.analog(3) / 128 | ||||
|     CONNECT_RATE = 0.5 + input.analog(4) / 256  # % of connections | ||||
| 
 | ||||
|     # para cada ponto | ||||
|     p_list, r_list = [], [] | ||||
|     for ponto in Ponto.SET: | ||||
|         ponto.move(VEL_MAX)    # atualiza posição | ||||
|         p_list.append(ponto) | ||||
|         r_list.append(ponto.r) | ||||
|     noFill() | ||||
|     strokeWeight(3) | ||||
|     poly_rounded2(p_list, r_list) | ||||
| 
 | ||||
|     # checa arestas, se OK desenhar, se nãotem pontos removidos ou iguais | ||||
|     pontos_com_arestas = set()  # para guardar pontos com aresta | ||||
|     for aresta in Aresta.ARESTAS: | ||||
|         if (aresta.p1 not in Ponto.SET) or (aresta.p2 not in Ponto.SET)\ | ||||
|                 or (aresta.p1 is aresta.p2):  # arestas degeneradas | ||||
|             Aresta.ARESTAS.remove(aresta)   # remove a aresta | ||||
|         else:                # senão, tudo OK! | ||||
|             #aresta.desenha()  # desenha a linha | ||||
|             aresta.puxa_empurra(TAM_ARESTA)  # altera a velocidade dos pontos | ||||
|             # Adiciona ao conjunto de pontos com aresta | ||||
|             pontos_com_arestas.update([aresta.p1, aresta.p2]) | ||||
| 
 | ||||
|     pontos_sem_arestas = Ponto.SET - pontos_com_arestas | ||||
|     # print(len(Ponto.SET), len(pontos_sem_arestas), len(pontos_com_arestas)) | ||||
|     # atualiza número de pontos | ||||
|     quantidade_atual_de_pontos = len(Ponto.SET) | ||||
|     if NUM_PONTOS > quantidade_atual_de_pontos: | ||||
|         Ponto.SET.add(Ponto(random(width), random(height))) | ||||
|     elif NUM_PONTOS < quantidade_atual_de_pontos - 2: | ||||
|         if pontos_sem_arestas: | ||||
|             # remove um ponto sem aresta | ||||
|             Ponto.SET.remove(pontos_sem_arestas.pop()) | ||||
|         else: | ||||
|             Ponto.SET.pop()  # remove um ponto qualquer | ||||
|     # outra maneira de eliminar pontos solitários é criando arestas | ||||
|     if pontos_sem_arestas: | ||||
|         for ponto in pontos_sem_arestas: | ||||
|             ponto.cria_arestas() | ||||
|     # atualiza número de arestas | ||||
|     if int((NUM_PONTOS) * CONNECT_RATE) > len(Aresta.ARESTAS) + 1: | ||||
|         if pontos_sem_arestas:   # preferência por pontos solitários | ||||
|             choice(list(pontos_sem_arestas)).cria_arestas() | ||||
|         else: | ||||
|             choice(list(Ponto.SET)).cria_arestas() | ||||
|     elif int(NUM_PONTOS * CONNECT_RATE) < len(Aresta.ARESTAS) - 1: | ||||
|         Aresta.ARESTAS.remove(choice(Aresta.ARESTAS)) | ||||
| 
 | ||||
|     if input.digital(13): | ||||
|         # Ponto.reset(int(input.analog(2) / 4)) | ||||
|         Ponto.SET = set() | ||||
|         for _ in range(NUM_PONTOS): | ||||
|             Ponto.SET.add(Ponto(width / 2, height / 2)) | ||||
| 
 | ||||
|     # uncomment next lines to export GIF | ||||
|     global GIF_EXPORT | ||||
|     if not frameCount % 5 and GIF_EXPORT: | ||||
|         GIF_EXPORT = gif_export(GifMaker, | ||||
|                                 frames=1000, | ||||
|                                 delay=300, | ||||
|                                 filename=SKETCH_NAME) | ||||
| 
 | ||||
|     # Updates reading or draws sliders and checks mouse dragging / keystrokes | ||||
|     input.update() | ||||
| 
 | ||||
| def mouseDragged():        # quando o mouse é arrastado | ||||
|     for ponto in Ponto.SET:   # para cada Ponto checa distância do mouse | ||||
|         if dist(mouseX, mouseY, ponto.x, ponto.y) < TAM_PONTO / 2: | ||||
|             # move o Ponto para posição do mouse | ||||
|             ponto.x, ponto.y = mouseX, mouseY | ||||
|             ponto.vx = 0 | ||||
|             ponto.vy = 0 | ||||
| 
 | ||||
| def keyPressed(): | ||||
|     global GIF_EXPORT | ||||
|     if key == 'p':  # save PNG | ||||
|         saveFrame("####.png") | ||||
|     if key == 'g':  # save GIF | ||||
|         GIF_EXPORT = True | ||||
|     if key == 'h': | ||||
|         input.help() | ||||
| 
 | ||||
|     input.keyPressed() | ||||
| 
 | ||||
| def keyReleased(): | ||||
|     input.keyReleased() | ||||
|  | @ -23,6 +23,15 @@ Get updates from my sort-of-weekly newsletter: [[sketch-mail](https://tinyletter | |||
| 
 | ||||
| ## 2019 | ||||
| 
 | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| [sketch_190307a](https://github.com/villares/sketch-a-day/tree/master/2019/sketch_190307a) [[Py.Processing](https://villares.github.io/como-instalar-o-processing-modo-python/index-EN)] | ||||
| 
 | ||||
| An graph much like the ones before this, but made invisible, is behind the (virtual) corners of this rounded poly. | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
|  | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 villares
						villares