Files
dsProject/dsLightRag/Manim/UnitCircleSin.py

189 lines
5.5 KiB
Python
Raw Normal View History

2025-08-14 15:45:08 +08:00
from manim import *
class ParabolaLesson(Scene):
# 坐标常量定义
LEFT_MARGIN = 3.2
AXIS_RANGE = [-4, 4, -1, 3]
# 颜色定义
BG_COLOR = "#F5F5F5"
CURVE_COLOR = "#00BFFF"
FOCUS_COLOR = "#FF4500"
DIRECTRIX_COLOR = "#AAAAAA"
def construct(self):
self.camera.background_color = self.BG_COLOR
self._intro()
self._discovery()
self._proof()
self._practice()
def _intro(self):
# 创建坐标系
axes = Axes(
x_range=[-4, 4, 1],
y_range=[-1, 3, 1],
axis_config={"color": BLACK},
tips=False
)
axes_labels = axes.get_axis_labels(x_label="x", y_label="y")
# 初始抛物线 (a=1)
a_value = ValueTracker(1)
parabola = always_redraw(lambda: axes.plot(
lambda x: a_value.get_value() * x ** 2,
color=self.CURVE_COLOR
))
# 添加所有元素
self.add(axes, axes_labels, parabola)
def _discovery(self):
# 标题
title = Tex("$a$是正数,开口向上", color=BLUE).to_edge(UP)
# 公式
formula = MathTex("y = a x^2", color=BLACK).next_to(title, DOWN)
# 滑杆
slider = NumberLine(
x_range=[0, 2, 0.5],
length=4,
color=BLACK,
include_numbers=True
).to_edge(DOWN)
slider_label = Tex("$a$值:", color=BLACK).next_to(slider, LEFT)
# 滑杆指示器
dot = Dot(color=RED).move_to(slider.n2p(1))
a_value = ValueTracker(1)
dot.add_updater(lambda d: d.move_to(slider.n2p(
a_value.get_value()
)))
a_text = always_redraw(lambda: DecimalNumber(
a_value.get_value(),
color=RED
).next_to(dot, UP))
# 添加元素
self.play(
Write(title),
Write(formula),
Create(slider),
Write(slider_label)
)
self.add(dot, a_text)
# 动画a值变化 (0.5 -> 1 -> 2)
self.play(
a_value.animate.set_value(0.5),
run_time=5,
rate_func=rate_functions.ease_in_out_sine
)
self.play(
a_value.animate.set_value(1),
run_time=5,
rate_func=rate_functions.ease_in_out_sine
)
self.play(
a_value.animate.set_value(2),
run_time=5,
rate_func=rate_functions.ease_in_out_sine
)
# 5秒静止帧
self.wait(5)
def _proof(self):
# 更新标题
new_title = Tex("$a$是负数,开口向下", color=BLUE).to_edge(UP)
# 滑杆范围变为负数
slider = NumberLine(
x_range=[-2, 0, 0.5],
length=4,
color=BLACK,
include_numbers=True
).to_edge(DOWN)
slider_label = Tex("$a$值:", color=BLACK).next_to(slider, LEFT)
# 更新滑杆指示器
a_value = ValueTracker(-1)
dot = Dot(color=RED).move_to(slider.n2p(-1))
dot.add_updater(lambda d: d.move_to(slider.n2p(
a_value.get_value()
)))
a_text = always_redraw(lambda: DecimalNumber(
a_value.get_value(),
color=RED
).next_to(dot, UP))
# 更新公式
formula = MathTex("y = a x^2", color=BLACK).next_to(new_title, DOWN)
# 焦点和准线
focus = always_redraw(lambda: Dot(
color=self.FOCUS_COLOR
).move_to([0, 1 / (4 * a_value.get_value()), 0]))
directrix = always_redraw(lambda: DashedLine(
start=[-4, -1 / (4 * a_value.get_value()), 0],
end=[4, -1 / (4 * a_value.get_value()), 0],
color=self.DIRECTRIX_COLOR
))
# 切换元素
self.play(
Transform(self.mobjects[0], new_title),
Transform(self.mobjects[1], formula),
Transform(self.mobjects[2], slider),
Transform(self.mobjects[3], slider_label)
)
self.add(focus, directrix)
# 动画a值变化 (-0.5 -> -1 -> -2)
self.play(
a_value.animate.set_value(-0.5),
run_time=5,
rate_func=rate_functions.ease_in_out_sine
)
self.play(
a_value.animate.set_value(-1),
run_time=5,
rate_func=rate_functions.ease_in_out_sine
)
self.play(
a_value.animate.set_value(-2),
run_time=5,
rate_func=rate_functions.ease_in_out_sine
)
# 5秒静止帧
self.wait(5)
def _practice(self):
# 添加练习题文本
practice = Tex(
"思考题:当$a=-1$时,\\\\焦点和准线在哪里?",
color=BLUE
).scale(0.8).to_edge(DOWN)
# 显示练习题
self.play(Write(practice))
self.wait(5)
if __name__ == "__main__":
# 全局指定 ctex 模板(一次性)
config.tex_template = TexTemplateLibrary.ctex
# 使用临时配置渲染场景配置只在with块内有效
with tempconfig({
"quality": "low_quality",
"preview": True,
"output_file": "ParabolaLesson"
}):
# 实例化场景类
scene = ParabolaLesson()
# 执行渲染流程(包含文件生成和预览)
scene.render()