In [1]:
import sys
sys.path.insert(1,'c:/code/gh/pymunk')

In [2]:
#%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib import animation
from IPython.display import HTML

In [3]:
import pymunk
from pymunk.vec2d import Vec2d
import pymunk.matplotlib_util


Loading chipmunk for Windows (64bit) [c:\code\gh\pymunk\pymunk\chipmunk64.dll]

In [4]:
def setup_space():
    space = pymunk.Space()
    space.gravity = 0,-9820
    space.damping = 0.99
    return space

In [5]:
def setup_balls(space):
    width = 600
    height = 600
    for x in range(-100,150,50):
        x += width / 2
        offset_y = height/2
        mass = 10
        radius = 25
        moment = pymunk.moment_for_circle(mass, 0, radius, (0,0))
        body = pymunk.Body(mass, moment)
        body.position = x, -125+offset_y
        body.start_position = Vec2d(body.position)
        shape = pymunk.Circle(body, radius)
        shape.elasticity = 0.9999999
        space.add(body, shape)
        pj = pymunk.PinJoint(space.static_body, body, (x, 125+offset_y), (0,0))
        space.add(pj)

We reuse the debug drawing code from pymunk.matplotlib_util. Currently this is not optimal since it doesnt reuse the artists added to the axes, instead we have to clear the axes each frame and redraw it which is quite expensive. Hopefully a future version of pymunk will support a better way to do it.

For now if you want to draw a more complicated scene I recommend that you use pymunk.matplotlib_util as inspiration but write the drawing code yourself to better optimize the animation.


In [6]:
fig = plt.figure()
ax = plt.axes(xlim=(0, 600), ylim=(0, 600))
ax.set_aspect("equal")

space = setup_space()
setup_balls(space)

o = pymunk.matplotlib_util.DrawOptions(ax)


space.shapes[1].body.apply_impulse_at_local_point((-12000,0))
    
def init():
    space.debug_draw(o)
    return []

def animate(dt):
    #we run the animation with half speed intentionally to make it a little nicer to look at
    for x in range(10):
        space.step(1/50/10/2)
    ax.clear()
    space.debug_draw(o)
    return []

frames = 105
anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=frames, interval=20, blit=False)

HTML(anim.to_html5_video())


<cdata 'cpSpaceDebugColor &' 0x000001A2815F67A4>
Out[6]:

In [ ]: