VSpace

Qualified name: manim\_pymunk.space.VSpace

class VSpace(gravity=(0, -9.81), sub_step=8, **kwargs)[source]

Bases: Mobject

Pymunk physical space management is generally not used by users. This object has already been created in SpaceScene.

The Manim visualization manager for a Pymunk physical space.

The VSpace class encapsulates the Pymunk Space object, managing rigid bodies, shapes, and constraints within the simulation. It utilizes Manim’s updater mechanism to synchronize the physical simulation results with Mobject visual states in real-time.

Parameters

gravity

The gravity acceleration vector $(g_x, g_y)$. Defaults to $(0, -9.81)$.

sub_step
The number of sub-steps per frame for physical simulation. Increasing

this value improves numerical stability and collision accuracy.

Defaults to 8.

Examples

Example: VSpaceExample

from manim import *

import random
from manim_pymunk import *

class VSpaceExample(SpaceScene):
    def construct(self):
        COLLISION_TYPE = 123
        # 1. 地板
        floor = Line(start=LEFT * 5, end=RIGHT * 5, stroke_width=12, color=BLUE)
        floor.to_edge(DOWN, buff=0.1)
        self.add_static_body(floor)

        # 2. 生成石头
        stone_num = 15
        stones = [
            Dot(color=BLUE).move_to(
                random.uniform(1, 3) * UP + random.uniform(-2, 2) * RIGHT
            )
            for _ in range(stone_num)
        ]
        self.add_dynamic_body(*stones)

        self.set_collision_type(floor, *stones, collision_type=COLLISION_TYPE)

        def post_solve_callback(arbiter, space, data):
            # 测试获取碰撞瞬间的冲量长度
            if arbiter.total_impulse.length > 0.2:
                print(f"Impact Strength: {arbiter.total_impulse.length:.2f}")
            return True

        self.set_collision_detection_handler(
            collision_type_a=COLLISION_TYPE,
            collision_type_b=COLLISION_TYPE,
            post_solve=post_solve_callback,
        )

        self.apply_impulse_at_local_point(*stones, impulse=(0, 0.1, 0))

        self.apply_force_at_world_point(stones[0], force=(0.1, 0, 0))

        start_pt = (0, 2, 0)
        end_pt = (0, -7, 0)
        self.add(Line(start_pt, end_pt, color=RED))

        self.wait(1.5)

        results = self.get_line_query(floor, start_pt, end_pt, stroke_width=0.1)

        if results:
            hit_point = results[0][2]  # 获取碰撞点坐标
            print(f"Floor detected at: {hit_point}")
            # 在探测到的位置画一个临时的红圈验证
            self.add(Dot(hit_point, color=YELLOW, radius=0.1))

        final_vel = self.get_velocity_at_local_point(stones[-1])
        print(f"Last stone velocity: {final_vel}")
        self.wait(1)
import random
from manim_pymunk import *

class VSpaceExample(SpaceScene):
    def construct(self):
        COLLISION_TYPE = 123
        # 1. 地板
        floor = Line(start=LEFT * 5, end=RIGHT * 5, stroke_width=12, color=BLUE)
        floor.to_edge(DOWN, buff=0.1)
        self.add_static_body(floor)

        # 2. 生成石头
        stone_num = 15
        stones = [
            Dot(color=BLUE).move_to(
                random.uniform(1, 3) * UP + random.uniform(-2, 2) * RIGHT
            )
            for _ in range(stone_num)
        ]
        self.add_dynamic_body(*stones)

        self.set_collision_type(floor, *stones, collision_type=COLLISION_TYPE)

        def post_solve_callback(arbiter, space, data):
            # 测试获取碰撞瞬间的冲量长度
            if arbiter.total_impulse.length > 0.2:
                print(f"Impact Strength: {arbiter.total_impulse.length:.2f}")
            return True

        self.set_collision_detection_handler(
            collision_type_a=COLLISION_TYPE,
            collision_type_b=COLLISION_TYPE,
            post_solve=post_solve_callback,
        )

        self.apply_impulse_at_local_point(*stones, impulse=(0, 0.1, 0))

        self.apply_force_at_world_point(stones[0], force=(0.1, 0, 0))

        start_pt = (0, 2, 0)
        end_pt = (0, -7, 0)
        self.add(Line(start_pt, end_pt, color=RED))

        self.wait(1.5)

        results = self.get_line_query(floor, start_pt, end_pt, stroke_width=0.1)

        if results:
            hit_point = results[0][2]  # 获取碰撞点坐标
            print(f"Floor detected at: {hit_point}")
            # 在探测到的位置画一个临时的红圈验证
            self.add(Dot(hit_point, color=YELLOW, radius=0.1))

        final_vel = self.get_velocity_at_local_point(stones[-1])
        print(f"Last stone velocity: {final_vel}")
        self.wait(1)

Methods

apply_force_at_local_point

Applies a force to a Mobject's physical body at a point defined in local coordinates.

apply_force_at_world_point

Applies a force to a Mobject's physical body at a point defined in world coordinates.

apply_impulse_at_local_point

Applies an instantaneous impulse to a Mobject's physical body at a local point.

apply_impulse_at_world_point

Applies an instantaneous impulse to a Mobject's physical body at a world coordinate.

get_line_query

Performs a segment query to detect intersections between a line and a Mobject's shapes.

get_point_query_info

Performs a spatial query to find the relationship between a point and a Mobject's shapes.

get_shapea_shapeb_info

Retrieves detailed contact information between two specific physical shapes.

init_updater

local_to_world

remove_body_shapes_constraints

Removes physical bodies, shapes, or constraints from the physical space.

set_body_and_shapes

Sets up both the physical body and its collision shapes for a Mobject.

set_position_func

Assigns a custom position update callback to a Mobject's physical body.

set_velocity_func

Assigns a custom velocity update callback to a Mobject's physical body.

velocity_at_local_point

velocity_at_world_point

world_to_local

Attributes

always

Call a method on a mobject every frame.

animate

Used to animate the application of any method of self.

animation_overrides

depth

The depth of the mobject.

height

The height of the mobject.

width

The width of the mobject.

__calculate_hollow_shape(mob, n_divisions=4)

Generates Pymunk collision shapes for a hollow Mobject (outline only).

Instead of a solid polygon, this method constructs a collision boundary using multiple pymunk.Segment shapes that follow the Mobject’s contour. This is ideal for creating containers, cages, or hollow structures where other physical objects can move inside.

Parameters

mob

The VMobject whose stroke/outline will be used to create segments.

n_divisions

The subdivision level for Bezier curves. Higher values result in smoother boundaries but may impact simulation performance.

Parameters:
  • mob (Mobject)

  • n_divisions (int)

Return type:

None

__calculate_img_shape(mob)

Generates Pymunk collision shapes from ImageMobject pixel data.

This method analyzes the image’s transparency (alpha channel) or pixel contours to extract a representative convex polygon for physical interaction. If contour extraction fails or the image is fully opaque, it falls back to a standard rectangular bounding box.

Parameters

mob

The ImageMobject to process for shape generation.

Notes

For better performance and physical stability, complex image outlines are often simplified into low-vertex count convex polygons.

Parameters:

mob (ImageMobject)

Return type:

None

__calculate_solid_shape(mob)

Generates Pymunk collision shapes for a solid Mobject.

This method maps Manim primitives (Circle, Line, Polygon, etc.) to their corresponding Pymunk shape types. For complex shapes that are non-convex (e.g., a Star or a generic path), it automatically performs convex decomposition to ensure accurate physical interaction.

Parameters

mob

The VMobject for which collision shapes are generated.

Note

Physical engines generally only support convex polygons. Non-convex objects are decomposed into multiple convex sub-shapes attached to the same body.

Parameters:

mob (Mobject)

Return type:

None

__concave2convex_refined(mob, n_divisions, tolerance)

Decomposes a concave polygon into multiple convex polygons for physics processing.

Since Pymunk and most physics engines only support convex shapes for collision detection, this method takes complex non-convex VMobjects (like stars or generic paths) and breaks them down into a set of convex sub-polygons.

Parameters

mob

The VMobject (e.g., a Star or complex polygon) to be decomposed.

n_divisions

The Bezier subdivision level used to sample the Mobject’s contour points.

tolerance

The decomposition tolerance. Higher values simplify the resulting convex shapes by merging smaller features.

Returns

List[List[Tuple[float, float]]]

A list where each element is a list of vertices defining a specific convex sub-polygon.

Parameters:
  • mob (Mobject)

  • n_divisions (int)

  • tolerance (float)

__get_refined_points(n_divisions)

Extracts subdivided sample points from a Mobject for precise collision shape generation.

This method performs adaptive sampling on the Bezier curves that define a VMobject. By increasing the subdivision level, it approximates smooth curves with a high-resolution sequence of linear segments. It also includes logic to prune redundant points caused by floating-point precision errors.

Parameters

mob

The VMobject to be sampled.

n_divisions

The subdivision level for each Bezier curve segment. A higher value results in a denser point set and smoother physical boundaries.

Returns

list

A list of subdivided $(x, y)$ coordinate tuples representing the sampled path.

Parameters:
  • mob (Mobject)

  • n_divisions (int)

Return type:

list

__set_body(mob, body_type, center_of_gravity, velocity, angular_velocity)

Initializes and configures the Pymunk physical body for a Mobject.

This internal method creates a pymunk.Body instance, sets its motion type (Dynamic, Static, or Kinematic), and applies initial kinematic properties such as center of mass, linear velocity, and angular velocity.

Parameters

mob

The Mobject to which the physical body will be attached.

body_type

The Pymunk body type integer (e.g., pymunk.Body.DYNAMIC).

center_of_gravity

The center of mass position relative to the Mobject’s center $(x, y)$.

velocity

The initial linear velocity vector $(v_x, v_y)$ of the body.

angular_velocity

The initial angular velocity (in radians per second).

Parameters:
  • mob (Mobject)

  • body_type (int)

  • center_of_gravity (Tuple[float, float])

  • velocity (Tuple[float, float])

  • angular_velocity (float)

Return type:

None

__set_shape(mob, is_solid=True, elasticity=0.8, friction=0.8, density=1.0, sensor=False, surface_velocity=(0.0, 0.0))

Configures and attaches collision shapes to a Mobject’s physical body.

This internal method defines the ‘material’ and ‘boundary’ properties of the object. It determines how the object bounces, slides, and whether it occupies solid space or acts merely as a trigger zone.

Parameters

mob

The Mobject to assign physical shapes to. Must already have a .body.

is_solid

If True, the shape is treated as a solid object. If False, it may be treated as a hollow boundary (depending on the geometry type).

elasticity

Coefficient of restitution (0.0 to 1.0+). Controls bounciness.

friction

Coefficient of friction (0.0 to 1.0+). Controls surface resistance.

density

Used to automatically calculate the mass and moment of inertia based on the shape’s area/volume.

sensor

If True, the shape detects collisions (triggers callbacks) but produces no physical impact or bounce.

surface_velocity

The relative surface velocity. Useful for creating conveyor belt effects or moving walkways.

Parameters:
  • mob (Mobject)

  • is_solid (bool)

  • elasticity (float)

  • friction (float)

  • density (float)

  • sensor (bool)

  • surface_velocity (Tuple[float, float])

Return type:

None

__simulate_updater(mob)

Synchronizes a Mobject’s position and rotation with its associated physical body.

Reads the latest kinematic state (position and angle) from the Pymunk Body and updates the Mobject’s transform. This ensures that the visual representation in Manim stays perfectly aligned with the physics simulation.

Parameters

mob

The Manim Mobject to be synchronized. It must have a .body attribute linked to a Pymunk body.

Parameters:

mob (Mobject)

__step_updater(vspace, dt)

Executes a single frame update step for the physical simulation.

Divides the frame duration into multiple sub-steps and performs incremental step calculations on the physical space. This significantly improves numerical stability and precision, preventing high-speed objects from tunneling through boundaries.

Parameters

vspace

The VSpace object itself, acting as the controller for the simulation.

dt

The time increment for the current frame (in seconds).

_abc_impl = <_abc._abc_data object>
_add_body2space(mob)[source]

Registers the physical body and shapes of a Mobject into the simulation space.

If the body is static, only the shapes are added to the space. For dynamic or kinematic bodies, both the body and its shapes are added. Additionally, this method attaches the simulation updater to the Mobject to ensure its visual transform is synchronized with the physical simulation in every frame.

Parameters

mob

The Mobject containing .body and .shapes attributes to be integrated into the physical world.

Parameters:

mob (Mobject)

Return type:

None

static _add_shape_filter(mob, group=0, categories=4294967295, mask=4294967295)[source]

Configures collision filtering for all shapes associated with a Mobject.

This method defines which objects can collide with each other using Pymunk’s filtering rules. It uses group IDs to ignore collisions between related shapes and bitmasks (categories and masks) for complex layered filtering.

Parameters

mob

The Mobject whose shapes will receive the collision filter.

group

Shapes in the same non-zero group do not collide. Useful for ignoring collisions between parts of the same complex object.

categories

A bitmask representing the categories this shape belongs to. Default is all categories (32 bits set to 1).

mask

A bitmask representing which categories this shape will collide with. Default is all categories.

Parameters:
  • mob (Mobject)

  • group (int)

  • categories (int)

  • mask (int)

_collision_detection_handler(collision_type_a, collision_type_b, begin=None, pre_solve=None, post_solve=None, separate=None, data=None)[source]

Registers a collision handler between two specific collision types.

This method defines custom callback logic for when a shape of type A interacts with a shape of type B. It allows for fine-grained control over physics responses, such as triggering events, modifying friction during contact, or preventing specific objects from bouncing.

Parameters

collision_type_a

The first specific collision type ID.

collision_type_b

The second specific collision type ID.

begin

Called when the two shapes first make contact. Must return True to process the collision physically, or False to ignore it.

pre_solve

Called in each step while the shapes are touching, before the solver runs. Useful for overriding collision parameters like friction or surface velocity.

post_solve

Called in each step while the shapes are touching, after the solver runs. Commonly used to calculate collision impulses or impact energy.

separate

Called at the final step when the two shapes stop touching.

data

A custom dictionary for storing persistent state information accessible within the callbacks.

Returns

pymunk.CollisionHandler

The registered collision handler object.

Parameters:
  • collision_type_a (int)

  • collision_type_b (int)

  • begin (Callable[[Arbiter, Space, Dict], bool])

  • pre_solve (Callable[[Arbiter, Space, Dict], bool])

  • post_solve (Callable[[Arbiter, Space, Dict], None])

  • separate (Callable[[Arbiter, Space, Dict], None])

  • data (Dict[Any, Any])

_original__init__(gravity=(0, -9.81), sub_step=8, **kwargs)

Initialize self. See help(type(self)) for accurate signature.

Parameters:
  • gravity (Tuple[float, float])

  • sub_step (int)

static _set_collision_type(mob, collision_type)[source]

Sets the collision type ID for all physical shapes associated with a Mobject.

Collision types are user-defined integers used to categorize shapes. By assigning types, you can define specific callback functions in a collision handler to determine what happens when two shapes of certain types collide.

Parameters

mob

The Mobject whose associated physical shapes will be updated.

collision_type

An integer ID representing the collision category. (e.g., 1 for players, 2 for enemies).

Parameters:
  • mob (Mobject)

  • collision_type (int)

_wildcard_collision_handler(collision_type_a, begin=None, pre_solve=None, post_solve=None, separate=None, data=None)[source]

Registers a wildcard collision handler for a specific collision type.

This handler triggers whenever a shape with collision_type_a collides with any other shape in the space, regardless of the other shape’s collision type. It is useful for global behaviors, such as playing a sound whenever a specific object hits anything.

Parameters

collision_type_a

The collision type ID to monitor.

begin

Called when two shapes first touch. Returning False ignores the collision.

pre_solve

Called every step while shapes are touching, before the collision solver runs. Returning False ignores the collision for this step.

post_solve

Called every step while shapes are touching, after the collision solver runs. Useful for retrieving collision impulse or kinetic energy.

separate

Called when two shapes stop touching.

data

A custom dictionary passed to all callback functions for state management.

Returns

pymunk.CollisionHandler

The registered collision handler object.

Parameters:
  • collision_type_a (int)

  • begin (Callable[[Arbiter, Space, Dict], bool])

  • pre_solve (Callable[[Arbiter, Space, Dict], bool])

  • post_solve (Callable[[Arbiter, Space, Dict], None])

  • separate (Callable[[Arbiter, Space, Dict], None])

  • data (Dict[Any, Any])

animation_overrides = {}
static apply_force_at_local_point(mob, force, point=(0, 0, 0))[source]

Applies a force to a Mobject’s physical body at a point defined in local coordinates.

The force is applied relative to the body’s current orientation. If the point is not the center of gravity, it will also generate a torque, causing the object to rotate.

Parameters

mob

The Mobject whose physical body will receive the force.

force

The force vector $(f_x, f_y, f_z)$ to apply. Note that Pymunk operates in 2D, so the z-component is typically ignored.

point

The offset from the body’s center of gravity $(x, y, z)$ where the force is applied, in local coordinates.

Parameters:
  • mob (Mobject)

  • force (Tuple[float, float, float])

  • point (Tuple[float, float, float])

Return type:

None

static apply_force_at_world_point(mob, force, point=(0, 0, 0))[source]

Applies a force to a Mobject’s physical body at a point defined in world coordinates.

The force vector is applied at an absolute position in the scene. If the point does not coincide with the body’s center of gravity, it will generate torque and cause the body to rotate. This is useful for external influences that occur at specific scene locations.

Parameters

mob

The Mobject whose physical body will receive the force.

force

The force vector $(f_x, f_y, f_z)$ to apply. Note that Pymunk typically ignores the z-component.

point

The absolute position in the world (scene) coordinates where the force is applied. Defaults to the origin $(0, 0, 0)$.

Parameters:
  • mob (Mobject)

  • force (Tuple[float, float, float])

  • point (Tuple[float, float, float])

Return type:

None

static apply_impulse_at_local_point(mob, impulse, point=(0, 0, 0))[source]

Applies an instantaneous impulse to a Mobject’s physical body at a local point.

Impulses cause an immediate change in velocity (linear and angular) without requiring time to elapse, simulating effects like a sudden hit or explosion. The point is defined relative to the body’s current position and orientation.

Parameters

mob

The Mobject whose physical body will receive the impulse.

impulse

The impulse vector $(i_x, i_y, i_z)$ to apply. The z-component is typically ignored in 2D physics.

point

The offset from the body’s center of gravity $(x, y, z)$ where the impulse is applied, in local coordinates.

Parameters:
  • mob (Mobject)

  • impulse (Tuple[float, float, float])

  • point (Tuple[float, float, float])

Return type:

None

static apply_impulse_at_world_point(mob, impulse, point=(0, 0, 0))[source]

Applies an instantaneous impulse to a Mobject’s physical body at a world coordinate.

The impulse vector is applied at an absolute position in the scene. This causes an immediate change in the body’s linear and angular velocity. If the application point is offset from the body’s center of mass, the body will begin to rotate.

Parameters

mob

The Mobject whose physical body will receive the impulse.

impulse

The impulse vector $(i_x, i_y, i_z)$ to apply. The z-component is typically ignored in 2D physics.

point

The absolute position in world (scene) coordinates where the impulse is applied. Defaults to the origin $(0, 0, 0)$.

Parameters:
  • mob (Mobject)

  • impulse (tuple[float, float, float])

  • point (Tuple[float, float, float])

Return type:

None

static get_line_query(mob, start, end, stroke_width)[source]

Performs a segment query to detect intersections between a line and a Mobject’s shapes.

This method simulates a ‘laser beam’ or thick line segment traveling from ‘start’ to ‘end’. It identifies if and where this segment pierces the Mobject’s physical boundaries, considering the segment’s thickness.

Parameters

mob

The Mobject whose associated physical shapes will be checked for intersection.

start

The (x, y, z) starting point of the query segment.

end

The (x, y, z) ending point of the query segment.

stroke_width

The radius of the query segment. Effectively makes the ‘laser’ a thick cylinder/capsule for detection.

Returns

query_info_list

A list of tuples containing intersection data: - alpha: A float (0.0 to 1.0) representing the normalized distance

along the segment where the hit occurred.

  • normal: A 3D vector representing the surface normal at the impact point.

  • point: The exact 3D coordinate of the intersection point.

  • shape: The specific pymunk.Shape that was hit.

Parameters:
  • mob (Mobject)

  • start (Tuple[float, float, float])

  • end (Tuple[float, float, float])

  • stroke_width (float)

Return type:

list

static get_point_query_info(mob, point=(0, 0, 0))[source]

Performs a spatial query to find the relationship between a point and a Mobject’s shapes.

This method calculates how a specific point in space relates to the physical boundaries of a Mobject. It is essential for determining if a point is inside an object, how far it is from the surface, and the direction to the closest surface point.

Parameters

mob

The Mobject whose associated physical shapes will be queried.

point

A (x, y, z) coordinate representing the test location in the scene. Note: Only the (x, y) components are used for the 2D physics engine.

Returns

query_info_list

A list of tuples, where each tuple contains: - distance: The distance from the point to the shape (negative if inside). - gradient: A 3D vector representing the direction of the distance gradient. - point: The closest point on the shape’s surface to the query point. - shape: The specific pymunk.Shape object that was queried.

Parameters:
  • mob (Mobject)

  • point (Tuple[float, float, float])

Return type:

list

static get_shapea_shapeb_info(shape_a, shape_b)[source]

Retrieves detailed contact information between two specific physical shapes.

This method performs a low-level collision query to find the ‘contact manifold’ between two shapes. It calculates the collision normal and the set of points where the two shapes are touching or overlapping.

Parameters

shape_a

The first pymunk.Shape to check for collision.

shape_b

The second pymunk.Shape to check for collision.

Returns

contact_data

A list where the first element is the collision normal, followed by tuples of contact point details: - normal: A 3D vector representing the direction required to resolve

the collision (from shape_a to shape_b).

  • point_a: The coordinate on the surface of shape_a involved in the contact.

  • point_b: The coordinate on the surface of shape_b involved in the contact.

  • distance: The penetration depth (negative if overlapping, positive if separated within the collision margin).

Parameters:
  • shape_a (Shape)

  • shape_b (Shape)

Return type:

list

init_updater()[source]
static local_to_world(mob, point=(0, 0, 0))[source]
Parameters:
  • mob (Mobject)

  • point (Tuple[float, float, float])

Return type:

Tuple[float, float, float]

remove_body_shapes_constraints(*items)[source]

Removes physical bodies, shapes, or constraints from the physical space.

This method handles the unregistration of Pymunk objects. It is crucial for maintaining simulation performance and preventing memory leaks or unexpected physical interactions after a Mobject has been removed from the scene.

Parameters

items

The Pymunk objects (Body, Shape, or Constraint) to be removed from the simulation space.

Parameters:

items (Body | Shape | Constraint)

Return type:

None

set_body_and_shapes(mob, body_type, is_solid, elasticity, friction, density, sensor, surface_velocity, center_of_gravity, velocity, angular_velocity)[source]

Sets up both the physical body and its collision shapes for a Mobject.

This method acts as a high-level initializer that configures the motion properties (velocity, gravity center) and the physical material properties (friction, elasticity) simultaneously, effectively binding a complete physical identity to a visual Mobject.

Parameters

mob

The Mobject to be initialized with physical properties.

body_type

The Pymunk body type (Dynamic, Static, or Kinematic).

is_solid

Whether the shapes are treated as solid objects or hollow boundaries.

elasticity

The coefficient of restitution. Controls how much energy is preserved after a collision.

friction

The friction coefficient. Controls how much the object resists sliding.

density

The density used to calculate mass and moment of inertia based on shape area.

sensor

If True, the shapes will trigger collision callbacks but won’t cause physical bounces.

surface_velocity

A constant velocity applied to the surface of the shape (e.g., for conveyor belts).

center_of_gravity

The center of mass relative to the Mobject’s center $(x, y)$.

velocity

The initial linear velocity vector $(v_x, v_y)$.

angular_velocity

The initial angular velocity in radians per second.

Parameters:
  • mob (Mobject)

  • body_type (int)

  • is_solid (bool)

  • elasticity (float)

  • friction (float)

  • density (float)

  • sensor (bool)

  • surface_velocity (Tuple[float, float])

  • center_of_gravity (Tuple[float, float])

  • velocity (Tuple[float, float])

  • angular_velocity (float)

Return type:

None

static set_position_func(mob, callback=None)[source]

Assigns a custom position update callback to a Mobject’s physical body.

By default, Pymunk updates a body’s position based on its velocity. This method allows you to override that behavior with custom logic. The callback is executed during every physical simulation step.

Parameters

mob

The Mobject whose physical body’s position update logic will be customized.

callback

A function with the signature def callback(body: pymunk.Body, dt: float). If None, the default Pymunk position update logic is restored.

Parameters:
  • mob (Mobject)

  • callback (Callable[[Body, float], None])

static set_velocity_func(mob, callback=None)[source]

Assigns a custom velocity update callback to a Mobject’s physical body.

This method overrides how Pymunk calculates velocity in each step. It is commonly used to implement specialized physical effects such as custom air resistance (drag), planetary gravity, or specific damping behaviors that differ from the global space settings.

Parameters

mob

The Mobject whose physical body’s velocity logic will be customized.

callback

A function with the signature: def callback(body: Body, gravity: Tuple[float, float], damping: float, dt: float) If None, the default Pymunk velocity update logic is restored.

Parameters:
  • mob (Mobject)

  • callback (Callable[[Body, tuple[float, float], float, float], None])

sub_step: int
updaters: list[Updater]
static velocity_at_local_point(mob, point=(0, 0, 0))[source]
Parameters:
  • mob (Mobject)

  • point (Tuple[float, float, float])

Return type:

Tuple[float, float, float]

static velocity_at_world_point(mob, point=(0, 0, 0))[source]
Parameters:
  • mob (Mobject)

  • point (Tuple[float, float, float])

Return type:

Tuple[float, float, float]

static world_to_local(mob, point=(0, 0, 0))[source]
Parameters:
  • mob (Mobject)

  • point (Tuple[float, float, float])

Return type:

Tuple[float, float, float]

Parameters:
  • gravity (Tuple[float, float])

  • sub_step (int)