Pymunkでバネ(DampedSpring)を使う

シミュレーションでバネを使う例。

import sys

import pymunk
import pymunk.pygame_util
import pygame as pg
from pygame.locals import QUIT, KEYDOWN, K_ESCAPE


SCR_W, SCR_H = 200, 200
TICK = 100.


def setup_space():
    space = pymunk.Space()
    space.gravity = 0, -100
    space.damping = 0.99
    return space


def setup_pygame():
    # Initialize pygame screen for pymunk debug.
    pg.init()
    scr = pg.display.set_mode((SCR_W, SCR_H))
    clk = pg.time.Clock()
    draw_options = pymunk.pygame_util.DrawOptions(scr)
    return scr, clk, draw_options


def add_ground(space):
    b0 = space.static_body
    ground = pymunk.Segment(b0, (0, 0), (SCR_W, 0), 4)
    ground.elasticity = 1.0
    space.add(ground)
    return


def add_balls_and_spring(space):
    R = 15
    b1 = pymunk.Body(mass=1, moment=10)
    b1.position = SCR_W/4, SCR_H/2
    s1 = pymunk.Circle(b1, radius=R)
    s1.elasticity = 1.0

    b2 = pymunk.Body(mass=1, moment=10)
    b2.position = 3*SCR_W/4, SCR_H/2
    s2 = pymunk.Circle(b2, radius=R)
    s2.elasticity = 1.0

    spring = pymunk.DampedSpring(b1, b2, (0, 0), (0, 0),
                                 rest_length=50, stiffness=100, damping=1.0)
    space.add(b1, s1, b2, s2, spring)
    return


def run():
    # Initialize Pygame and Pymunk
    scr, clk, draw_options = setup_pygame()  # Pygame setup
    space = setup_space()  # Pymunk setup

    # Add objects
    add_ground(space)
    add_balls_and_spring(space)

    # Run simulation
    t = 0
    while True:
        for e in pg.event.get():
            if e.type == QUIT:
                sys.exit(0)
            elif e.type == KEYDOWN and e.key == K_ESCAPE:
                sys.exit(0)
        scr.fill((20, 20, 20))
        space.debug_draw(draw_options)
        space.step(1/TICK)
        pg.display.flip()
        clk.tick(TICK)
        pg.image.save(scr, f'./images/scr_{t:04}.png')
        t += 1
    pg.quit()


if __name__ == '__main__':
    run()

f:id:nobUnaga:20200325172955g:plain
sample