在manim中实现抛物线的切线和它的视觉效果
利用manim实现如斯美丽的图象。并动画它,是一个让人很愉快的事情。
这三幅图像巧妙地结合了数学与物理的概念,展现了它们之间的深刻联系。
第一幅图像通过一条蓝色的曲线和两条黄色的切线,直观地展示了切线的概念。这种视觉效果不仅强调了曲线的变化,还引导观众思考切线与曲线之间的关系,体现了微积分中的导数概念。
第二幅图像则通过几何图形的组合,展示了角度和弧度的关系。椭圆和三角形的结合使得图形更加生动,强调了几何与代数之间的联系,尤其是在三角函数的应用中。
第三幅图像则进一步深化了这一主题,通过引入向量和三角函数的分解,展示了如何将一个向量分解为其在 x 轴和 y 轴上的分量。这种分解不仅在物理学中有广泛应用,也在数学中帮助理解三角函数的性质。
整体而言,这些图像通过生动的视觉表现和清晰的布局,成功地将数学与物理的概念结合在一起,激发了观众对这两个领域的兴趣和理解。
from manim import * class TangentLine010(Scene): def construct(self): # 设置背景颜色 self.camera.background_color = "#003311" # 创建表示 π 的文本符号 pi_symbol = Text("π", font_size=150, color=BLUE, font="MS PGothic") pi_symbol.move_to(ORIGIN) # 将 π 符号移动到原点 # 创建两个点,用于绘制线段 dot = Dot(ORIGIN + 0.05 * LEFT) dot2 = Dot(ORIGIN + 0.09 * RIGHT) # 创建一条线段,稍微向上移动并旋转 line = Line(dot.get_center(), dot2.get_center(), stroke_width=6).set_color(BLACK).shift(0.49 * UP + 0.1 * RIGHT).rotate(-PI / 19) # 创建眼睛的椭圆形状 left_eye = Ellipse(width=0.4, height=0.25, color=WHITE, fill_opacity=1).shift(LEFT * 0.15 + UP * 0.625).rotate(PI / 13) right_eye = Ellipse(width=0.4, height=0.25, color=WHITE, fill_opacity=1).shift(RIGHT * 0.35 + UP * 0.625).rotate(-PI / 13) # 创建眼珠 left_pupil = Dot(color=BLACK).shift(LEFT * 0.15 + UP * 0.625) right_pupil = Dot(color=BLACK).shift(RIGHT * 0.35 + UP * UP * 0.625) # 将眼睛和眼珠合并为一个组 eyes = VGroup(left_eye, right_eye, left_pupil, right_pupil) que = Text("???", font_size=52, color=WHITE, font="Fantasy").next_to(pi_symbol, UP) # 创建包含 π 符号、眼睛和其他元素的组合 pieye = VGroup(pi_symbol, eyes, que, line).shift(2 * DL + LEFT).scale(1.5).shift(2 * LEFT) self.add(pieye) # 将组合添加到场景中 # 创建坐标轴 axes = Axes().add_coordinates() # 定义函数 def func(x): return -0.20 * x**2 + 3 # 二次函数的公式 # 绘制函数图像 graph = axes.plot(func, color=PURPLE_E, x_range=[-5, 5]) self.play(Create(graph), run_time=2) # 动画显示图像 # 设置切线的切点 tangent_point_x = 2 d01 = Dot(axes.c2p(tangent_point_x, func(tangent_point_x)), radius=0.1, color=RED) # 切线点 # 计算切线的 y 坐标和斜率 tangent_point_y = func(tangent_point_x) tangent_slope = -0.40 * tangent_point_x y_intercept = tangent_point_y - tangent_slope * tangent_point_x # 创建切线函数 def ffff(x): return tangent_slope * x + y_intercept # 创建切线的起点和终点 arrow_start = Dot(axes.c2p(tangent_point_x, func(tangent_point_x))) # 切线起点 x1 = 5 # 切线终点的 x 值 y1 = ffff(x1) # 根据切线函数计算终点的 y 值 arrow_end = Dot(axes.c2p(x1, y1)) # 切线终点 # 创建切线的箭头 arrow = Arrow(start=arrow_start, end=arrow_end, buff=0, color=RED) txt_aa = MathTex(r"u", color=YELLOW_B).next_to(arrow, LEFT).shift(RIGHT) # 标签 # 绘制切线 tangent_line = axes.plot(ffff, color=YELLOW, stroke_width=0.5) # 在曲线的末端画个点# 在曲线的末端画个点 end_p = 5 # 设置终点的 x 值 p_end = Dot(axes.c2p(end_p, func(end_p)), radius=0.12, color=WHITE) # 创建终点的点 # 添加切点标记 self.add(d01, p_end) # 将切点和末端点添加到场景中 # 创建 cos 向量 arrow_start_C = Dot(axes.c2p(tangent_point_x, func(tangent_point_x))) # cos 向量的起点 arrow_end_C = Dot(axes.c2p(x1, func(tangent_point_x))) # cos 向量的终点 # 创建向量 arrow_C = Arrow(start=arrow_start_C, end=arrow_end_C, buff=0, color=PURPLE) # 创建箭头 txt_c = MathTex(r"\parallel \overrightarrow{u} \parallel \cos(\theta)", color=PURPLE).next_to(arrow_C, UP) # cos 向量标签 # 创建 sin 向量 arrow_start_S = Dot(axes.c2p(x1, func(tangent_point_x))) # sin 向量的起点 arrow_end_S = Dot(axes.c2p(x1, y1)) # sin 向量的终点 # 创建向量 arrow_S = Arrow(start=arrow_start_S, end=arrow_end_S, buff=0, color=ORANGE) # 创建箭头 txt_S = MathTex(r"\parallel \overrightarrow{u} \parallel \sin(\theta)", color=ORANGE).next_to(arrow_C, RIGHT).shift(0.5 * DOWN).scale(0.7) # sin 向量标签 # 播放动画展示切线和箭头 self.play(Create(tangent_line), Create(arrow), Create(txt_aa)) # 显示切线和箭头的动画 self.wait(1) # 暂停一秒 self.play(Create(arrow_C), Create(arrow_end_C)) # 显示 cos 向量的动画 self.play(Create(txt_c)) # 显示 cos 向量的标签 self.play(Create(arrow_S), Create(arrow_end_S)) # 显示 sin 向量的动画 self.play(Create(txt_S)) # 显示 sin 向量的标签 # 画表示 # 手动定义三角形的顶点 y1 = Polygon( [0, 1.5, 0], # 顶点 A [0.5, 1, 0], # 顶点 B [-2.5, -1, 0], # 顶点 C color=WHITE, fill_opacity=0 ).next_to(pi_symbol, UP).shift(2 * DOWN + 2 * LEFT) # 将三角形向下和左移动 y0 = Ellipse(width=4, height=2, color=WHITE, fill_opacity=1, stroke_width=1).next_to(pi_symbol, UP).shift(1.65 * LEFT + DOWN * 1.35) # 创建一个椭圆 # 合并 u = Union(y0, y1, fill_opacity=1, stroke_width=2, stroke_color=WHITE).shift(3 * UP + 3.5 * RIGHT) # 将椭圆和多边形合并 # 获取并集的中心 c_t = u.get_center() # 获取合并后的形状的中心 print(c_t) # 打印中心坐标 p0 = Dot().next_to(pi_symbol, UP) # 创建一个点在 π 符号上方 y2 = Ellipse(width=4, height=2, color=WHITE, fill_opacity=1, stroke_width=1).next_to(pi_symbol, UP).shift(1.65 * LEFT + DOWN * 1.35).shift(3 * UP + 3.5 * RIGHT) # 创建一个新的椭圆,并向右上方移动 self.play(Transform(p0, u)) # 将 p0 变换成形状 u self.add(u) # 将合并后的形状 u 添加到场景中 self.add(y2) # 将新的椭圆 y2 添加到场景中 # 角度文本 tex_theta = MathTex(r"\theta = \frac{\arcsin}{\arccos} ", color=BLUE_D).next_to(y2).shift(-3 * RIGHT) # 创建表示角度的文本 self.play(Transform(p0, tex_theta)) # 将 p0 变换为角度文本 self.add(tex_theta) # 将角度文本添加到场景中 # 在运动后确保 tex_theta 在最上层 # self.bring_to_front(tex_theta) # 这行代码可以用来确保 tex_theta 在其他对象的上面 # 加视觉效果 self.wait() # 等待结束
代码解释
-
创建点和向量:
- 代码中创建了多个点,分别表示切线、cos 向量和 sin 向量的起始和终止位置,并用箭头表示这些向量。
- 还添加了对应的标签,例如
$ \parallel \overrightarrow{u} \parallel \cos(\theta)$
和$ \parallel \overrightarrow{u} \parallel \sin(\theta)$
。
-
动画播放:
- 通过
self.play()
方法来播放生成的图形和动画,确保逐步展示场景中添加的元素。 - 每个部分被创建时都有等候时间,以便观众可以清晰地看到每个元素的构建过程。
- 通过
-
合并图形:
- 代码通过
Polygon
和Ellipse
创建了多边形和椭圆,随后用Union
方法将这些图形合并,以创建新的形状。 - 中心位置可以通过
.get_center()
方法获得,用于后续的定位和转换。
- 代码通过
-
文本和公式:
- 通过
MathTex
创建了数学公式以表示角度关系,并将其添加到场景中。 - 可能的视觉效果通过等待和变换结合起来以增强观众体验。
- 通过
这一段代码整体上是为了更好地展示数学中的切线、三角函数(sin 和 cos),以及它们的几何表示,并通过动画增强理解。
运行结果我没有放出来。如果想看的画评论区留言。我会上传出来的