多元微积分可视化

空间曲线的切线和法平面

围绕空间曲线的切线和法平面,观察空间曲线、切向量、法平面之间的关系与推理路径。

打开原视频

space_curve_demo.py
1from manim import *2import numpy as np3 4class SpaceCurveDemo(ThreeDScene):5    def construct(self):6        # 设置3D场景7        self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)8        9        # 创建标题10        title = Text("空间曲线的切线和法平面", font="PingFang SC", font_size=32)11        title.to_corner(UL, buff=0.5)12        self.add_fixed_in_frame_mobjects(title)13        self.play(Write(title))14        self.wait()15 16        # 创建3D坐标系17        axes = ThreeDAxes(18            x_range=[-3, 3, 1],19            y_range=[-3, 3, 1],20            z_range=[-1, 2, 1],21            axis_config={"color": GRAY}22        )23        self.add(axes)24        self.wait()25 26        # 定义螺旋线参数方程27        def helix(t):28            return np.array([29                1.5 * np.cos(t),30                1.5 * np.sin(t),31                t/632            ])33 34        # 定义螺旋线的导数(切向量)35        def helix_derivative(t):36            return np.array([37                -1.5 * np.sin(t),38                1.5 * np.cos(t),39                1/640            ])41 42        # 创建螺旋线43        curve = ParametricFunction(44            lambda t: helix(t),45            t_range=[0, 4*PI],46            color=BLUE47        )48        self.play(Create(curve))49        self.wait()50 51        # 显示参数方程52        param_eq = VGroup(53            MathTex(r"x = x(t)", color=BLUE, font_size=24),54            MathTex(r"y = y(t)", color=BLUE, font_size=24),55            MathTex(r"z = z(t)", color=BLUE, font_size=24)56        )57        param_eq.arrange(DOWN, aligned_edge=LEFT, buff=0.2)58        param_eq.to_corner(UR, buff=0.5)59        param_eq.shift(LEFT)  # 向左移动一个单位60        self.add_fixed_in_frame_mobjects(param_eq)61        self.play(Write(param_eq))62        self.wait()63 64        # 创建固定点和动点65        fixed_point = helix(1)66        fixed_dot = Dot3D(point=fixed_point, color=RED)67        self.add(fixed_dot)68        self.wait()69 70        # 创建割线71        def create_secant_line(t):72            point = helix(t)73            direction = point - fixed_point74            # 创建无限延伸的直线75            return Line(76                start=fixed_point - 2*direction,77                end=fixed_point + 2*direction,78                color=YELLOW79            )80 81        # 创建割线点82        secant_dot = Dot3D(point=helix(3), color=GREEN)83        secant_line = create_secant_line(3)84        self.add(secant_dot, secant_line)85        self.wait()86 87        # 显示割线方程标注88        secant_label = Text("割线方程", font="PingFang SC", font_size=16, color=YELLOW)89        secant_label.next_to(param_eq, DOWN, buff=0.2)90        self.add_fixed_in_frame_mobjects(secant_label)91        self.play(Write(secant_label))92        self.wait()93 94        # 显示割线方程95        secant_eq = MathTex(96            r"\frac{x-x(t_0)}{x(t)-x(t_0)} = \frac{y-y(t_0)}{y(t)-y(t_0)} = \frac{z-z(t_0)}{z(t)-z(t_0)}",97            color=YELLOW,98            font_size=2099        )100        secant_eq.next_to(secant_label, DOWN, buff=0.2)101        self.add_fixed_in_frame_mobjects(secant_eq)102        self.play(Write(secant_eq))103        self.wait()104 105        # 演示割线趋近于切线的过程106        def update_secant(mob, alpha):107            t = 3 - 2*alpha  # 从3趋近于1108            point = helix(t)109            # 更新割线110            direction = point - fixed_point111            if alpha < 0.99:  # 在接近极限之前保持割线112                mob.become(Line(113                    start=fixed_point - 2*direction,114                    end=fixed_point + 2*direction,115                    color=YELLOW116                ))117                # 更新动点位置118                secant_dot.move_to(point)119            else:  # 在最后直接变成切线120                derivative = helix_derivative(1)121                mob.become(Line(122                    start=fixed_point - 2*derivative,123                    end=fixed_point + 2*derivative,124                    color=YELLOW125                ))126 127        # 创建动画128        self.play(129            UpdateFromAlphaFunc(secant_line, update_secant),130            UpdateFromAlphaFunc(secant_dot, lambda m, a: m.move_to(helix(3 - 2*a))),131            run_time=3132        )133        self.wait()134 135        # 移除割线点136        self.remove(secant_dot)137        self.wait()138 139        # 显示极限表示140        limit_eq = MathTex(141            r"\lim_{t \to t_0} \frac{x(t)-x(t_0)}{t-t_0} = x'(t_0)",142            color=YELLOW,143            font_size=20144        )145        limit_eq.next_to(secant_eq, DOWN, buff=0.2)146        self.add_fixed_in_frame_mobjects(limit_eq)147        self.play(Write(limit_eq))148        self.wait()149 150        # 显示切线方程标注151        tangent_label = Text("切线方程", font="PingFang SC", font_size=16, color=YELLOW)152        tangent_label.next_to(limit_eq, DOWN, buff=0.2)153        self.add_fixed_in_frame_mobjects(tangent_label)154        self.play(Write(tangent_label))155        self.wait()156 157        # 显示切线方程158        tangent_eq = MathTex(159            r"\frac{x-x(t_0)}{x'(t_0)} = \frac{y-y(t_0)}{y'(t_0)} = \frac{z-z(t_0)}{z'(t_0)}",160            color=YELLOW,161            font_size=20162        )163        tangent_eq.next_to(tangent_label, DOWN, buff=0.2)164        self.add_fixed_in_frame_mobjects(tangent_eq)165        self.play(Write(tangent_eq))166        self.wait()167 168        # 清理残影169        self.clear()170        self.add(axes, curve, fixed_dot, secant_line, title, param_eq, secant_label, secant_eq, limit_eq, tangent_label, tangent_eq)171        self.wait()172 173        # 改变视角以更好地观察174        self.move_camera(phi=60 * DEGREES, theta=60 * DEGREES, run_time=2)175        self.wait()176 177        # 旋转3D视图178        self.begin_ambient_camera_rotation(rate=0.2)179        self.wait(4)180        self.stop_ambient_camera_rotation()181        self.wait()182 183        # 总结184        summary = Text(185            "空间曲线的切线是割线的极限",186            font="PingFang SC",187            color=WHITE,188            font_size=24189        )190        summary.to_edge(DOWN, buff=0.3)191        self.add_fixed_in_frame_mobjects(summary)192        self.play(Write(summary))193        self.wait(2)194 195        # 淡出所有元素196        self.play(197            *[FadeOut(mob) for mob in self.mobjects],198            run_time=2199        )

讲解

这个视频围绕「空间曲线的切线和法平面」展开。画面把问题、图像和公式放在同一条理解路径中,让抽象关系先被看见。

开头先建立问题背景和主要对象,让观察从标题、坐标或第一组关系进入。

画面中出现的文字「空间曲线的切线和法平面」给出视觉入口。随后画面通过对象创建、移动、淡入淡出和高亮,把抽象命题拆成可以跟随的步骤。

随后出现更具体的图像或公式提示,动画会把局部对象和整体结论联系起来。这里可以重点观察变量、曲线、区域或向量如何随镜头推进而变化。

核心公式可以写成:

x=x(t)x = x(t)

这类公式可以和画面中的符号一一对应。

观察路径

观察路径可以分三步:先锁定「空间曲线的切线和法平面」中的核心对象,尤其留意空间曲线、切向量、法平面之间的联系;再跟随画面中变量、图像或向量的变化;最后回到公式或结论,判断局部变化如何支撑整体关系。

本页可以从空间曲线、切向量、法平面、参数曲线这些概念进入,继续沿相邻问题观察同一类数学结构。