or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-pymunk

Pymunk is a easy-to-use pythonic 2D physics library built on Munk2D

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/pymunk@7.1.x

To install, run

npx @tessl/cli install tessl/pypi-pymunk@7.1.0

0

# Pymunk - Python 2D Physics Library

1

2

Pymunk is a easy-to-use pythonic 2D physics library that provides a complete interface to the Chipmunk2D physics engine. It enables developers to create realistic physics simulations with rigid bodies, collisions, constraints, and forces for games, simulations, and educational physics demonstrations.

3

4

## Package Information

5

6

**Package Name:** `pymunk`

7

**Version:** 7.1.0

8

**License:** MIT

9

**Homepage:** https://www.pymunk.org

10

**Repository:** https://github.com/viblo/pymunk

11

12

### Installation

13

14

```bash

15

pip install pymunk

16

```

17

18

### Dependencies

19

20

- **Python:** 3.9+

21

- **Chipmunk2D:** Included (forked as Munk2D)

22

- **CFFI:** For C library bindings

23

- **Optional:** pygame, pyglet, matplotlib (for visualization utilities)

24

25

## Core Imports

26

27

```python { .api }

28

import pymunk

29

30

# Core simulation classes

31

from pymunk import Space, Body, Shape

32

33

# Shape types

34

from pymunk import Circle, Poly, Segment

35

36

# Utility classes

37

from pymunk import Vec2d, BB, Transform, ShapeFilter

38

39

# Physics information

40

from pymunk import Arbiter, ContactPoint, ContactPointSet

41

from pymunk import PointQueryInfo, SegmentQueryInfo, ShapeQueryInfo

42

43

# Debug visualization

44

from pymunk import SpaceDebugDrawOptions

45

46

# Constraint/joint classes (from pymunk.constraints)

47

from pymunk.constraints import (

48

PinJoint, SlideJoint, PivotJoint, GrooveJoint,

49

DampedSpring, DampedRotarySpring, RotaryLimitJoint,

50

RatchetJoint, GearJoint, SimpleMotor

51

)

52

53

# Utility modules

54

import pymunk.pygame_util # Pygame integration

55

import pymunk.pyglet_util # Pyglet integration

56

import pymunk.matplotlib_util # Matplotlib integration

57

import pymunk.autogeometry # Automatic geometry generation

58

import pymunk.util # Geometry and math utilities

59

import pymunk.batch # High-performance batch operations

60

```

61

62

## Basic Usage

63

64

### Creating a Simple Physics World

65

66

```python { .api }

67

import pymunk

68

69

# Create the physics space

70

space = pymunk.Space()

71

space.gravity = (0, -981) # Earth gravity (pixels/s²)

72

73

# Create a static ground body

74

ground_body = pymunk.Body(body_type=pymunk.Body.STATIC)

75

ground_shape = pymunk.Segment(ground_body, (0, 0), (800, 0), 5)

76

ground_shape.friction = 0.7

77

space.add(ground_body, ground_shape)

78

79

# Create a dynamic falling ball

80

ball_mass = 10

81

ball_radius = 20

82

ball_moment = pymunk.moment_for_circle(ball_mass, 0, ball_radius)

83

ball_body = pymunk.Body(ball_mass, ball_moment)

84

ball_body.position = 400, 600

85

ball_shape = pymunk.Circle(ball_body, ball_radius)

86

ball_shape.friction = 0.7

87

ball_shape.elasticity = 0.8 # Bounciness

88

space.add(ball_body, ball_shape)

89

90

# Run the simulation

91

dt = 1/60.0 # 60 FPS

92

for i in range(600): # 10 seconds

93

space.step(dt)

94

print(f"Ball position: {ball_body.position}")

95

```

96

97

### Physics Constraints Example

98

99

```python { .api }

100

import pymunk

101

102

space = pymunk.Space()

103

space.gravity = (0, -981)

104

105

# Create two bodies connected by a pin joint

106

body1 = pymunk.Body(10, pymunk.moment_for_circle(10, 0, 20))

107

body1.position = 100, 300

108

shape1 = pymunk.Circle(body1, 20)

109

110

body2 = pymunk.Body(10, pymunk.moment_for_circle(10, 0, 20))

111

body2.position = 200, 300

112

shape2 = pymunk.Circle(body2, 20)

113

114

# Connect with a pin joint (rigid connection)

115

pin = pymunk.PinJoint(body1, body2, (0, 0), (0, 0))

116

117

# Add a spring between them

118

spring = pymunk.DampedSpring(

119

body1, body2, (0, 0), (0, 0),

120

rest_length=50, stiffness=1000, damping=50

121

)

122

123

space.add(body1, shape1, body2, shape2, pin, spring)

124

```

125

126

### Collision Detection and Callbacks

127

128

```python { .api }

129

import pymunk

130

131

def collision_handler(arbiter, space, data):

132

"""Handle collision between two shapes"""

133

print(f"Collision! Impulse: {arbiter.total_impulse}")

134

return True # Process the collision normally

135

136

space = pymunk.Space()

137

138

# Set collision handler for specific collision types

139

space.add_collision_handler(1, 2).begin = collision_handler

140

141

# Create shapes with collision types

142

ball1 = pymunk.Circle(body1, 20)

143

ball1.collision_type = 1

144

145

ball2 = pymunk.Circle(body2, 20)

146

ball2.collision_type = 2

147

148

space.add(body1, ball1, body2, ball2)

149

```

150

151

## Architecture

152

153

Pymunk follows a clean object-oriented design with the following core components:

154

155

### Space - The Physics World

156

The `Space` class represents the physics simulation world that contains and manages all physical objects. It handles collision detection, constraint solving, and time stepping.

157

158

**Key Responsibilities:**

159

- Managing bodies, shapes, and constraints

160

- Running collision detection algorithms

161

- Solving constraint equations

162

- Integrating physics over time

163

- Providing spatial queries

164

165

### Bodies - Physical Objects

166

The `Body` class represents rigid objects with mass, position, velocity, and rotation. Bodies can be:

167

- **Dynamic**: Affected by forces and collisions

168

- **Kinematic**: Controlled by user code

169

- **Static**: Never move (for terrain/walls)

170

171

### Shapes - Collision Geometry

172

Shape classes (`Circle`, `Poly`, `Segment`) define the collision boundaries and material properties of bodies:

173

- Handle collision detection

174

- Define material properties (friction, elasticity)

175

- Provide mass/inertia calculation

176

- Support sensors (collision detection without response)

177

178

### Constraints - Connections Between Bodies

179

Constraint classes define relationships between bodies:

180

- **Joints**: Pin joints, pivot joints, slide joints

181

- **Springs**: Linear and rotary springs with damping

182

- **Motors**: Velocity and position control

183

- **Limits**: Restrict motion ranges

184

185

### Utility Classes

186

Supporting classes for common operations:

187

- **Vec2d**: 2D vector math with operator overloading

188

- **Transform**: 2D affine transformations

189

- **BB**: Axis-aligned bounding boxes

190

- **ShapeFilter**: Collision filtering system

191

192

## Capabilities

193

194

### Physics World Management

195

Complete control over physics simulation parameters and object lifecycles.

196

197

```python { .api }

198

# Space configuration

199

space.iterations = 10 # Solver iterations per step

200

space.gravity = (0, -981) # Global gravity vector

201

space.damping = 0.999 # Global velocity damping

202

space.sleep_time_threshold = 0.5 # Time before objects sleep

203

space.collision_slop = 0.1 # Collision overlap tolerance

204

205

# Object management

206

space.add(body, shape, constraint) # Add objects

207

space.remove(shape) # Remove objects

208

space.step(dt) # Advance simulation

209

210

# Spatial queries

211

hits = space.point_query((100, 200), 0, pymunk.ShapeFilter())

212

hit = space.point_query_nearest((100, 200), 0, pymunk.ShapeFilter())

213

hits = space.segment_query((0, 0), (100, 100), 0, pymunk.ShapeFilter())

214

```

215

216

[→ See Physics World Documentation](physics-world.md)

217

218

### Bodies and Shapes

219

Flexible rigid body dynamics with multiple shape types and material properties.

220

221

```python { .api }

222

# Body types and creation

223

body = pymunk.Body(mass=10, moment=pymunk.moment_for_circle(10, 0, 25))

224

kinematic_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC)

225

static_body = space.static_body # Built-in static body

226

227

# Shape creation with materials

228

circle = pymunk.Circle(body, radius=25, offset=(0, 10))

229

circle.friction = 0.7

230

circle.elasticity = 0.95

231

circle.density = 1.0

232

233

poly = pymunk.Poly(body, vertices=[(0,0), (50,0), (50,50), (0,50)])

234

segment = pymunk.Segment(body, (0, 0), (100, 0), radius=5)

235

236

# Force and impulse application

237

body.apply_force_at_world_point((1000, 0), (100, 100))

238

body.apply_impulse_at_local_point((500, 0), (0, 0))

239

```

240

241

[→ See Bodies and Shapes Documentation](bodies-shapes.md)

242

243

### Physics Constraints

244

Rich set of constraint types for connecting bodies with realistic joint behavior.

245

246

```python { .api }

247

# Joint constraints

248

pin = pymunk.PinJoint(body_a, body_b, anchor_a=(0, 0), anchor_b=(0, 0))

249

pivot = pymunk.PivotJoint(body_a, body_b, pivot_point=(100, 100))

250

slide = pymunk.SlideJoint(body_a, body_b, anchor_a, anchor_b, min_dist=10, max_dist=50)

251

groove = pymunk.GrooveJoint(body_a, body_b, groove_a=(0,0), groove_b=(100,0), anchor_b=(0,0))

252

253

# Spring constraints

254

spring = pymunk.DampedSpring(

255

body_a, body_b, anchor_a=(0, 0), anchor_b=(0, 0),

256

rest_length=100, stiffness=500, damping=20

257

)

258

rotary_spring = pymunk.DampedRotarySpring(

259

body_a, body_b, rest_angle=0, stiffness=1000, damping=50

260

)

261

262

# Motor constraints

263

motor = pymunk.SimpleMotor(body_a, body_b, rate=math.pi)

264

gear = pymunk.GearJoint(body_a, body_b, phase=0, ratio=2.0)

265

```

266

267

[→ See Constraints Documentation](constraints.md)

268

269

### Mathematical Utilities

270

Comprehensive 2D math utilities with intuitive vector operations and geometric calculations.

271

272

```python { .api }

273

# Vector operations

274

v1 = pymunk.Vec2d(10, 20)

275

v2 = pymunk.Vec2d(5, 15)

276

result = v1 + v2 # Vector addition

277

length = abs(v1) # Vector magnitude

278

unit = v1.normalized() # Unit vector

279

rotated = v1.rotated(math.pi/2) # Rotate vector

280

281

# Bounding boxes

282

bb = pymunk.BB(left=0, bottom=0, right=100, top=100)

283

center = bb.center() # Get center point

284

area = bb.area() # Calculate area

285

expanded = bb.expand(pymunk.Vec2d(10, 10)) # Expand by vector

286

287

# Transformations

288

transform = pymunk.Transform.rotation(math.pi/4) # 45° rotation

289

translated = transform.translated(100, 50) # Add translation

290

point = transform @ pymunk.Vec2d(10, 10) # Apply to point

291

```

292

293

[→ See Utilities Documentation](utilities.md)

294

295

### Debug Visualization

296

Built-in debug drawing support for popular graphics libraries with customizable rendering options.

297

298

```python { .api }

299

# Pygame debug drawing

300

import pygame

301

import pymunk.pygame_util

302

303

screen = pygame.display.set_mode((800, 600))

304

draw_options = pymunk.pygame_util.DrawOptions(screen)

305

space.debug_draw(draw_options)

306

307

# Pyglet debug drawing

308

import pyglet

309

import pymunk.pyglet_util

310

311

draw_options = pymunk.pyglet_util.DrawOptions()

312

with draw_options:

313

space.debug_draw(draw_options)

314

315

# Matplotlib debug drawing

316

import matplotlib.pyplot as plt

317

import pymunk.matplotlib_util

318

319

fig, ax = plt.subplots()

320

draw_options = pymunk.matplotlib_util.DrawOptions(ax)

321

space.debug_draw(draw_options)

322

plt.show()

323

324

# Custom debug options

325

draw_options.shape_outline_color = pymunk.SpaceDebugColor(1, 0, 0, 1) # Red

326

draw_options.collision_point_color = pymunk.SpaceDebugColor(0, 1, 0, 1) # Green

327

```

328

329

[→ See Visualization Documentation](visualization.md)

330

331

### Geometry Processing

332

Advanced geometry utilities for automatic shape generation, convex decomposition, and marching squares.

333

334

```python { .api }

335

import pymunk.autogeometry

336

import pymunk.util

337

338

# Automatic geometry processing

339

points = [(0,0), (100,0), (100,100), (50,150), (0,100)]

340

simplified = pymunk.autogeometry.simplify_curves(points, tolerance=5.0)

341

convex_hull = pymunk.autogeometry.to_convex_hull(points, tolerance=1.0)

342

convex_parts = pymunk.autogeometry.convex_decomposition(points, tolerance=1.0)

343

344

# Marching squares for bitmap to geometry conversion

345

def sample_func(point):

346

"""Sample function returning 1.0 for solid, 0.0 for empty"""

347

x, y = point

348

return 1.0 if (x-50)**2 + (y-50)**2 < 25**2 else 0.0

349

350

polylines = pymunk.autogeometry.march_soft(

351

pymunk.BB(0, 0, 100, 100), 20, 20, 0.5, sample_func

352

)

353

354

# Utility geometry functions

355

is_convex = pymunk.util.is_convex(points)

356

area = pymunk.util.calc_area(points)

357

centroid = pymunk.util.calc_center(points)

358

triangles = pymunk.util.triangulate(points)

359

```

360

361

[→ See Geometry Documentation](geometry.md)

362

363

## Physics Calculation Functions

364

365

Pymunk provides convenience functions for calculating mass properties and areas of common shapes. These are essential for setting up bodies with proper physics properties.

366

367

### Moment of Inertia Calculations

368

369

```python { .api }

370

def moment_for_circle(

371

mass: float,

372

inner_radius: float,

373

outer_radius: float,

374

offset: tuple[float, float] = (0, 0)

375

) -> float:

376

"""

377

Calculate the moment of inertia for a hollow circle.

378

379

A solid circle has an inner radius of 0.

380

381

Args:

382

mass: Mass of the shape

383

inner_radius: Inner radius (0 for solid circle)

384

outer_radius: Outer radius

385

offset: Offset from body center of gravity

386

387

Returns:

388

Moment of inertia value

389

390

Example:

391

# Solid circle

392

moment = pymunk.moment_for_circle(10, 0, 25)

393

394

# Hollow circle (ring)

395

moment = pymunk.moment_for_circle(10, 20, 25)

396

"""

397

398

def moment_for_segment(

399

mass: float,

400

a: tuple[float, float],

401

b: tuple[float, float],

402

radius: float

403

) -> float:

404

"""

405

Calculate the moment of inertia for a line segment.

406

407

The endpoints a and b are relative to the body.

408

409

Args:

410

mass: Mass of the shape

411

a: First endpoint

412

b: Second endpoint

413

radius: Thickness radius

414

415

Returns:

416

Moment of inertia value

417

"""

418

419

def moment_for_box(mass: float, size: tuple[float, float]) -> float:

420

"""

421

Calculate the moment of inertia for a solid box centered on the body.

422

423

Args:

424

mass: Mass of the shape

425

size: (width, height) of the box

426

427

Returns:

428

Moment of inertia value

429

430

Example:

431

moment = pymunk.moment_for_box(10, (50, 30))

432

"""

433

434

def moment_for_poly(

435

mass: float,

436

vertices: Sequence[tuple[float, float]],

437

offset: tuple[float, float] = (0, 0),

438

radius: float = 0

439

) -> float:

440

"""

441

Calculate the moment of inertia for a solid polygon shape.

442

443

Assumes the polygon center of gravity is at its centroid.

444

The offset is added to each vertex.

445

446

Args:

447

mass: Mass of the shape

448

vertices: List of vertices

449

offset: Offset added to each vertex

450

radius: Corner rounding radius

451

452

Returns:

453

Moment of inertia value

454

"""

455

```

456

457

### Area Calculations

458

459

```python { .api }

460

def area_for_circle(inner_radius: float, outer_radius: float) -> float:

461

"""

462

Calculate area of a hollow circle.

463

464

Args:

465

inner_radius: Inner radius (0 for solid circle)

466

outer_radius: Outer radius

467

468

Returns:

469

Area of the circle

470

"""

471

472

def area_for_segment(

473

a: tuple[float, float],

474

b: tuple[float, float],

475

radius: float

476

) -> float:

477

"""

478

Calculate area of a beveled segment.

479

480

Will always be zero if radius is zero.

481

482

Args:

483

a: First endpoint

484

b: Second endpoint

485

radius: Thickness radius

486

487

Returns:

488

Area of the segment

489

"""

490

491

def area_for_poly(

492

vertices: Sequence[tuple[float, float]],

493

radius: float = 0

494

) -> float:

495

"""

496

Calculate signed area of a polygon shape.

497

498

Returns a negative number for polygons with clockwise winding.

499

500

Args:

501

vertices: List of vertices

502

radius: Corner rounding radius

503

504

Returns:

505

Signed area of the polygon

506

"""

507

```

508

509

### Empty Callback Function

510

511

```python { .api }

512

def empty_callback(*args, **kwargs) -> None:

513

"""

514

A default empty callback function.

515

516

Can be used to reset a collision callback to its original empty

517

function. More efficient than defining your own empty function.

518

"""

519

```

520

521

## Version Information

522

523

Pymunk provides version information for both the Python library and the underlying Chipmunk2D physics engine.

524

525

### Version Properties

526

527

```python { .api }

528

version: str

529

"""

530

The release version of this Pymunk installation.

531

532

Valid only if Pymunk was installed from a source or binary

533

distribution (i.e. not in a checked-out copy from git).

534

535

Example:

536

import pymunk

537

print(pymunk.version) # "7.1.0"

538

"""

539

540

chipmunk_version: str

541

"""

542

The Chipmunk2D version used with this Pymunk version.

543

544

This property shows the actual version when you import Pymunk.

545

546

The string format is: <cpVersionString>-<github_commit>

547

where cpVersionString is the version string set by Chipmunk2D

548

and the git commit hash corresponds to the specific chipmunk

549

source from github.com/viblo/Chipmunk2D included with Pymunk.

550

551

Example:

552

import pymunk

553

print(pymunk.chipmunk_version) # "7.0.3-ade7ed72849e60289eefb7a41e79ae6322fefaf3"

554

"""

555

```

556

557

### Usage Example

558

559

```python { .api }

560

import pymunk

561

562

# Get version information

563

print(f"Pymunk version: {pymunk.version}")

564

print(f"Chipmunk version: {pymunk.chipmunk_version}")

565

566

# Version compatibility checking

567

def check_version_compatibility():

568

"""Check if current Pymunk version meets minimum requirements"""

569

required_version = "7.0.0"

570

current_version = pymunk.version

571

572

# Simple string comparison (works for semantic versioning)

573

if current_version >= required_version:

574

print(f"✓ Pymunk {current_version} meets requirement (>= {required_version})")

575

return True

576

else:

577

print(f"✗ Pymunk {current_version} does not meet requirement (>= {required_version})")

578

return False

579

580

check_version_compatibility()

581

```

582

583

## Error Handling

584

585

Pymunk uses standard Python exceptions and provides detailed error messages for common issues:

586

587

- **ValueError**: Invalid parameters or constraints

588

- **RuntimeError**: Physics engine errors or invalid operations

589

- **AttributeError**: Accessing properties on freed objects

590

591

## Thread Safety

592

593

- Spaces can be created with threading support: `Space(threaded=True)`

594

- Individual objects are not thread-safe

595

- Use appropriate locking when accessing objects from multiple threads

596

- Threading not available on Windows platform

597

598

## Performance Tips

599

600

- Use `Space.use_spatial_hash()` for large numbers of objects

601

- Prefer static bodies for terrain and immovable objects

602

- Use batch operations from `pymunk.batch` for large datasets

603

- Set appropriate `Space.iterations` for stability vs. performance trade-offs

604

- Use sensors for non-physical collision detection

605

- Consider object sleeping for inactive bodies

606

607

This comprehensive physics library provides all the tools needed for realistic 2D physics simulations with an intuitive Python interface that abstracts the underlying C physics engine complexity while maintaining high performance and flexibility.