Skip to main content

A deterministic pure-Python 2D and 3D rigid-body physics engine.

Project description

pyphysics

pyphysics is a pure-Python rigid-body physics engine with deterministic 2D and 3D simulation APIs. It is built for games, prototypes, education, robotics experiments, and simulation tools that need a readable engine core without runtime dependencies.

PyPI name note: the pyphysics distribution name is already owned on PyPI by another project. This package can still be installed locally as pyphysics, but publishing it so pip install pyphysics resolves to this library requires ownership or maintainer access to that existing PyPI project.

Highlights

  • 2D rigid bodies: dynamic, static, and kinematic
  • 3D rigid bodies: dynamic, static, and kinematic
  • 2D shapes: Circle, Box, ConvexPolygon
  • 3D shapes: Sphere, Box3D, ConvexPolyhedron
  • SAT-based convex polygon and polyhedron collision
  • Impulse collision response with restitution and friction
  • Gravity, force accumulation, persistent acceleration, and damping
  • Distance joints for 2D constraints
  • Sensors, contact callbacks, collision categories, and collision masks
  • Ray casting and AABB queries in 2D and 3D
  • PhysicsClock for fixed timesteps, scaled time, frame count, and accumulation
  • Continuous substepping for fast-moving bodies
  • No runtime dependencies

Installation

For local development:

python -m pip install -e .

When published under an available PyPI distribution name:

python -m pip install <distribution-name>

The import package is always:

import pyphysics

2D Quick Start

from pyphysics import Body, Box, Circle, Vec2, World

world = World(gravity=Vec2(0, -9.81))

world.add(Body.static(position=Vec2(0, -2), shape=Box(20, 1)))
ball = world.add(
    Body.dynamic(
        position=Vec2(0, 5),
        shape=Circle(0.5),
        mass=1.0,
        restitution=0.55,
    )
)

for _ in range(120):
    world.step(1 / 60)

print(ball.position)

3D Quick Start

from pyphysics import Body3D, Box3D, Sphere, Vec3, World3D

world = World3D(gravity=Vec3(0, -9.81, 0))

world.add(Body3D.static(position=Vec3(0, -2, 0), shape=Box3D(20, 1, 20)))
ball = world.add(
    Body3D.dynamic(
        position=Vec3(0, 5, 0),
        shape=Sphere(0.5),
        mass=1.0,
        restitution=0.55,
    )
)

for _ in range(120):
    world.step(1 / 60)

print(ball.position)

Convex Shapes

from pyphysics import Body, ConvexPolygon, ConvexPolyhedron, Vec2, Vec3, World, World3D

world2 = World(gravity=Vec2())
ship = world2.add(
    Body.dynamic(
        shape=ConvexPolygon.regular(5, 1.0),
        mass=2,
        acceleration=Vec2(15, 0),
    )
)

world3 = World3D(gravity=Vec3())
rock = world3.add(
    Body.dynamic(
        shape=ConvexPolyhedron.tetrahedron(1.0),
        mass=1,
        acceleration=Vec3(0, 0, 8),
    )
)

Time And Continuity

PhysicsClock gives the world a single place for fixed timestep state, frame count, elapsed simulation time, and time scaling.

from pyphysics import PhysicsClock, Vec2, World

world = World(
    gravity=Vec2(),
    clock=PhysicsClock(fixed_dt=1 / 120, time_scale=1.0),
    max_translation_per_step=0.25,
)

for stats in world.tick(elapsed=1 / 60):
    print(stats.frame, stats.time, stats.substeps)

Fast bodies are automatically split into substeps when continuous=True:

world = World(gravity=Vec2(), continuous=True, max_translation_per_step=0.25)

Sensors And Contact Events

from pyphysics import Body, Box, Circle, Vec2, World

world = World(gravity=Vec2())
trigger = world.add(Body.static(shape=Box(3, 3), sensor=True, name="trigger"))
player = world.add(Body.dynamic(shape=Circle(0.5), position=Vec2(), mass=1, name="player"))

world.on_begin_contact = lambda contact: print(contact.a.name, contact.b.name)
stats = world.step(1 / 60)

assert stats.sensor_contacts == 1

Examples

python examples/basic_scene.py
python examples/basic_scene_3d.py

Development

Run tests:

python -m unittest discover -s tests -v

Build distributions:

python -m build

Check distributions before upload:

python -m twine check dist/*

Upload to PyPI, only after choosing an available distribution name and creating a PyPI API token:

python -m twine upload dist/*

Package Status

This repository currently provides the import package pyphysics. The desired PyPI command pip install pyphysics cannot point to this project unless the existing PyPI owner grants access or transfers the name. A practical publishing path is to keep the import name pyphysics and publish under a new distribution name such as pyphysics-engine, then users would install it with:

python -m pip install pyphysics-engine

and import it with:

import pyphysics

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

newtonian_physics-0.2.0.tar.gz (19.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

newtonian_physics-0.2.0-py3-none-any.whl (26.5 kB view details)

Uploaded Python 3

File details

Details for the file newtonian_physics-0.2.0.tar.gz.

File metadata

  • Download URL: newtonian_physics-0.2.0.tar.gz
  • Upload date:
  • Size: 19.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for newtonian_physics-0.2.0.tar.gz
Algorithm Hash digest
SHA256 044a71088931f5bfb048151d34c7c2e348d41b51fd8c2f3156c352e3777ae2b3
MD5 c6282df783d192b7bb5a1631a5feeade
BLAKE2b-256 de2ece0c8e49c2ca07e38554aa6e8179761a77ed28d819274030a3030b8849f6

See more details on using hashes here.

File details

Details for the file newtonian_physics-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for newtonian_physics-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9384bdc3dd1e6039a040810145edc261405a0be73b5bc25202c96554143e6c32
MD5 3ee3c989c0d4fce74075a3ef65a88e27
BLAKE2b-256 fbe89213a279f6c83d1e5489de310feefdf135dd09801d35cd5809933446ad6b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page