最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
切线之美:SymPy与Manim联手打造直观导数动画
时间:2026-05-21 18:30:01 编辑:袖梨 来源:一聚教程网
在Manim中制作导数定义动画时,如何避免繁琐的手动计算?本文将介绍如何利用SymPy实现自动化符号运算,轻松呈现割线逼近切线的动态过程。

这个经典场景需要绘制曲线和割线,通过让割线上一个点无限逼近另一个点,最终形成切线。其核心在于计算割线斜率(f(x+h) - f(x))/h,并观察当h趋近于0时的变化。
虽然原理简单,但手动推导极限、逐帧计算坐标不仅耗时,还容易出错。以函数f(x)=x³-2x+1在x=1处的切线动画为例,我们需要解决以下问题:
- 定义割线:确定两点P(1, f(1))和Q(1+h, f(1+h))的位置。
- 计算斜率:求解斜率表达式slope = (f(1+h) - f(1))/h。
- 求极限:当h→0时,确定斜率的极限值f'(1)。
- 动态更新:在动画中让h从1逐渐减小到0.01,实时计算Q点坐标和割线斜率。
手动处理这些步骤需要展开(1+h)³-2(1+h)+1等复杂表达式,对于更复杂的函数如f(x)=sin(x²)几乎不可行。这就是我们需要SymPy的原因——实现动态、精准的自动化符号计算。
SymPy 解决方案:让计算机做数学
SymPy能完美处理符号运算,其核心函数包括:
diff(f, x):自动求导函数limit(expr, h, 0):计算极限值
以下代码展示了SymPy的强大功能:
from sympy import symbols, diff, limit# 定义符号变量
x = symbols('x')# 定义函数
f = x**3 - 2*x + 1# 自动求导
f_prime = diff(f, x)
print(f"导函数 f'(x) = {f_prime}") # 输出: 3*x**2 - 2# 计算x=1处的导数
slope_at_1 = f_prime.subs(x, 1)
print(f"x=1处斜率 = {slope_at_1}") # 输出: 1# 验证极限
secant_slope_expr = (f.subs(x, 1+h) - f.subs(x, 1)) / h
limit_slope = limit(secant_slope_expr, h, 0)
print(f"极限斜率 = {limit_slope}") # 输出: 1
Manim 联动实战:让切线"动"起来
将SymPy集成到Manim动画中,使用ValueTracker控制h值的变化:
from manim import *
from sympy import symbols, lambdify, diffclass DerivativeAnimation(Scene):
def construct(self):
# SymPy计算部分
x_sym = symbols("x")
f_sym = x_sym**3 - 2*x_sym + 1
f = lambdify(x_sym, f_sym, "numpy")
f_prime_sym = diff(f_sym, x_sym)
exact_k = float(f_prime_sym.subs(x_sym, 1)) # 精确导数 # Manim可视化
ax = Axes(x_range=[-2, 3], y_range=[-3, 5])
graph = ax.plot(f, color=YELLOW)
p_point = Dot(ax.c2p(1, f(1)), color=RED) # 动态割线
h_tracker = ValueTracker(1)
def get_secant_line():
h_val = h_tracker.get_value()
x_q = 1 + h_val
k = (f(x_q) - f(1)) / h_val
return ax.plot(
lambda x: k * (x - 1) + f(1),
color=GREEN, x_range=[0, x_q + 1]
) secant_line = always_redraw(get_secant_line) # 精确切线
tangent_line = ax.plot(
lambda x: exact_k * (x - 1) + f(1),
color=PURPLE, x_range=[-0.5, 2.5]
) # 动画流程
self.play(Create(ax), Create(graph), Create(p_point))
self.play(Create(secant_line))
self.play(
h_tracker.animate.set_value(0.001),
run_time=5,
rate_func=rate_functions.ease_in_out_quad
)
self.play(Create(tang
相关文章
-
燕云十六声被诬陷悬赏怎么解决
05-21
-
异环玉子市场怎么样
05-21
-
无限远征推图阵容如何搭配
05-21
-
幻灵召唤师寂静公主玩法攻略
05-21
-
百川智能开源Baichuan2-13B-Base文本生成模型
05-21
-
Redis事务:Redis实现悲观锁与乐观锁的两种方式
05-21