十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Manim物理动画教程:4个最小场景让力学与电磁学动起来

Manim物理动画教程:4个最小场景让力学与电磁学动起来 Manim物理动画教程4个最小场景让力学与电磁学动起来【免费下载链接】manimA community-maintained Python framework for creating mathematical animations.项目地址: https://gitcode.com/GitHub_Trending/man/manimManim 是一个社区维护的 Python 数学动画框架核心能力是把公式、几何和运动过程渲染成视频。用 Manim 做物理动画的关键不是找什么物理引擎而是想明白一件事动画里没有真实的力学求解器所有运动都是你亲手写的参数方程Manim 只负责逐帧画出来。想通这一点剩下的就是把Sphere、ValueTracker、TracedPath这几个现成组件拼起来。第一帧三维画面ThreeDScene 与 Sphere 快速上手物理动画的第一步是搭舞台。三维场景必须继承ThreeDScene而不是普通的Scene源码在 manim/scene/three_d_scene.py。它比Scene多了两个东西三维相机以及一个set_camera_orientation方法用来控制相机的极角phi、方位角theta、缩放和焦距——相当于给画面摆机位。基础几何体在 manim/mobject/three_d/three_dimensions.py 里Sphere、Cube、Cylinder、Plane都是现成的。注意Sphere只接受几何参数center、radius、resolution等并没有质量摩擦系数这类物理属性——质量这些量要放在你自己的变量里算别指望塞给图形对象。from manim import * class FirstFrame(ThreeDScene): def construct(self): # phi/theta 决定相机朝向先摆好机位 self.set_camera_orientation(phi75 * DEGREES, theta45 * DEGREES) ground Plane(colorGREY_B, opacity0.5) ball Sphere(center[0, 0, 1], radius0.3) ball.set_color(RED) self.add(ground, ball) self.wait()渲染命令直接manim -qm FirstFrame.py FirstFrame即可-qm是低质量快速预览。如果机位不对只调phi和theta两个角就行其他参数默认值够用。让小球动起来ValueTracker 与 add_updater 模拟抛体运动第一帧只是静态的。要让球沿抛物线飞核心思路是用一个ValueTracker装时间再用 updater 函数在每个渲染帧里根据当前时间算出位置。ValueTracker的源码在 manim/mobject/value_tracker.py它本质上是一个可以被.animate平滑改变数值的 mobject而add_updater是 mobject 的通用方法挂在上面的回调每帧都会被调用一次。轨迹用TracedPath免费获得它在 manim/animation/changing.py 中只需要传一个取点函数比如ball.get_center它会自动跟着物体描出一条线class ProjectileMotion(ThreeDScene): def construct(self): self.set_camera_orientation(phi75 * DEGREES, theta45 * DEGREES) ball Sphere(radius0.2) ball.set_color(RED) trace TracedPath(ball.get_center, stroke_colorRED) v0, angle, g 5, 45 * DEGREES, 9.8 vx, vz v0 * np.cos(angle), v0 * np.sin(angle) t ValueTracker(0) def follow_physics(mob): now t.get_value() pos [vx * now, 0, 1 vz * now - 0.5 * g * now ** 2] if pos[2] 0: # 落地即停最朴素的碰撞处理 pos[2] 0 mob.move_to(pos) ball.add_updater(follow_physics) self.add(trace, ball) # 把时间从 0 推到 2 秒linear 保证时间均匀流逝 self.play(t.animate.set_value(2), run_time3, rate_funclinear) ball.clear_updaters() # 别忘了摘掉 updater self.wait()两个细节值得记住一是rate_funclinear默认缓动函数会让时间忽快忽慢物理过程就必须用线性二是TracedPath和带 updater 的物体会持续消耗算力演示结束一定要clear_updaters()。 同一套模式换个公式就是自由落体、圆周运动或行星轨道——方程换掉updater 不用动。用 ParametricFunction 绘制电场线电磁学可视化里电场线本质是一族参数曲线。ParametricFunction定义在 manim/mobject/graphing/functions.py传入t_range和取点函数就能把参数方程直接画成 mobject二维三维通用。以正点电荷的径向电场为例电场线就是从球面沿各个方向向外射出的射线用球坐标展开即可class ElectricFieldLines(ThreeDScene): def construct(self): self.set_camera_orientation(phi60 * DEGREES, theta45 * DEGREES) charge Sphere(radius0.3) charge.set_color(YELLOW) def make_line(azimuth): def curve(u): # u 从 0 到 1半径向外生长 r 0.5 2.0 * u return [r * np.cos(azimuth), r * np.sin(azimuth), 0] return curve lines VGroup(*[ ParametricFunction(make_line(TAU * i / 12), t_range[0, 1], colorBLUE) for i in range(12) ]) self.add(charge, lines) self.play(Rotate(lines, angleTAU, about_pointORIGIN), run_time8, rate_funclinear)磁感线、双电荷的偶极场都是同样套路先按物理规律写出参数方程再用ParametricFunction批量生成。涉及公式展示时MathTex(r\vec{F} q(\vec{E} \vec{v} \times \vec{B}))这类矢量表达式用默认 TeX 模板就能渲染模板细节可参考 manim/utils/tex_templates.py。完整案例30 行代码实现阻尼弹簧振子把前面的积木组合起来一个质量块、一根动态更新的弹簧、一条衰减的正弦曲线。核心是阻尼振动解析解x(t) A·e^(-bt/2m)·cos(ωt)用 updater 把它逐帧贴到弹簧和物块上。这段代码可以直接保存运行class SpringOscillation(Scene): def construct(self): mass Square(side_length0.5, fill_colorBLUE, fill_opacity1) mass.move_to([0, 3, 0]) A, b, m, k 2.0, 0.3, 1.0, 2.0 omega np.sqrt(k / m) def damped_x(now): return A * np.exp(-b * now / (2 * m)) * np.cos(omega * now) t ValueTracker(0) def update_spring(mob): y 3 damped_x(t.get_value()) mob.become(Line([0, 0, 0], [0, y - 0.25, 0], colorGREEN)) def update_mass(mob): mob.move_to([0, 3 damped_x(t.get_value()), 0]) spring Line([0, 0, 0], mass.get_bottom(), colorGREEN) spring.add_updater(update_spring) mass.add_updater(update_mass) self.add(spring, mass) self.play(t.animate.set_value(6), run_time8, rate_funclinear) spring.clear_updaters() mass.clear_updaters() self.wait()如果觉得只有物块在晃不够直观可以在旁边挂一个Axes同步绘制x-t曲线——把damped_x(t.get_value())写进一个FunctionGraph的 updater 即可具体轴配置可参考官方示例 example_scenes/basic.py。Manim 物理动画常见避坑与调优建议⚠️ 几个新手最容易踩的坑场景基类写错任何带Sphere、Plane等三维物体和相机操作的场景都必须继承ThreeDScene普通Scene下会直接报错。时间不用 linearplay默认的缓动函数会扭曲物理时间轴所有驱动时间流逝的animate都要显式写rate_funclinear。updater 泄漏add_updater的回调每帧执行场景切换或play结束后记得clear_updaters()否则后续动画卡顿且逻辑互相污染。相机与 updaters 叠加ThreeDScene支持ambient_camera_rotation环境相机自转它和 updater 可以同时存在但渲染开销会叠加。性能方面三维Surface类物体Sphere等的resolution参数直接决定面数预览时降到(10, 10)量级、正式渲染再调高是最立竿见影的优化Manim 本身也有缓存机制重复渲染相同场景可参考 manim/utils/caching.py。需要硬件加速渲染时可阅读 docs/source/faq/opengl.md 了解 OpenGL 渲染器的配置方式行为细节以官方文档为准。延伸资源快速上手流程docs/source/tutorials/quickstart.rst动画机制深入讲解docs/source/guides/deep_dive.rst三维与 OpenGL 示例场景example_scenes/opengl.py官方示例合集example_scenes/basic.py先跑通第一个Sphere场景再往里加你那一行参数方程——Manim 物理动画的门槛就在这一来一回之间。【免费下载链接】manimA community-maintained Python framework for creating mathematical animations.项目地址: https://gitcode.com/GitHub_Trending/man/manim创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表