赞
踩
关于 Manim 的安装,github 上有多种版本,使用起来各不相同(运行方式、API等等)踩了一些坑,最终用的 Manim 社区版,里面有详细的教程和API介绍。
from manim import * def func(x): return np.sin(x*PI) class PlotTangent(MovingCameraScene): def construct(self): self.camera.frame.save_state() # 标题函数公式, 放置在左上角 title = MathTex("f(x) = sin(x)") title.to_corner(UL) # 绘制坐标系 ax = Axes(x_range = [-2.5, 2.5, 0.5], y_range = [-1.5, 1.5], x_length = 10, axis_config={"include_numbers": True}, ) graph = ax.get_graph(func, color=BLUE) # 函数曲线 x_space = np.linspace(-1.5, 1.5, 200) # 设定切线的 x 取值范围 ''' 绘制切线, get_secant_slope_group 是用来绘制割线的, 这里 dx 设的足够小看起来就像切线 这里的 slopes 里面有3条线, 第三条是需要的切线, 另外两条是 dx 和 dy ''' slopes = ax.get_secant_slope_group( x = x_space[0], graph = graph, dx = 0.0001, secant_line_length = 5, secant_line_color = RED_D, ) dot = Dot(point=[ax.coords_to_point(x_space[0], func(x_space[0]))]) # 初始切点 # 切点处标记的信息, 用 VGroup() 把公式和动态斜率数值绑定成一组 text, decimal = label = VGroup( MathTex("f'(x) = "), DecimalNumber( 0, num_decimal_places=3, include_sign=True ) ) label.arrange(RIGHT) # 没有这行的话公式和数值会重合在一起 label.scale(0.6) # 比例缩放 label.set_color(YELLOW_C) # 颜色 label.add_updater(lambda d: d.next_to(dot, UL)) # label 在 dot 的左上角 # decimal 的数值设定为 dot 点的斜率 decimal.add_updater(lambda d: d.set_value( np.cos(ax.point_to_coords(dot.get_center())[0] * PI) )) self.add(title, ax, graph, dot) # 标题、坐标系、函数曲线、初始切点 # 切点的xy轴垂线 h_line = always_redraw(lambda: ax.get_lines_to_point(dot.get_center())) self.play(Create(h_line), Create(slopes[2]), Write(label)) # 切点垂线、切线、标签 self.play(self.camera.frame.animate.scale(0.8).move_to(dot)) # 镜头跟踪切点位置 def update_curve(mob): mob.move_to(dot.get_center()) ''' 这里用循环来变换切点坐标和切线, 感觉不是最优的方法 其实点可以通过 dot.add_updater(lambda x: x.move_to()) 来动态更新 但是不知道切线怎么用 add_updater 的方式来变换, 只好先用循环实现 ''' for x in x_space[1:]: self.camera.frame.add_updater(update_curve) slopes_d = ax.get_secant_slope_group( x = x, graph = graph, dx = 0.0001, secant_line_length = 5, secant_line_color = RED_D, ) dot_d = Dot(point=[ax.coords_to_point(x, func(x))]) self.play( ReplacementTransform(slopes[2], slopes_d[2]), ReplacementTransform(dot, dot_d), run_time=0.015 ) slopes = slopes_d dot = dot_d self.camera.frame.remove_updater(update_curve) self.play(Restore(self.camera.frame)) self.wait() # jupyter notebook 的魔法函数运行方式 %manim -ql -v WARNING -i PlotTangent
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。