### Sesc Av. Paulista ## Grupo de estudos em Python #### `hackmd.io/@sesc-av-paulista/estudos-em-python-24-abril` # Simulações físicas 2D (com [PyMunk](https://pymunk.org)) Primeiro exemplo (bolinhas e uma parede fixa) ![image](https://hackmd.io/_uploads/S13AS-uJeg.png) ```python= import pymunk bolinhas = [] # lista vazia paredes = [] space = pymunk.Space() space.gravity = 0, 900 def setup(): size(600, 600) acrescenta_parede(100, 500, 500, 500) def acrescenta_bola(x, y): corpo = pymunk.Body(10, 100) corpo.position = x, y forma = pymunk.Circle(corpo, 10, (0, 0)) forma.friction = 0.99 space.add(corpo, forma) bolinhas.append(forma) def acrescenta_parede(xa, ya, xb, yb): forma = pymunk.Segment(space.static_body, (xa, ya), (xb, yb), radius=1.5) forma.friction = 100.99 space.add(forma) paredes.append(forma) def draw(): # fica repetindo background(0, 0, 200) # R, G, B for bola in bolinhas: r = bola.radius pos = bola.body.position no_stroke() fill(0) circle(pos.x, pos.y, r * 2) for parede in paredes: stroke(128) stroke_weight(3) corpo = parede.body angulo = corpo.angle inicio = corpo.position + parede.a.rotated(angulo) final = corpo.position + parede.b.rotated(angulo) line(inicio.x, inicio.y, final.x, final.y) if is_key_pressed and key_code == SHIFT: acrescenta_bola(mouse_x + random(-1, 1), mouse_y) print(len(space.shapes)) space.step(1 / 60) def mouse_pressed(): acrescenta_bola(mouse_x + random(-1, 1), mouse_y) def key_pressed(): if key == DELETE and paredes: ultima_parede = paredes.pop() space.shapes.remove(ultima_parede) ``` Final ![image](https://hackmd.io/_uploads/rJZnabu1ex.png) ```python= # Código para py5 "imported mode" precisa de um "sketch runner" # Saiba mais em: https://abav.lugaralgum.com/como-instalar-py5/ import pymunk space = pymunk.Space() space.gravity = 0, 900 bolinhas = [] paredes = [] inicio_nova_parede = None def setup(): size(600, 600) acrescenta_parede(100, 500, 500, 500) def acrescenta_bola(x, y): corpo = pymunk.Body(10, 100) corpo.position = x, y forma = pymunk.Circle(corpo, 10, (0, 0)) forma.friction = 0.99 space.add(corpo, forma) bolinhas.append(forma) def acrescenta_parede(xa, ya, xb, yb): forma = pymunk.Segment(space.static_body, (xa, ya), (xb, yb), radius=1.5) forma.friction = 100.99 space.add(forma) paredes.append(forma) def draw(): # fica repetindo background(0, 0, 200) # R, G, B for bola in bolinhas.copy(): r = bola.radius pos = bola.body.position no_stroke() fill(0) circle(pos.x, pos.y, r * 2) # remover bolas que cairam pra baixo da tela if pos.y > height + 50: bolinhas.remove(bola) space.remove(bola) # desenhar linhas-parede (simplifiquei!) for parede in paredes: stroke(128) stroke_weight(3) line(parede.a.x, parede.a.y, parede.b.x, parede.b.y) # muitas bolas novas if is_key_pressed and key_code == SHIFT: acrescenta_bola(mouse_x + random(-1, 1), mouse_y) # mostra preview da parede sendo desenhada if inicio_nova_parede: stroke(255, 0, 0) # linha vermelha line(*inicio_nova_parede, mouse_x, mouse_y) # avança um passo da simulação space.step(1 / 60) def mouse_pressed(): global inicio_nova_parede if key_code == CONTROL: acrescenta_bola(mouse_x + random(-1, 1), mouse_y) else: inicio_nova_parede = (mouse_x, mouse_y) def mouse_released(): global inicio_nova_parede if (inicio_nova_parede and dist(*inicio_nova_parede, mouse_x, mouse_y) > 5): inicio_x, inicio_y = inicio_nova_parede acrescenta_parede(inicio_x, inicio_y, mouse_x, mouse_y) inicio_nova_parede = None def key_pressed(): global inicio_nova_parede, space, bolinhas, paredes # tecla DELETE apaga paredes if key == DELETE and inicio_nova_parede: inicio_nova_parede = None elif key == DELETE and paredes: ultima_parede = paredes.pop() space.remove(ultima_parede) # "c" limpa bolas elif key == 'c' or key == 'C': for bola in bolinhas.copy(): bolinhas.remove(bola) space.remove(bola) # "s" salva estado da simulação elif key == 's': save_pickle((space, bolinhas, paredes), 'space.data') print('salvo') # "l" (de "load") recarrega estado salvo elif key == 'l': if Path('space.data').is_file(): space, bolinhas, paredes = load_pickle('space.data') print(f'objetos simulados: {len(space.shapes)}') ```