# -*- coding: utf-8 -*-.py # -*- coding: utf-8 -*- # Skeleton.py from manim import * import numpy as np class Skeleton(Scene): # 定义坐标轴范围常量 X_MIN = -3.5 * PI X_MAX = 3.5 * PI Y_MIN = -1.5 Y_MAX = 1.5 def construct(self): # 创建坐标系 axes = Axes( x_range=[self.X_MIN, self.X_MAX, PI], y_range=[self.Y_MIN, self.Y_MAX, 0.5], axis_config={ "color": WHITE, "include_tip": True, "include_numbers": False, "tick_size": 0 } ) # 添加坐标轴标签 x_label = axes.get_x_axis_label(Text("x").scale(0.7), direction=DOWN) y_label = axes.get_y_axis_label(Text("y").scale(0.7), direction=LEFT) # 动画展示坐标轴(淡入效果) self.play(FadeIn(axes), run_time=1) self.play(Write(x_label), Write(y_label), run_time=1) # 创建正弦函数曲线 sin_graph = axes.plot( lambda x: np.sin(x), color=GREEN ) # 创建正弦函数标签 sin_label = MathTex(r"\sin(x)").scale(0.7) sin_label.move_to(axes.c2p(-3 * PI, 1)) # 动画: 绘制正弦曲线和标签 self.play(Create(sin_graph), run_time=3) self.play(Write(sin_label), run_time=1) self.wait(1) # 创建余弦函数曲线(红色) cos_graph = axes.plot( lambda x: np.cos(x), color=RED ) # 创建余弦函数标签位置(3π,-1) cos_label = MathTex(r"\cos(x)").scale(0.7) cos_label.move_to(axes.c2p(3 * PI, -1)) # 动画: 将正弦曲线转换为余弦曲线 self.play(TransformFromCopy(sin_graph, cos_graph), run_time=3) # 显示余弦函数标签 self.play(Write(cos_label), run_time=1) self.wait(1) # 在屏幕上方显示三角函数关系式(黄色) formula = MathTex( r"\cos(x) = \sin\left(x + \frac{\pi}{2}\right)", color=YELLOW ) formula.to_edge(UP) self.play(Write(formula), run_time=2) self.wait(2) # 创建值追踪器,从 -3π 到 3π x_tracker = ValueTracker(-3 * PI) # 创建动态虚线(黄色) vertical_line = always_redraw(lambda: DashedLine( start=axes.c2p(x_tracker.get_value(), self.Y_MIN), end=axes.c2p(x_tracker.get_value(), self.Y_MAX), color=YELLOW, stroke_width=2, dash_length=0.1 )) # 创建动态点(绿色跟踪sin, 红色跟踪cos) sin_dot = always_redraw(lambda: Dot( point=axes.c2p(x_tracker.get_value(), np.sin(x_tracker.get_value())), color=GREEN, radius=0.08 )) cos_dot = always_redraw(lambda: Dot( point=axes.c2p(x_tracker.get_value(), np.cos(x_tracker.get_value())), color=RED, radius=0.08 )) # 添加动态元素到场景 self.add(vertical_line, sin_dot, cos_dot) # 播放扫描动画(6秒匀速) self.play( x_tracker.animate.set_value(3 * PI), run_time=6, rate_func=linear ) # 最后等待1秒 self.wait(1) if __name__ == "__main__": # 导入必要的模块 import sys import os from manim import * # 设置 UTF-8 编码 os.environ['PYTHONIOENCODING'] = 'utf-8' sys.stdout.reconfigure(encoding='utf-8') sys.stderr.reconfigure(encoding='utf-8') # 全局指定 ctex 模板(一次性) config.tex_template = TexTemplateLibrary.ctex # 设置输出格式为MP4 config.output_format = "mp4" # 设置输出目录 config.media_dir = "./output/videos/1080p60" # 使用临时配置渲染场景(配置只在with块内有效) with tempconfig({ "quality": "high_quality", "background_color": BLACK, "preview": True, "pixel_height": 1080, "pixel_width": 1920, "frame_rate": 30 }): # 实例化场景类 scene = Skeleton() # 执行渲染流程(包含文件生成和预览) scene.render()