simvx.core.physics.shapes2d

Shape resources for 2D physics.

The 2D sibling of :mod:~simvx.core.physics.shapes. A Shape2D is a plain collision-geometry resource (a value), not a scene node. It is held by a

class:

~simvx.core.physics.nodes2d.CollisionShape2D node (via a Property) or set directly on a body as a convenience collider. A body never branches on shape kind: it calls shape.build(world) and each subclass dispatches to the 2D world’s matching world.create_* factory, keeping body nodes open/closed over new shape kinds.

Mirrors shapes.py (naming/structure/validation), carrying Vec2 geometry and 2D-only kinds (segment, convex/concave polygon). RectangleShape2D keeps the 2D-facing name but dispatches to the world’s create_box factory.

All of these are exported from simvx.core.

Module Contents

Classes

Shape2D

Abstract 2D collision-geometry resource that OWNS its backend shape.

CircleShape2D

A circle collision shape of a given radius (2D sibling of SphereShape3D).

RectangleShape2D

An axis-aligned (body-local) box collision shape centred at the origin.

CapsuleShape2D

A Y-axis capsule collision shape (a segment swept by a circle).

SegmentShape2D

A thick line-segment collision shape (2D-only, no 3D equivalent).

ConvexPolygonShape2D

A convex polygon collision shape from counter-clockwise points.

ConcavePolygonShape2D

A STATIC edge-soup collision shape (2D analogue of ConcaveMeshShape3D).

Data

API

simvx.core.physics.shapes2d.__all__

[‘Shape2D’, ‘CircleShape2D’, ‘RectangleShape2D’, ‘CapsuleShape2D’, ‘SegmentShape2D’, ‘ConvexPolygonS…

class simvx.core.physics.shapes2d.Shape2D[source]

Bases: abc.ABC

Abstract 2D collision-geometry resource that OWNS its backend shape.

The 2D sibling of :class:~simvx.core.physics.shapes.Shape, with the same ownership contract: :meth:build hands back the one backend handle this resource owns in a given world, building it on the first ask, and every handle it owns is released when the resource is collected. Geometry is immutable by contract and not by enforcement (see the 3D class for what a write after :meth:build does and does not change), and per-node scale travels with the BODY rather than being baked into the shared resource.

build(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle[source]

Return this resource’s backend shape handle in world.

Built once per world by :meth:create and remembered, so asking twice hands back the same handle and every body built from this resource shares one backend record.

The handle’s lifetime is THIS RESOURCE’s lifetime, so a caller holds the resource, not the handle: a node keeps the resource it built from, and a query takes the resource as its argument. CircleShape2D(0.5).build(world) as a throwaway expression hands back a handle whose owner is already gone.

Args: world: The :class:~simvx.core.physics.world2d.Physics2DWorld whose shape factory builds the opaque handle.

Returns: An opaque ShapeHandle for use with world.create_body.

abstractmethod create(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle[source]

Build a fresh backend shape for this geometry (called once per world).

Subclasses dispatch to the matching world.create_* factory. Callers want :meth:build, which memoises this per world and owns the result; calling create directly mints a handle nothing will ever release.

__slots__

()

class simvx.core.physics.shapes2d.CircleShape2D(radius: float = 0.5)[source]

Bases: simvx.core.physics.shapes2d.Shape2D

A circle collision shape of a given radius (2D sibling of SphereShape3D).

Args: radius: Circle radius in world units (must be > 0).

Initialization

create(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle[source]
build(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle
__slots__

()

class simvx.core.physics.shapes2d.RectangleShape2D(half_extents: simvx.core.math.Vec2 | tuple[float, float] = (0.5, 0.5))[source]

Bases: simvx.core.physics.shapes2d.Shape2D

An axis-aligned (body-local) box collision shape centred at the origin.

The 2D world’s factory for this geometry is create_box, so :meth:build dispatches there.

Args: half_extents: Half-sizes along x/y. Coerced to Vec2 (float32); every component must be > 0.

Initialization

create(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle[source]
build(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle
__slots__

()

class simvx.core.physics.shapes2d.CapsuleShape2D(radius: float = 0.5, height: float = 2.0)[source]

Bases: simvx.core.physics.shapes2d.Shape2D

A Y-axis capsule collision shape (a segment swept by a circle).

height is the TOTAL extent along Y, including the two semicircular caps, so the central segment half-length is max(0.0, height / 2 - radius). When height <= 2 * radius the segment collapses to a point and the capsule degenerates to a circle of the given radius: a valid, documented case (parity with CapsuleShape3D and the segment-reduction maths in the builtin backend), NOT an error. Accordingly height >= 2 * radius is NOT validated.

Args: radius: Capsule radius in world units (must be > 0). height: Total extent along Y including both caps (must be > 0).

Initialization

create(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle[source]
build(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle
__slots__

()

class simvx.core.physics.shapes2d.SegmentShape2D(a: simvx.core.math.Vec2 | tuple[float, float] = (-0.5, 0.0), b: simvx.core.math.Vec2 | tuple[float, float] = (0.5, 0.0), radius: float = 0.0)[source]

Bases: simvx.core.physics.shapes2d.Shape2D

A thick line-segment collision shape (2D-only, no 3D equivalent).

A “beam” from a to b (body-local), useful for thin static walls / floors and one-way platforms.

Args: a: Segment start, body-local (Vec2). b: Segment end, body-local (Vec2). Must differ from a (a zero-length segment is degenerate). radius: Segment thickness radius (>= 0); 0 is an infinitely thin line.

Initialization

create(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle[source]
build(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle
__slots__

()

class simvx.core.physics.shapes2d.ConvexPolygonShape2D(points: collections.abc.Sequence[simvx.core.math.Vec2 | tuple[float, float]])[source]

Bases: simvx.core.physics.shapes2d.Shape2D

A convex polygon collision shape from counter-clockwise points.

The 2D analogue of ConvexHullShape3D. At least 3 points are required (a polygon needs a triangle). Convexity / winding is NOT re-checked at the resource layer (the backend tolerates the cloud); pass CCW points.

Args: points: Iterable of >= 3 points (Vec2 or (x, y) tuples), coerced to a single (N, 2) float32 array. Must be finite.

Initialization

create(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle[source]
build(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle
__slots__

()

class simvx.core.physics.shapes2d.ConcavePolygonShape2D(segments: collections.abc.Sequence[object] | numpy.ndarray)[source]

Bases: simvx.core.physics.shapes2d.Shape2D

A STATIC edge-soup collision shape (2D analogue of ConcaveMeshShape3D).

Holds N line segments (an [start, end] pair of Vec2 each), body-local. The 2D analogue of a static triangle mesh: STATIC-ONLY level geometry with no inertia / mass. Placing it on a non-STATIC body is an error raised at body creation (the static-only contract is enforced by the physics world, not here).

Args: segments: (N, 2, 2) float32 array (or an iterable coercible to it) of N segments, each an [start, end] pair of Vec2 points. N must be >= 1 and every coordinate finite.

Initialization

create(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle[source]
build(world: simvx.core.physics.world2d.Physics2DWorld) simvx.core.physics.world2d.ShapeHandle
__slots__

()