码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 让数学公式自动推导


    合集 - manim动画(43)
    1.【manim动画教程】-- 安装2023-03-282.【manim动画教程】-- 基本图形2023-03-293.【manim动画教程】-- 坐标系2023-04-104.【manim动画教程】-- 文本样式2023-04-075.【manim动画教程】-- 文字和公式2023-04-046.【manim动画教程】-- 图形样式2023-03-317.【manim动画教程】--相机2023-04-198.【manim动画教程】--高级动画效果2023-04-149.【manim动画教程】--常用动画效果2023-04-1210.【manim】之滚动字幕2022-12-0611.【manim】之圆规动画2023-01-3112.【manim】之目录动画2023-02-2813.Manim:动画制作背后的魔法2025-05-1814.manim 动画效果总结2025-05-2015.manim变换效果总结2025-05-2116.Manim动画渲染:从代码到屏幕的幕后故事2025-05-2217.轻松掌握Manim的.animate语法:让动画编程更简单2025-05-2518.Manim中三种函数图像类的比较2025-06-0519.掌握ChangeSpeed类:让数学动画速度随心而动!2025-06-1520.把数学对象画出来:Manim Mobject类库速查手册2025-08-1621.「亲手画出动态数学」:让数学可视化触手可及的Manim入门课2025-11-0722.让你的动画“活”过来:Manim 节奏控制指南 (Rate Functions)2025-11-2323.Manim进阶:用背景图片让你的数学视频脱颖而出2025-11-2624.Manim v0.19.1 发布啦!三大新特性让动画制作更丝滑2025-12-0225.🚀 Manim CE v0.20.0 发布:动画构建更丝滑,随机性终于“可控”了!02-2126.ManimCE v0.20.1 发布:LaTeX 渲染修复与动画稳定性提升03-0227.探索视觉的边界:用 Manim 重现有趣的知觉错觉03-0728.用Manim实现动态交点计算--从一个动点问题说起04-1629.Manim如何在数学公式中完美显示中文?04-1930.如何灵活设置公式中各个部分的颜色?04-2231.如何让多个动画“齐步走”?04-2632.告别手动计算,SymPy 初识与 Manim 联动05-16
    33.让数学公式自动推导05-17
    34.切线的魔法:用 SymPy 和 Manim 轻松搞定导数动画05-1935.填充与积累:积分与面积的可视化05-2136.轨迹的蓝图:方程求解与交点计算05-2337.Manim物理模拟:别自己写欧拉了!05-2538.用 SymPy 解决 Manim 曲线绘制速度不均的问题06-0139.一次函数图像工厂:用 SymPy 自动生成 y=kx+b 对比动画06-0340.用SymPy自动计算抛物线求根、判别式与顶点06-0541.用SymPy自动求解三角形构造与全等条件验证06-0842.用SymPy自动求解追及问题的方程06-1043.用SymPy自动因式分解:从面积拼图到代数恒等式06-13
    收起

    我们在做数学公式推导的视频时,比如,想展示一个因式分解: $ x^2+2x+1 $ 变成 $ (x+1)^2 $ 的,或者反过来因式展开,都需要手动计算分解或展开后的结果。

    然后再做一个切换动画。

    expr1 = MathTex("x^2 + 2x + 1")
    expr2 = MathTex("(x + 1)^2")
    self.play(Transform(expr1, expr2))
    

    简单的公式可以手动去做,如果公式稍微复杂呢?比如:

    • $ x3-6x2+11x-6 $ 可分解成:$ (x-1)(x-2)(x-3) $
    • $ 2x^3 + 4x^2-30x $ 可分解成:$ 2x(x-3)(x+5) $
    • ... ...

    这几个公式就不是那么容易分解了,我们制作公式变换的数学动画,或者绘制函数图像时,肯定不想把时间花在这些数学推导上。

    那么,把 SymPy 引进了 Manim 的动画制作中—— 一切都变了。

    1. 痛点还原:手动推导

    假设我们要展示从 $ (x+2)(x-3) $ 展开到 $ x^2-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, modules="numpy")
    
        # 绘制曲线
        graph = axes.plot(f, x_range=x_range, color=YELLOW, stroke_width=3)
    
        # 创建标签
        graph_label = axes.get_graph_label(
            graph, label=f"f(x)={latex(expr)}", x_val=x_range[1], direction=UP * 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), color=RED, radius=0.1)
            # 添加坐标标签
            label = MathTex(f"({rx}, 0)", font_size=30, color=RED).next_to(dot, UP * 0.5)
            root_dots.add(dot)
            root_labels.add(label)
    
        return root_dots, root_labels
    

    其中:

    1. plot_function_curve:根据曲线方程的字符串(比如"x**2 - x - 6")来绘制曲线
    2. find_roots:求解曲线方程的根,也就是和曲线和 X 轴的交点
    3. 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_length=8,
                y_length=6,
                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_label="x", y_label="f(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_ratio=0.3,
                )
            )
            self.wait()
    
    

    上面的代码看着长,其实关键的就一行:equation = "x**2 - x - 6"。

    其他部分都是渲染坐标系,创建各种元素的动画等等。

    生成的效果如下:

    使用 SymPy 中核心的几个方法如下:

    • sympify:比如,expr = sympify(equation_str)将曲线方程的字符串转换成 SymPy 中的符号公式
    • lambdify:SymPy 中的符号公式转换为 Python 函数(供 Manim 绘制曲线用)
    • latex:比如,latex(expr),将SymPy 中的符号公式转换为 Manim 中显示公式的 Latex 格式
    • solve:solve(Eq(expr, 0), x),求解方程的根,也就是动画中标记的与 X 轴的交点

    只从上面示例中的代码,可能还看不出来上 SymPy 和 Manim 结合的威力。

    这时候,如何我们还想绘制另一个曲线,$ x3-6x2+11x-6 $,那么,只要改一行代码就行了。

    equation = "x**2 - x - 6" 改成 "x**3 - 6*(x**2) +11*x - 6"

    这里显示的有点重叠,我们可以根据曲线显示的情况,调整下坐标系或曲线参数的范围。

    axes = Axes(
        x_range=[-2, 5, 1], 
        # ...
        x_axis_config={"numbers_to_include": range(-1, 6)},
        # ...
    )
    
    # 绘制函数图像
    graph, graph_label = plot_function_curve(
        axes, equation, x_range=[-1, 4.5], plot_range=[-1, 5] # 调整了这里的范围
    )
    

    4. 小结

    本文主要内容如下:

    • 痛点认知:手动推导公式既低效又容易出错。
    • SymPy 核心技能:expand() 展开、factor() 因式分解、latex() 转换。
    • Manim 联动套路:SymPy 算 → LaTeX 转 → Manim 渲染。

    任何代数方程的因式变化或曲线函数都可以自动化生成,我们可以把精力集中在动画节奏和视觉设计上。

  • 相关阅读:
    Langchain里的“记忆力”,让AI只记住有用的事
    Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单
    总结:K8S指标与Prometheus实现
    k8s-----17、集群安全机制
    多路转接(上)——select
    Oracle Primavera Unifier uDesigner 资产管理器(Asset Manager )
    菜单组件Menu
    argparse模块介绍
    【Hack The Box】linux练习-- Tabby
    java毕业设计鞍山丘比特房屋租赁管理系统Mybatis+系统+数据库+调试部署
  • 原文地址:https://www.cnblogs.com/wang_yb/p/20064748
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号