partial_derivative.py
1# -*- coding: utf-8 -*-2from manim import *3import numpy as np4 5class PartialDerivative(ThreeDScene):6 def construct(self):7 # 设置初始相机角度8 self.set_camera_orientation(phi=70 * DEGREES, theta=30 * DEGREES)9 10 # 创建3D坐标系11 axes = ThreeDAxes(12 x_range=[-2, 2, 1],13 y_range=[-2, 2, 1],14 z_range=[-1, 3, 1],15 x_length=6,16 y_length=6,17 z_length=418 )19 20 # 添加坐标轴标签21 x_label = MathTex("x").next_to(axes.x_axis.get_end(), RIGHT)22 y_label = MathTex("y").next_to(axes.y_axis.get_end(), UP)23 z_label = MathTex("z").next_to(axes.z_axis.get_end(), OUT)24 labels = VGroup(x_label, y_label, z_label)25 26 # 创建函数z = x^2 + y^2的曲面27 def func(x, y):28 return x**2 + y**229 30 surface = Surface(31 lambda u, v: axes.c2p(u, v, func(u, v)),32 u_range=[-2, 2],33 v_range=[-2, 2],34 resolution=(30, 30),35 checkerboard_colors=[BLUE_D, BLUE_E],36 fill_opacity=0.15 # 降低透明度使其若隐若现37 )38 39 # 显示坐标系和曲面40 self.play(Create(axes), Write(labels))41 self.play(Create(surface))42 self.wait(1)43 44 # 选择一个点(a,b)45 a, b = 1, 146 point = Dot3D(axes.c2p(a, b, func(a, b)), color=YELLOW, radius=0.1)47 point_label = MathTex("(a,b)", color=YELLOW).scale(0.7)48 point_coords = VGroup(point, point_label)49 point_label.add_updater(lambda m: m.next_to(point, UP + RIGHT))50 51 # 在显示x方向截面前调整相机角度52 self.move_camera(phi=60 * DEGREES, theta=-30 * DEGREES, run_time=2)53 54 # 创建x方向的截面平面55 x_plane = Surface(56 lambda u, v: axes.c2p(u, b, v),57 u_range=[-2, 2],58 v_range=[-1, 3],59 resolution=(2, 2),60 fill_opacity=0.8, # 降低不透明度61 color="#FF9999" # 使用更鲜艳的粉色62 )63 64 # 创建x方向的截面曲线65 x_curve = ParametricFunction(66 lambda t: axes.c2p(t, b, func(t, b)),67 t_range=[-2, 2],68 color="#FF0000", # 使用更鲜艳的红色69 stroke_width=4 # 增加线宽70 )71 72 # 修改x方向的切线73 def get_x_tangent_points(a, b, delta=1.5): # 增加delta使切线更长74 center = axes.c2p(a, b, func(a, b))75 slope = 2 * a76 left = axes.c2p(a - delta, b, func(a, b) - slope * delta)77 right = axes.c2p(a + delta, b, func(a, b) + slope * delta)78 return left, center, right79 80 left_point, center_point, right_point = get_x_tangent_points(a, b)81 x_tangent = Line(82 left_point,83 right_point,84 color="#FF0000", # 与曲线同色85 stroke_width=386 )87 88 # 显示x方向的偏导数几何意义89 self.play(Create(point), Write(point_label))90 self.play(Create(x_plane))91 self.play(Create(x_curve))92 self.play(Create(x_tangent)) # 移除 x_tangent_extension93 94 # 删除原来的偏导数公式,只保留说明文字95 x_explanation = VGroup(96 Text("x方向偏导数:", font="SimSun", color=RED_B).scale(0.5),97 VGroup(98 Text("固定y=b时,曲线", font="SimSun", color=RED_A).scale(0.4),99 Text("在点(a,b)处的切线斜率", font="SimSun", color=RED_A).scale(0.4)100 ).arrange(DOWN, aligned_edge=LEFT)101 ).arrange(DOWN, aligned_edge=LEFT)102 x_explanation.to_corner(UL).shift(RIGHT * 0.5) # 向右移动一些103 self.add_fixed_in_frame_mobjects(x_explanation)104 self.play(Write(x_explanation))105 self.wait(1)106 107 # 在显示y方向截面前调整相机角度108 self.move_camera(phi=60 * DEGREES, theta=60 * DEGREES, run_time=2)109 110 # 创建y方向的截面平面111 y_plane = Surface(112 lambda u, v: axes.c2p(a, u, v),113 u_range=[-2, 2],114 v_range=[-1, 3],115 resolution=(2, 2),116 fill_opacity=0.8, # 降低不透明度117 color="#99FF99" # 使用更鲜艳的绿色118 )119 120 # 创建y方向的截面曲线121 y_curve = ParametricFunction(122 lambda t: axes.c2p(a, t, func(a, t)),123 t_range=[-2, 2],124 color="#00FF00", # 使用更鲜艳的绿色125 stroke_width=4 # 增加线宽126 )127 128 # 修改y方向的切线129 def get_y_tangent_points(a, b, delta=1.5): # 增加delta使切线更长130 center = axes.c2p(a, b, func(a, b))131 slope = 2 * b132 left = axes.c2p(a, b - delta, func(a, b) - slope * delta)133 right = axes.c2p(a, b + delta, func(a, b) + slope * delta)134 return left, center, right135 136 left_point, center_point, right_point = get_y_tangent_points(a, b)137 y_tangent = Line(138 left_point,139 right_point,140 color="#00FF00", # 与曲线同色141 stroke_width=3142 )143 144 # 显示y方向的偏导数几何意义145 self.play(Create(y_plane))146 self.play(Create(y_curve))147 self.play(Create(y_tangent)) # 移除 y_tangent_extension148 149 # 删除原来的偏导数公式,只保留说明文字150 y_explanation = VGroup(151 Text("y方向偏导数:", font="SimSun", color=GREEN_B).scale(0.5),152 VGroup(153 Text("固定x=a时,曲线", font="SimSun", color=GREEN_A).scale(0.4),154 Text("在点(a,b)处的切线斜率", font="SimSun", color=GREEN_A).scale(0.4)155 ).arrange(DOWN, aligned_edge=LEFT)156 ).arrange(DOWN, aligned_edge=LEFT)157 y_explanation.next_to(x_explanation, DOWN, buff=0.8) # 增加垂直间距158 self.add_fixed_in_frame_mobjects(y_explanation)159 self.play(Write(y_explanation))160 self.wait(1)161 162 # 最后旋转时调整相机运动163 self.move_camera(phi=60 * DEGREES, theta=45 * DEGREES, run_time=2)164 self.begin_ambient_camera_rotation(rate=0.2)165 self.wait(4)166 self.stop_ambient_camera_rotation()167 168 # 修改最终说明文字169 final_explanation = VGroup(170 Text("偏导数的几何意义:", font="SimSun").scale(0.5),171 Text("在曲面上固定一个变量,", font="SimSun").scale(0.4),172 Text("得到的一元函数图像上的切线斜率", font="SimSun").scale(0.4)173 ).arrange(DOWN, aligned_edge=LEFT)174 final_explanation.to_corner(DOWN)175 self.add_fixed_in_frame_mobjects(final_explanation)176 self.play(Write(final_explanation))177 178 self.wait(2) 讲解
这个视频围绕「偏导数的几何意义」展开。画面把问题、图像和公式放在同一条理解路径中,让抽象关系先被看见。
开头先建立问题背景和主要对象,让观察从标题、坐标或第一组关系进入。
画面中出现的文字「(a,b)」给出视觉入口。随后画面通过对象创建、移动、淡入淡出和高亮,把抽象命题拆成可以跟随的步骤。
随后出现更具体的图像或公式提示,动画会把局部对象和整体结论联系起来。这里可以重点观察变量、曲线、区域或向量如何随镜头推进而变化。
核心公式可以写成:
这类公式可以和画面中的符号一一对应。
观察路径
观察路径可以分三步:先锁定「偏导数的几何意义」中的核心对象,尤其留意偏导数、切平面、多元函数之间的联系;再跟随画面中变量、图像或向量的变化;最后回到公式或结论,判断局部变化如何支撑整体关系。
本页可以从偏导数、切平面、多元函数、函数图像这些概念进入,继续沿相邻问题观察同一类数学结构。