痛点还原:手动推导 假设我们要展示从 (x2)(x−3) 展开到 x2−x−6 的过程。传统做法会这样写# 原始因式 expr_origin MathTex((x 2)(x - 3)) # 手动计算中间步骤心算 or 草稿纸 # ... ... # 合并同类项 expr_result MathTex(x^2 - x - 6) # 然后动画切换切换... self.play(Transform(expr_origin, expr_result))问题显而易见容易算错特别是系数复杂时无法自动化换个新公式就得重写代码缺乏动态生成的灵活性我们真正需要的是一个能自动处理代数变形并且把结果无缝喂给Manim的管道。2. SymPy 登场代数变形的“发动机”SymPy 是Python的符号计算库简单说就是能让计算机帮你推导数学公式。核心武器expand()和factor()from sympy import symbols, expand, factor, latex x symbols(x) # 原始表达式因式形式 expr_factored (x 2) * (x - 3) # 一键展开 expr_expanded expand(expr_factored) print(expr_expanded) # 输出x**2 - x - 6 # 再一键因式分解 expr_back factor(expr_expanded) print(expr_back) # 输出(x - 3)*(x 2)expand()方法可以帮助我们将因式展开factor()方法则是分解因式。SymPy不仅能返回计算结果还能生成LaTeX 字符串这正是Manim渲染公式需要的格式from sympy import latex latex_code latex(expr_expanded) print(latex_code) # 输出x^{2} - x - 6有了这个“发动机”我们只需要告诉 SymPy 起点和终点中间的所有代数变形它都能自动计算。3. Manim 联动实战让公式自动推导下面通过一个曲线绘制的示例来演示SymPy如何让Manim动画更加简单。为了能够绘制曲线的方法能够通用我们封装几个函数from sympy import symbols, sympify, solve, Eq, latex, lambdify def plot_function_curve(axes, equation_str, x_range, plot_range): 绘制函数曲线 Args: axes: 坐标系对象 equation_str: 方程字符串如 x**2 - x - 6 x_range: 绘图 x 范围如 [-3.5, 4.5] plot_range: 用于 sympy 求解的 x 范围 Returns: graph: 曲线对象 graph_label: 曲线标签 x symbols(x) expr sympify(equation_str) # 创建可调用函数 f lambdify(x, expr, modulesnumpy) # 绘制曲线 graph axes.plot(f, x_rangex_range, colorYELLOW, stroke_width3) # 创建标签 graph_label axes.get_graph_label( graph, labelff(x){latex(expr)}, x_valx_range[1], directionUP * 3 ) return graph, graph_label def find_roots(equation_str): 使用 SymPy 求解方程的根 Args: equation_str: 方程字符串如 x**2 - x - 6 Returns: roots: 实数根列表 x symbols(x) expr sympify(equation_str) # 求解方程 f(x) 0 solutions solve(Eq(expr, 0), x) # 只保留实数根 roots [] for sol in solutions: if sol.is_real: roots.append(float(sol)) return roots def create_root_markers(axes, roots): 创建零点标记和标签 Args: axes: 坐标系对象 roots: 根的列表 Returns: root_dots: 零点标记组 root_labels: 零点标签组 root_dots VGroup() root_labels VGroup() for rx in roots: # 在零点处画点 dot Dot(axes.c2p(rx, 0), colorRED, radius0.1) # 添加坐标标签 label MathTex(f({rx}, 0), font_size30, colorRED).next_to(dot, UP * 0.5) root_dots.add(dot) root_labels.add(label) return root_dots, root_labels其中plot_function_curve根据曲线方程的字符串比如x**2 - x - 6来绘制曲线find_roots求解曲线方程的根也就是和曲线和 X 轴的交点create_root_markers把曲线方程的根标记出来有了上面封装的函数绘制一个曲线的动画代码就非常简洁了。class PlotQuadraticFunction(Scene): def construct(self): # 1. 创建坐标系 axes Axes( x_range[-4, 5, 1], # x 轴范围-4 到 5步长 1 y_range[-8, 10, 2], # y 轴范围-8 到 10步长 2 x_length8, y_length6, axis_config{color: BLUE, include_numbers: True, font_size: 24}, x_axis_config{numbers_to_include: range(-4, 6)}, y_axis_config{numbers_to_include: range(-8, 11, 2)}, ) axes_labels axes.get_axis_labels(x_labelx, y_labelf(x)) # 定义方程 equation x**2 - x - 6 # 绘制函数图像 graph, graph_label plot_function_curve( axes, equation, x_range[-3.5, 4.5], plot_range[-4, 5] ) # 使用 SymPy 求解零点 roots find_roots(equation) # 创建零点标记 root_dots, root_labels create_root_markers(axes, roots) # 动画展示 self.play(Create(axes), Write(axes_labels)) self.wait() self.play(Create(graph), Write(graph_label)) self.wait() self.play( LaggedStart( *[Create(dot) for dot in root_dots], *[Write(label) for label in root_labels], lag_ratio0.3, ) ) self.wait()上面的代码看着长其实关键的就一行equation x**2 - x - 6。其他部分都是渲染坐标系创建各种元素的动画等等。生成的效果如下