1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| from manim import * import numpy as np
class CircleTangent(Scene): def construct(self): # 第一部分:封面 title = Text("圆的切线:几何关系与推导", font_size=48, color=BLUE) subtitle = Text("几何直观与数学推导", font_size=36, color=GREEN) subtitle.next_to(title, DOWN, buff=0.5)
self.play(Write(title), Write(subtitle)) self.wait(2) self.play(FadeOut(title), FadeOut(subtitle))
# 第二部分:几何演示 # 创建坐标系 axes = Axes( x_range=[-4, 4, 1], y_range=[-3, 3, 1], x_length=8, y_length=6, axis_config={"color": WHITE, "stroke_width": 2}, ) axes.add_coordinates()
# 创建圆:圆心(0,0),半径2 circle = Circle(radius=2, color=YELLOW, stroke_width=4) circle.move_to(ORIGIN)
# 圆心标记 center = Dot(ORIGIN, color=RED, radius=0.08) center_label = MathTex("O", color=RED).next_to(ORIGIN, DL, buff=0.1)
# 圆上一点P p_angle = PI / 3# 60度 p_point = circle.point_at_angle(p_angle) p_dot = Dot(p_point, color=GREEN, radius=0.08) p_label = MathTex("P", color=GREEN).next_to(p_point, UR, buff=0.1)
# 显示坐标系和圆 self.play(Create(axes), run_time=1.5) self.play(Create(circle), run_time=2) self.play(FadeIn(center), Write(center_label)) self.play(FadeIn(p_dot), Write(p_label)) self.wait(1)
# 绘制半径OP radius = Line(ORIGIN, p_point, color=RED, stroke_width=4) radius_label = MathTex("\\text{半径 } OP", color=RED).next_to(radius.get_center(), LEFT, buff=0.2)
self.play(Create(radius), Write(radius_label)) self.wait(1)
# 绘制切线(垂直于半径) radius_vector = p_point - ORIGIN tangent_vector = np.array([-radius_vector[1], radius_vector[0], 0]) # 旋转90度 tangent_vector = tangent_vector / np.linalg.norm(tangent_vector) # 单位化
# 绘制切线(长度为4) tangent_line = Line( p_point - 2 * tangent_vector, p_point + 2 * tangent_vector, color=BLUE, stroke_width=4 ) tangent_label = MathTex("\\text{切线}", color=BLUE).next_to(tangent_line.get_center(), UP, buff=0.2)
self.play(Create(tangent_line), Write(tangent_label)) self.wait(1)
# 显示垂直符号 right_angle = RightAngle(radius, tangent_line, length=0.3, color=GREEN, stroke_width=4,quadrant=(-1, 1)) self.play(Create(right_angle))
# 垂直关系文本 perpendicular_text = MathTex("OP \\perp \\text{切线}", color=GREEN, font_size=36) perpendicular_text.next_to(right_angle,RIGHT,buff=0.5)
self.play(Write(perpendicular_text)) self.wait(2)
# 第三部分:缩小几何图形并移至左上角,同时显示数学推导 # 创建几何图形组 geometry_group = VGroup(axes, circle, center, center_label, p_dot, p_label, radius, radius_label, tangent_line, tangent_label, right_angle, perpendicular_text)
# 缩小并移动几何图形到左上角 self.play( geometry_group.animate.scale(0.6).to_corner(LEFT, buff=0.5), run_time=2 )
# 显示数学推导标题 derivation_title = Text("数学推导", font_size=36, color=ORANGE) derivation_title.to_edge(UP).shift(DOWN * 0.5) self.play(Write(derivation_title))
# 推导步骤 steps = VGroup( MathTex("\\text{1. 已知:圆方程 } (x-a)^2 + (y-b)^2 = r^2"), MathTex("\\text{2. 圆心 } O(a,b), \\text{ 切点 } P(x_0, y_0)"), MathTex("\\text{3. 半径斜率: } k_{OP} = \\frac{y_0 - b}{x_0 - a}"), MathTex("\\text{4. 切线斜率: } k = -\\frac{1}{k_{OP}} = -\\frac{x_0 - a}{y_0 - b}"), MathTex("\\text{5. 切线方程: } y - y_0 = k(x - x_0)"), MathTex("\\text{6. 代入得: } y - y_0 = -\\frac{x_0 - a}{y_0 - b}(x - x_0)"), MathTex("\\text{7. 整理: } (x_0 - a)(x - a) + (y_0 - b)(y - b) = r^2") )
steps.arrange(DOWN, aligned_edge=LEFT, buff=0.3) steps.scale(0.7) steps.next_to(derivation_title, DOWN, buff=0.5).to_edge(RIGHT, buff=1)
# 逐步显示推导过程 for step in steps: self.play(Write(step), run_time=1.5) self.wait(0.5)
self.wait(2)
# 第四部分:具体实例 - 清除前面的所有内容 self.play( FadeOut(geometry_group), FadeOut(derivation_title), FadeOut(steps) )原作者的代码还要长一些,我做了适当的修改,主要是用来做圆的切斜的一些知识,渲染的过程中,会出现一些**LaTeX**文件包的提示,和我们第一次安装完Manim之后进行代码测试的时候一样,例如提示安装**CTEX.sty**文件,从提示来看是ctex宏包的一部分,点击安装就可以
|