云计算百科
云计算领域专业知识百科平台

函数极限可视化代码分析与详解

from manim import *
import numpy as np
import math

class LimitVisualization(Scene):

def construct(self):
#背景颜色就是黑板颜色一样黑绿颜色
self.camera.background_color='#003311'
# 标题
title = Text("函数极限的可视化", font_size=48, color=BLUE)
title.to_edge(UP)
self.play(Write(title))
self.wait(1)

# 例子1: lim(x→0) sin(x)/x = 1
self.example1()
self.clear()
self.wait(0.5)

# 例子2: lim(x→∞) (1 + 1/x)^x = e
#使用VGroup组合
title2 = VGroup(Text("例2:", font_size=36, color=YELLOW),
MathTex(r"\\lim_{x \\to +\\infty} \\left(1+\\frac{1}{x}\\right)^x = e \\approx 2.71828",
font_size=36, color=YELLOW)).arrange(RIGHT, buff=0.3).to_edge(UP)

#self.play(Write(title2))
self.example2()
self.clear()
self.wait(0.5)

# 例子3: lim(x→2) (x²-4)/(x-2) = 4
title3 = VGroup(Text("例3:", font_size=36, color=YELLOW),
MathTex(r"\\lim_{x \\to 2} \\frac{x^{2}-4}{x-2} = 4",
font_size=36, color=YELLOW)).arrange(RIGHT, buff=0.3).to_edge(UP)

#title3 = Text("例3: lim(x→2) (x²-4)/(x-2) = 4", font_size=36, color=GREEN)
title3.to_edge(UP)
self.play(Write(title3))
self.example3()
self.clear()
self.wait(0.5)

# 例子4: lim(x→∞) sin(x)/x = 0
title4 = VGroup(Text("例4:", font_size=36, color=YELLOW),
MathTex(r"\\lim_{x \\to +\\infty} \\frac{sin(x)}{x} =0",
font_size=36, color=YELLOW)).arrange(RIGHT, buff=0.3).to_edge(UP)
#title4 = Text("例4: lim(x→∞) sin(x)/x = 0", font_size=36, color=ORANGE)
title4.to_edge(UP)
self.play(Write(title4))
self.example4()

self.wait(2)

def example1(self):
# 例1: lim(x→0) sin(x)/x = 1
example_text = VGroup(
Text("例1:", font_size=36, color=YELLOW),
MathTex(r"\\lim_{x \\to 0} \\frac{sin(x)}{x}=1 ",
font_size=36, color=YELLOW)).arrange(RIGHT, buff=0.3).shift(2*UP)
self.play(Write(example_text))

# 创建坐标轴
axes = Axes(
x_range=[-6, 6, 1],
y_range=[-0.5, 1.5, 0.5],
x_length=8,
y_length=4,
axis_config={"color": BLUE}
)
axes_labels = axes.get_axis_labels(x_label="x", y_label="y")

# 创建函数图形
graph = axes.plot(
lambda x: np.sin(x)/x if x != 0 else 1,
x_range=[-6, -0.01],
color=YELLOW
)
graph2 = axes.plot(
lambda x: np.sin(x)/x if x != 0 else 1,
x_range=[0.01,6],
color=YELLOW
)
graph2.points = graph2.points[::-1] # 或者使用 graph2.reverse_points()

# 标记极限点
point = Dot(axes.coords_to_point(0, 1), color=RED)
point_label = MathTex("(0, 1)", color=RED).next_to(point, RIGHT)

li1 = VGroup(axes, axes_labels, graph, graph2, point, point_label).shift(1.5*DOWN)

self.play(Create(axes), Write(axes_labels))
self.play(Create(graph),Create(graph2))
# 右侧反向创建(从右到左)!
self.play(Create(point), Write(point_label))

self.play(li1.animate.scale(0.5).move_to(LEFT * 5 ))

# 显示极限计算
limit_text = MathTex(r"\\lim_{x \\to 0} \\frac{\\sin x}{x} = 1", font_size=36, color=GREEN).shift(RIGHT)
self.play(Write(limit_text))

# 显示数值计算
values_text = Text("数值验证:", font_size=36, color=WHITE)
values_text.next_to(limit_text, DOWN)
self.play(Write(values_text))

values = [
"x = 0.1: sin(0.1)/0.1 = 0.9983",
"x = 0.01: sin(0.01)/0.01 = 0.99998",
"x = 0.001: sin(0.001)/0.001 = 0.9999998"
]

for i, v in enumerate(values):
text = Text(v, font_size=25, color=BLUE_C)
text.next_to(values_text, DOWN, buff=0.5 + i * 0.4) # 每次递增
self.play(Write(text))

self.wait(2)

def example2(self):
# 例2: lim(x→∞) (1+1/x)^x = e

example_text =VGroup(Text("例2:", font_size=36, color=YELLOW),
MathTex(r"\\lim_{x \\to +\\infty} \\left(1+\\frac{1}{x}\\right)^x = e \\approx 2.71828",
font_size=36, color=YELLOW)).arrange(RIGHT, buff=0.3).shift(2*UP)

self.play(Write(example_text))

# 创建坐标轴
axes = Axes(
x_range=[0, 100, 10],
y_range=[0, 4, 1],
x_length=8,
y_length=4,
axis_config={"color": BLUE}
)
axes_labels = axes.get_axis_labels(x_label="x", y_label="y")

# 创建函数图形
graph = axes.plot(
lambda x: (1 + 1/x)**x,
x_range=[0.01, 100],
color=ORANGE
)

self.play(Create(axes), Write(axes_labels))
self.play(Create(graph))

# 添加水平渐近线 y=e
e_line = DashedLine(
start=axes.coords_to_point(0, np.e),
end=axes.coords_to_point(100, np.e),
color=GREEN
)
e_label = MathTex(r"y = e \\approx 2.718", color=GREEN).next_to(e_line, LEFT)

self.play(Create(e_line), Write(e_label))

li1 = VGroup(axes, axes_labels, graph,e_line,e_label)

self.play(li1.animate.scale(0.5).rotate(-1.5).move_to(LEFT * 5 ))

# 显示数值计算
values_text = Text("数值验证:", font_size=24, color=WHITE)
self.play(Write(values_text))

values = [
"x = 10: (1+1/10)^10 = 2.5937",
"x = 100: (1+1/100)^100 = 2.7048",
"x = 1000: (1+1/1000)^1000 = 2.7169"
]

for i, v in enumerate(values):
text = Text(v, font_size=20, color=BLUE_C)
text.next_to(values_text, DOWN,buff=0.5 + i * 0.4)
self.play(Write(text))

self.wait(2)

def example3(self):
# 例3: lim(x→2) (x²-4)/(x-2) = 4
example_text = MathTex(r"\\lim_{x \\to 2} \\frac{x^{2}-4}{x-2} = 4", font_size=36, color=GREEN).shift(2*UP)
#example_text.to_edge(UP)
self.play(Write(example_text))

# 创建坐标轴
axes = Axes(
x_range=[-2, 6, 1],
y_range=[-2, 8, 2],
x_length=8,
y_length=4,
axis_config={"color": BLUE}
)
axes_labels = axes.get_axis_labels(x_label="x", y_label="y")

# 创建函数图形(去除x=2处的间断点)
graph1 = axes.plot(
lambda x: (x**2 – 4)/(x – 2) if x != 2 else 4,
x_range=[-2, 1.99],
color=GREEN
)
graph2 = axes.plot(
lambda x: (x**2 – 4)/(x – 2) if x != 2 else 4,
x_range=[2.01, 6],
color=GREEN
)
graph2.points = graph2.points[::-1] # 或者使用 graph2.reverse_points()

self.play(Create(axes), Write(axes_labels))
self.play(Create(graph1), Create(graph2))

# 标记极限点
point = Dot(axes.coords_to_point(2, 4), color=RED, radius=0.15)
point_label = MathTex("(2, 4)", color=RED).next_to(point, UR)
open_circle = Circle(color=RED, radius=0.15).move_to(axes.coords_to_point(2, 4))
open_circle.set_fill(RED, opacity=1)

#////////////////////
self.play(Create(point), Write(point_label))
#_______________________________
li1 = VGroup(axes, axes_labels, graph1, graph2,point,point_label,open_circle)

self.play(li1.animate.scale(0.5).move_to(LEFT * 5 ))

# 显示函数分解
formula_text = MathTex(r"\\frac{x^2-4}{x-2} = \\frac{(x-2)(x+2)}{x-2} = x+2", font_size=30, color=WHITE)
formula_text.next_to(example_text, DOWN, buff=0.5)
self.play(Write(formula_text))

# 显示数值计算
values_text = Text("数值验证:", font_size=24, color=WHITE)
values_text.next_to(formula_text, DOWN, buff=0.5)
self.play(Write(values_text))

values = [
"x = 1.9: (1.9²-4)/(1.9-2) = 3.9",
"x = 1.99: (1.99²-4)/(1.99-2) = 3.99",
"x = 2.01: (2.01²-4)/(2.01-2) = 4.01"
]

for i, v in enumerate(values):
text = Text(v, font_size=20, color=BLUE_C)
text.next_to(values_text, DOWN,buff=0.5 + i * 0.4)
self.play(Write(text))

self.wait(2)

def example4(self):
# 例4: lim(x→∞) sin(x)/x = 0
example_text = VGroup(Text(" ", font_size=36, color=YELLOW),
MathTex(r"\\lim_{x \\to +\\infty} \\frac{sin(x)}{x} =0",
font_size=36, color=YELLOW)).arrange(RIGHT, buff=0.3).shift(2*UP)
self.play(Write(example_text))

# 创建坐标轴
axes = Axes(
x_range=[0, 50, 5],
y_range=[-1, 1, 0.5],
x_length=8,
y_length=4,
axis_config={"color": BLUE}
)
axes_labels = axes.get_axis_labels(x_label="x", y_label="y")

# 创建函数图形
graph = axes.plot(
lambda x: np.sin(x)/x if x != 0 else 1,
x_range=[0.01, 50],
color=ORANGE
)

# 创建包络线
env_upper = axes.plot(
lambda x: 1/x,
x_range=[0.5, 50],
color=RED,
stroke_width=2
)
env_lower = axes.plot(
lambda x: -1/x,
x_range=[0.5, 50],
color=RED,
stroke_width=2
)

# 添加水平渐近线
zero_line = DashedLine(
start=axes.coords_to_point(0, 0),
end=axes.coords_to_point(50, 0),
color=GREEN
)
zero_label = MathTex(" 0", color=GREEN).next_to(zero_line, 0.5*LEFT)

self.play(Create(axes), Write(axes_labels))
self.play( Write(zero_label))
self.play(Create(graph),Create(zero_line),Create(env_upper), Create(env_lower),run_time=4)

# 显示解释
explain_text = VGroup(Text("sin(x)有界:", font_size=24, color=YELLOW),
MathTex(r"\\frac{1}{x}", font_size=34, color=YELLOW),
Text("趋于0,因此极限为0:", font_size=24, color=YELLOW)
).arrange(RIGHT, buff=0.75).shift(UP)

self.play(Write(explain_text))

# 显示数值计算
values_text = Text("数值验证:", font_size=24, color=WHITE).shift(DOWN)
self.play(Write(values_text))

values = [
"x = 10: sin(10)/10 = -0.0544",
"x = 50: sin(50)/50 = -0.00214",
"x = 100: sin(100)/100 = -0.00506"
]

for i, v in enumerate(values):
text = Text(v, font_size=20, color=BLUE_C)
text.next_to(values_text, DOWN,buff=0.5 + i * 0.4)
self.play(Write(text))

self.wait(2)

一、整体架构分析

1.1 代码结构总览

这段代码是一个基于 Manim 的数学教学动画程序,通过可视化的方式展示了四个经典的函数极限问题。程序的结构可以总结如下:

LimitVisualization (场景类)

├── construct() – 主入口方法
│ ├── 设置背景色
│ ├── 添加主标题
│ ├── 依次调用四个示例方法
│ └── 管理场景切换

├── example1() – 例1: lim(x→0) sin(x)/x = 1
├── example2() – 例2: lim(x→∞) (1+1/x)^x = e
├── example3() – 例3: lim(x→2) (x²-4)/(x-2) = 4
└── example4() – 例4: lim(x→∞) sin(x)/x = 0

1.2 核心设计思想

教学分层设计:

  • 每个示例遵循 “展示 → 视觉化 → 数值验证” 的教学逻辑
  • 通过动画逐步引入数学概念,使抽象的极限概念变得直观


二、关键代码段分析

2.1 场景初始化

class LimitVisualization(Scene):
def construct(self):
# 设置深绿色背景,模拟黑板效果
self.camera.background_color='#003311'

# 添加主标题
title = Text("函数极限的可视化", font_size=48, color=BLUE)
title.to_edge(UP)
self.play(Write(title))

设计亮点:

  • 选择深绿色背景(#003311)模拟黑板,营造课堂氛围
  • 使用Write()动画让标题逐字出现,增强视觉吸引力

2.2 例1:sin(x)/x 的极限

def example1(self):
# 创建坐标轴,精确控制范围和大小
axes = Axes(
x_range=[-6, 6, 1], # x轴范围:-6到6,间隔1
y_range=[-0.5, 1.5, 0.5], # y轴范围
x_length=8, # x轴长度(像素)
y_length=4 # y轴长度
)

# 处理x=0处的间断点,分段绘制
graph = axes.plot(
lambda x: np.sin(x)/x if x != 0 else 1,
x_range=[-6, -0.01], # 左半部分
color=YELLOW
)

关键技术处理:

  • 间断点处理:由于sin(x)/x在x=0处未定义,采用分段绘制的方式
  • 动画顺序:先绘制坐标轴,再绘制函数图像,最后标记极限点

# 右侧图像反向绘制,实现从右到左的动画效果
graph2.points = graph2.points[::-1]

2.3 例2:极限e的显示

# 添加水平渐近线 y=e
e_line = DashedLine(
start=axes.coords_to_point(0, np.e),
end=axes.coords_to_point(100, np.e),
color=GREEN
)

教学特点:

  • 渐近线可视化:用虚线段清晰标示极限值e的位置
  • 对比展示:将图形缩小后移到左侧,腾出空间展示数值计算

2.4 例3:可去间断点

# 标记极限点,同时绘制实心点和空心圆
point = Dot(axes.coords_to_point(2, 4), color=RED, radius=0.15)
open_circle = Circle(color=RED, radius=0.15)
open_circle.set_fill(RED, opacity=1)

数学意义:

  • 同时使用实心点和空心圆,展示函数在该点的“补充定义”思想
  • 通过图形分解演示:(x²-4)/(x-2) = x+2(x≠2时)

2.5 例4:夹逼定理的运用

# 创建包络线展示 sin(x)/x 的界限
env_upper = axes.plot(lambda x: 1/x, x_range=[0.5, 50], color=RED)
env_lower = axes.plot(lambda x: -1/x, x_range=[0.5, 50], color=RED)

数学原理可视化:

  • 用红色包络线(±1/x)直观展示夹逼定理
  • 清晰呈现sin(x)/x被两条曲线夹住并趋近于0的过程

三、动画技术与数学教学的创新结合

3.1 渐进式学习流程

每个示例的动画流程都是:

步骤展示 → 图形绘制 → 极限标记 → 数值验证

3.2 空间复用策略

# 缩放并移动图形到左侧
li1.animate.scale(0.5).move_to(LEFT * 5)

空间规划:

  • 图形区与文字区并行,同时利用屏幕空间
  • 缩放操作让用户既有整体图形预览,又能看到具体数值

3.3 色彩编码系统

元素类型颜色用途
坐标轴 蓝色 基础框架
函数图像 黄色/橙色/绿色 区分不同函数
极限点/线 红/绿 强调极限位置
标题公式 黄色 核心数学内容
数值验证 蓝青色 辅助信息

四、代码优化建议

4.1 代码复用改进

def create_axes(self, x_range, y_range, x_label="x", y_label="y"):
"""统一的坐标轴创建函数"""
axes = Axes(
x_range=x_range,
y_range=y_range,
axis_config={"color": BLUE}
)
return VGroup(axes, axes.get_axis_labels(x_label=x_label, y_label=y_label))

4.2 动画控制改进

# 使用并行动画提高效率
self.play(
Create(graph),
Create(env_upper),
Create(env_lower),
run_time=4
)

4.3 参数配置优化

# 将常量提取为配置
CONFIG = {
"background_color": '#003311',
"axis_color": BLUE,
"title_size": 48,
"example_text_size": 36
}


五、总结

这个代码示例展示了如何将数学极限这一抽象概念通过动画可视化:

  • 视觉教学设计:通过颜色、动画和空间布局强化教学效果
  • 数学逻辑严谨:正确处理特殊点(间断点)和极限概念
  • 多层信息呈现:图形展示 + 计算过程 + 数值验证的多维度学习
  • 该代码不仅是一个数学可视化工具,更是一个教学方法的创新实践,让学习者能够直观地理解深奥的数学概念。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 函数极限可视化代码分析与详解
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!