|
|
from manim import *
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
class AnimatedFunctionPlot(Scene):
|
|
|
def construct(self):
|
|
|
# 创建坐标系(修正数学符号显示)
|
|
|
axes = Axes(
|
|
|
x_range=[-3.5 * PI, 3.5 * PI, PI / 2],
|
|
|
y_range=[-1.5, 1.5, 0.5],
|
|
|
axis_config={"color": BLUE},
|
|
|
x_axis_config={
|
|
|
"numbers_to_include": np.arange(-3 * PI, 3.5 * PI, PI),
|
|
|
"numbers_with_elongated_ticks": np.arange(-3 * PI, 3.5 * PI, PI),
|
|
|
"decimal_number_config": {
|
|
|
"num_decimal_places": 0,
|
|
|
},
|
|
|
},
|
|
|
y_axis_config={
|
|
|
"decimal_number_config": {
|
|
|
"num_decimal_places": 1,
|
|
|
}
|
|
|
},
|
|
|
tips=False,
|
|
|
).scale(0.9)
|
|
|
|
|
|
# 修正1:使用MathTex并正确转义π符号
|
|
|
x_labels = VGroup(*[
|
|
|
MathTex(r"%d\pi" % i if i != 0 else "0").scale(0.7).move_to(axes.c2p(i * PI, 0))
|
|
|
for i in range(-3, 4)
|
|
|
])
|
|
|
|
|
|
self.play(
|
|
|
Create(axes, run_time=2),
|
|
|
LaggedStart(*[Write(label) for label in x_labels], lag_ratio=0.3),
|
|
|
)
|
|
|
self.wait(0.5)
|
|
|
|
|
|
# 修正2:使用MathTex包装数学公式
|
|
|
sin_graph = axes.plot(lambda x: np.sin(x), color=GREEN)
|
|
|
sin_label = axes.get_graph_label(
|
|
|
sin_graph,
|
|
|
MathTex(r"\sin(x)", color=GREEN), # 使用MathTex替代Tex
|
|
|
x_val=-3 * PI,
|
|
|
direction=UP
|
|
|
)
|
|
|
|
|
|
self.play(
|
|
|
Create(sin_graph, run_time=3),
|
|
|
Write(sin_label, run_time=1),
|
|
|
rate_func=linear
|
|
|
)
|
|
|
self.wait()
|
|
|
|
|
|
# 修正3:余弦公式同样使用MathTex
|
|
|
cos_graph = axes.plot(lambda x: np.cos(x), color=RED)
|
|
|
cos_label = axes.get_graph_label(
|
|
|
cos_graph,
|
|
|
MathTex(r"\cos(x)", color=RED), # 使用MathTex替代Tex
|
|
|
x_val=3 * PI,
|
|
|
direction=DOWN
|
|
|
)
|
|
|
|
|
|
self.play(
|
|
|
TransformFromCopy(sin_graph, cos_graph, path_arc=PI / 2, run_time=3),
|
|
|
FadeIn(cos_label, shift=DOWN),
|
|
|
)
|
|
|
self.wait()
|
|
|
|
|
|
# 动态垂直线(追踪动画)
|
|
|
tracker = ValueTracker(-3 * PI)
|
|
|
vert_line = always_redraw(lambda:
|
|
|
DashedLine(
|
|
|
axes.c2p(tracker.get_value(), -1.5),
|
|
|
axes.c2p(tracker.get_value(), 1.5),
|
|
|
color=YELLOW
|
|
|
)
|
|
|
)
|
|
|
|
|
|
dot_sin = always_redraw(lambda:
|
|
|
Dot(color=GREEN).move_to(axes.i2gp(tracker.get_value(), sin_graph))
|
|
|
)
|
|
|
dot_cos = always_redraw(lambda:
|
|
|
Dot(color=RED).move_to(axes.i2gp(tracker.get_value(), cos_graph))
|
|
|
)
|
|
|
|
|
|
self.play(
|
|
|
Create(vert_line),
|
|
|
GrowFromCenter(dot_sin),
|
|
|
GrowFromCenter(dot_cos)
|
|
|
)
|
|
|
self.play(
|
|
|
tracker.animate.set_value(3 * PI),
|
|
|
run_time=6,
|
|
|
rate_func=linear
|
|
|
)
|
|
|
self.wait()
|
|
|
|
|
|
# 修正4:相位差公式使用正确数学环境
|
|
|
equation = MathTex(
|
|
|
r"\cos(x) = \sin\left(x + \frac{\pi}{2}\right)", # 使用MathTex
|
|
|
color=YELLOW
|
|
|
).to_edge(UP)
|
|
|
|
|
|
self.play(
|
|
|
Write(equation),
|
|
|
sin_graph.animate.shift(LEFT * PI / 2).set_color(ORANGE),
|
|
|
run_time=2
|
|
|
)
|
|
|
self.wait(2)
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
config = {
|
|
|
"quality": "high_quality",
|
|
|
"preview": True,
|
|
|
"media_dir": "./output",
|
|
|
"pixel_height": 1080,
|
|
|
"pixel_width": 1920,
|
|
|
"background_color": "#1E1E1E"
|
|
|
}
|
|
|
|
|
|
with tempconfig(config):
|
|
|
scene = AnimatedFunctionPlot()
|
|
|
scene.render() |