Source code for manim_pymunk.constraints.VSlideJoint

from tracemalloc import start
from typing import Optional
from manim import *
from manim_pymunk.constraints import VConstraint
from pymunk.constraints import SlideJoint
from pymunk import Space


[docs] class VSlideJoint(VConstraint): """Initializes a Slide Joint constraint between two Mobjects. A Slide Joint holds two bodies between a minimum and maximum distance. It acts like a solid link when the distance reaches the limits, but allows free movement within the specified range. Parameters ---------- a_mob The first Mobject to connect. b_mob The second Mobject to connect. anchor_a_local The anchor point on the first body, defined in local coordinates. anchor_b_local The anchor point on the second body, defined in local coordinates. min_dist The minimum allowed distance between the two anchor points. max_dist The maximum allowed distance between the two anchor points. anchor_a_appearance The visual representation (Mobject) of the first anchor point. anchor_b_appearance The visual representation (Mobject) of the second anchor point. indicator_line_class The Manim class used to draw the connection line (e.g., Line or DashedLine). Pass None to disable the visual indicator. indicator_line_config Configuration dictionary for the styling of the indicator line. Examples -------- .. manim:: VSlideJointExample from manim_pymunk import * class VSlideJointExample(SpaceScene): def construct(self): static_dot = Dot(ORIGIN) square = Square().move_to(static_dot).scale(2) square2 = Square().move_to(static_dot.get_center() + UR*3).scale(0.5) constraints = [ VPinJoint(static_dot, square), VSlideJoint( square, square2, anchor_a_local=square.get_corner(UR) - square.get_center(), min_dist=0.5, max_dist=3, ), VSimpleMotor( static_dot, square, rate=PI/4, max_torque=500, ), ] self.add_static_body(static_dot) self.add_dynamic_body(square, square2) self.add_shapes_filter(static_dot, square, square2, group=2) self.add_constraints(*constraints) self.wait(6) """ def __init__( self, a_mob: Mobject, b_mob: Mobject, anchor_a_local: list[float, float, float] = ORIGIN, anchor_b_local: list[float, float, float] = ORIGIN, min_dist: float = 0.0, max_dist: float = 1.0, anchor_a_appearance: Mobject = Dot(color=GREEN_A, radius=0.08), anchor_b_appearance: Mobject = Dot(color=GREEN_A, radius=0.08), indicator_line_class: Optional[Line] = Line, indicator_line_config: dict = { "color": RED, "stroke_width": 2, }, **kwargs, ): super().__init__(**kwargs) self.a_mob = a_mob self.b_mob = b_mob self.anchor_a_local = anchor_a_local self.anchor_b_local = anchor_b_local self.min_dist = min_dist self.max_dist = max_dist self.anchor_a_appearance = anchor_a_appearance self.anchor_b_appearance = anchor_b_appearance self.indicator_line_class = indicator_line_class self.indicator_line_config = indicator_line_config self.indicator_line = None self.constraint: Optional[SlideJoint] = None def __check_data(self): """Verify the validity of constraint parameters.""" pass
[docs] def install(self, space: Space): a_body = getattr(self.a_mob, "body", None) b_body = getattr(self.b_mob, "body", None) if not a_body or not b_body: raise ValueError("VSlideJoint connected objects must have Pymunk bodies.") self.constraint = SlideJoint( a_body, b_body, tuple(self.anchor_a_local[:2]), tuple(self.anchor_b_local[:2]), self.min_dist, self.max_dist, ) pos_a = a_body.local_to_world(tuple(self.anchor_a_local[:2])) pos_b = b_body.local_to_world(tuple(self.anchor_b_local[:2])) p1 = [pos_a.x, pos_a.y, 0] p2 = [pos_b.x, pos_b.y, 0] if self.indicator_line_class: self.indicator_line = self.indicator_line_class( start=p1, end=p2, **self.indicator_line_config ) self.add(self.indicator_line) self.anchor_a_appearance.move_to(p1) self.anchor_b_appearance.move_to(p2) self.add(self.anchor_a_appearance, self.anchor_b_appearance) space.add(self.constraint) self.add_updater(self.mob_updater)
[docs] def mob_updater(self, mob, dt): """Visual control updater""" if not self.constraint: return a_body = self.constraint.a b_body = self.constraint.b wa = a_body.local_to_world(self.constraint.anchor_a) wb = b_body.local_to_world(self.constraint.anchor_b) p1 = [wa.x, wa.y, 0] p2 = [wb.x, wb.y, 0] self.anchor_a_appearance.move_to(p1) self.anchor_b_appearance.move_to(p2) if isinstance(self.indicator_line, Line): self.indicator_line.put_start_and_end_on(p1, p2)