PymunkでPinJointを使う例

振り子運動のようなケースをシミュレーションしたい場合。 PymunkのExampleには複数の振り子を同時にシミュレーションする例(newton_cradle)があるが,単純に1つの場合の例。 初期のBodyとPinのアンカー配置で紐の長さが変わる。

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_pinjoint_ball(space):
    R = 20
    b = pymunk.Body(mass=1, moment=10)
    b.position = SCR_W/4, SCR_H/2
    s = pymunk.Circle(b, radius=R)
    pin_joint = pymunk.PinJoint(space.static_body, b, (SCR_W/2, SCR_H), (0, 0))
    space.add(b, s, pin_joint)
    return


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

    # Add objects
    add_pinjoint_ball(space)

    # Run simulation
    i = 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_{i:04}.png')
        i += 1
    pg.quit()


if __name__ == '__main__':
    run()

f:id:nobUnaga:20200325172624g:plain