146 lines
4.5 KiB
Python
146 lines
4.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
from manim import *
|
|
|
|
class ParabolaUp(Scene):
|
|
# 定义常量坐标
|
|
X_MIN, X_MAX = -4, 4
|
|
Y_MIN, Y_MAX = -3, 5
|
|
LEGEND_X = 3.5
|
|
LEGEND_Y_START = 3
|
|
LABEL_X = 2.0
|
|
|
|
def construct(self):
|
|
# 创建坐标轴系统
|
|
axes = Axes(
|
|
x_range=[self.X_MIN, self.X_MAX, 1],
|
|
y_range=[self.Y_MIN, self.Y_MAX, 1],
|
|
axis_config={"color": BLACK}
|
|
)
|
|
axes_labels = axes.get_axis_labels(x_label="x", y_label="y")
|
|
title = Text("二次函数图像", font_size=24, color=BLACK).to_edge(UP)
|
|
|
|
# 创建三个二次函数图像
|
|
graph1 = axes.plot(
|
|
lambda x: 0.5 * x**2,
|
|
color=BLUE,
|
|
x_range=[self.X_MIN, self.X_MAX]
|
|
)
|
|
graph2 = axes.plot(
|
|
lambda x: -0.5 * x**2,
|
|
color=RED,
|
|
x_range=[self.X_MIN, self.X_MAX]
|
|
)
|
|
graph3 = DashedVMobject(
|
|
axes.plot(lambda x: 0, color=GREEN, x_range=[self.X_MIN, self.X_MAX]),
|
|
num_dashes=50
|
|
)
|
|
|
|
# 创建函数表达式标签
|
|
label1 = MathTex(r"y = 0.5x^2", font_size=24, color=BLUE)
|
|
label1.move_to(axes.c2p(self.LABEL_X, 0.5 * self.LABEL_X**2 + 0.5))
|
|
label2 = MathTex(r"y = -0.5x^2", font_size=24, color=RED)
|
|
label2.move_to(axes.c2p(self.LABEL_X, -0.5 * self.LABEL_X**2 - 0.5))
|
|
label3 = MathTex(r"y = 0", font_size=24, color=GREEN)
|
|
label3.move_to(axes.c2p(self.LABEL_X, 0.5))
|
|
|
|
# 创建顶点标记
|
|
vertex_dot = Dot(axes.c2p(0, 0), color=BLACK, radius=0.08)
|
|
vertex_label = Text("顶点(0,0)", font_size=20, color=BLACK)
|
|
vertex_label.next_to(vertex_dot, DOWN, buff=0.1)
|
|
|
|
# 创建图例
|
|
legend_group = VGroup()
|
|
colors = [BLUE, RED, GREEN]
|
|
labels = ["a>0", "a<0", "a=0"]
|
|
styles = [None, None, DashedLine]
|
|
|
|
for i, (color, text, style) in enumerate(zip(colors, labels, styles)):
|
|
y_pos = self.LEGEND_Y_START - i * 0.8
|
|
pos = axes.c2p(self.LEGEND_X, y_pos)
|
|
|
|
if style is DashedLine:
|
|
line = DashedLine(
|
|
start=pos + LEFT*0.5,
|
|
end=pos + RIGHT*0.5,
|
|
color=color,
|
|
dash_length=0.1
|
|
)
|
|
else:
|
|
line = Line(
|
|
start=pos + LEFT*0.5,
|
|
end=pos + RIGHT*0.5,
|
|
color=color
|
|
)
|
|
|
|
text_item = Text(text, font_size=20, color=BLACK)
|
|
text_item.next_to(line, RIGHT, buff=0.2)
|
|
legend_item = VGroup(line, text_item)
|
|
legend_group.add(legend_item)
|
|
|
|
# 动画序列
|
|
self.play(
|
|
Create(axes),
|
|
Write(axes_labels),
|
|
Write(title),
|
|
run_time=2
|
|
)
|
|
self.wait(0.5)
|
|
|
|
# 绘制第一条抛物线
|
|
self.play(
|
|
Create(graph1),
|
|
Write(label1),
|
|
run_time=1.5
|
|
)
|
|
self.play(
|
|
Create(vertex_dot),
|
|
Write(vertex_label),
|
|
run_time=1
|
|
)
|
|
self.wait(0.5)
|
|
|
|
# 绘制第二条抛物线
|
|
self.play(
|
|
Create(graph2),
|
|
Write(label2),
|
|
run_time=1.5
|
|
)
|
|
self.wait(0.5)
|
|
|
|
# 绘制第三条抛物线
|
|
self.play(
|
|
Create(graph3),
|
|
Write(label3),
|
|
run_time=1.5
|
|
)
|
|
self.wait(0.5)
|
|
|
|
# 添加图例
|
|
self.play(
|
|
LaggedStart(*[FadeIn(item) for item in legend_group], lag_ratio=0.3),
|
|
run_time=2
|
|
)
|
|
self.wait(2)
|
|
|
|
if __name__ == "__main__":
|
|
# 导入必要的模块
|
|
import sys
|
|
import os
|
|
|
|
# 设置 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
|
|
# 使用临时配置渲染场景(配置只在with块内有效)
|
|
with tempconfig({
|
|
"quality": "high_quality",
|
|
"background_color": WHITE,
|
|
"preview": True
|
|
}):
|
|
# 实例化场景类
|
|
scene = ParabolaUp()
|
|
# 执行渲染流程(包含文件生成和预览)
|
|
scene.render() |