如何在Manim中模拟二维碰撞?相对论动量场景实现问题求解
问题原因
你写的碰撞判断逻辑仅在construct函数初始化阶段执行1次,不会在动画运行的每一帧实时检测碰撞状态;同时新增反弹updater时没有移除原有运动updater,多updater同时生效会造成位置逻辑冲突,最终表现为两个圆直接穿过对方。
修正方案
- 移除初始化阶段的一次性碰撞判断,将碰撞检测逻辑放入逐帧执行的updater中
- 增加碰撞状态标记位,避免碰撞后逻辑被反复触发
- 统一管理两个圆的位置更新逻辑,避免多updater冲突
- 碰撞触发后交换两个圆的运动轨迹,同时校准ValueTracker数值,避免位置跳变
修正后可直接运行的代码如下:
from manim import * import numpy as np def construct(self): ax = Axes().add_coordinates() # 初始运动轨迹:黄球向右,红球向左 def move_right(x): return x + 1 def move_left(x): return -x + 1 t_yellow = ValueTracker(-5) t_red = ValueTracker(0) has_collided = False yellow_circle = Circle(color=YELLOW) red_circle = Circle(color=RED) def frame_update(mob): nonlocal has_collided, move_right, move_left # 按当前轨迹更新两球位置 yellow_circle.move_to(ax.c2p(move_right(t_yellow.get_value()), 0.5)) red_circle.move_to(ax.c2p(move_left(t_red.get_value()), 0.5)) # 逐帧检测碰撞:圆心距小于等于两球半径之和即判定碰撞 center_dist = np.linalg.norm(yellow_circle.get_center() - red_circle.get_center()) if not has_collided and center_dist <= yellow_circle.radius + red_circle.radius: has_collided = True # 校准时间tracker数值,保证碰撞后运动衔接无跳变 t_yellow.set_value(0) t_red.set_value(2) # 交换运动函数,实现沿原路径反向弹开 move_right, move_left = move_left, move_right self.add(ax, yellow_circle, red_circle) self.add_updater(frame_update) self.play( t_yellow.animate.set_value(2), t_red.animate.set_value(5), run_time=6 ) self.remove_updater(frame_update)
扩展提示
如果要实现严谨的相对论动量模拟,不需要改动碰撞检测框架,只需要在碰撞触发分支中,按照相对论动量守恒、能量守恒公式计算两个小球碰撞后的速度,替换当前示例中直接交换运动轨迹的逻辑即可。
内容的提问来源于stack exchange,提问作者Zahra_M
相关产品推荐
相关产品推荐

