初一数学

 

  1 # -*- coding: utf-8 -*-
  2 from manim import *
  3 import sys
  4 import io
  5 
  6 # 设置标准输出编码
  7 sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
  8 
  9 class ZigzagGraph(Scene):
 10     def construct(self):
 11         # === 1. 节点位置定义 ===
 12         positions = {
 13             -1: [-6, 2, 0],
 14             2: [-6, 0, 0],
 15             4: [-4, 2, 0],
 16             -3: [-4, 0, 0],
 17             -5: [-2, 2, 0],
 18             6: [-2, 0, 0],
 19             8: [0, 2, 0],
 20             -7: [0, 0, 0],
 21             -9: [2, 2, 0],
 22             10: [2, 0, 0],
 23             'A': [4, 2, 0],
 24             'B': [6, 2, 0],
 25             'C': [6, 0, 0],
 26             'D': [8, 0, 0],
 27         }
 28 
 29         # === 2. 创建节点 ===
 30         nodes = {}
 31         for label, pos in positions.items():
 32             if isinstance(label, int):
 33                 color = RED if label < 0 else GREEN
 34                 # 使用LaTeX的\textbf{}来加粗
 35                 node = MathTex(r"\textbf{" + str(label) + "}", color=color, font_size=36)
 36             else:
 37                 node = MathTex(r"\textbf{" + label + "}", color=BLUE, font_size=36)
 38             node.move_to(pos)
 39             nodes[label] = node
 40 
 41         # 创建省略号
 42         dots1 = MathTex(r"\cdots", font_size=40).move_to([positions['A'][0], positions[10][1], 0])  
 43         dots2 = MathTex(r"\cdots", font_size=40).move_to([positions['D'][0], positions['B'][1], 0])  
 44         
 45         # === 3. 创建箭头 ===
 46         arrows = []
 47         connections = [
 48             (-1, 2), (2, -3), (-3, 4), (4, -5), (-5, 6),
 49             (6, -7), (-7, 8), (8, -9), (-9, 10),
 50             (10, dots1), (dots1, 'A'), ('A', 'B'),
 51             ('B', 'C'), ('C', 'D'), ('D', dots2)
 52         ]
 53 
 54         for start, end in connections:
 55             start_obj = nodes.get(start) or (dots1 if start is dots1 else dots2 if start is dots2 else None)
 56             end_obj = nodes.get(end) or (dots1 if end is dots1 else dots2 if end is dots2 else None)
 57             if start_obj and end_obj:
 58                 arrow = Arrow(start_obj.get_center(), end_obj.get_center(), buff=0.3, stroke_width=3, color=GRAY)
 59                 arrows.append(arrow)
 60 
 61         # === 4. 创建高亮圆圈 ===
 62         # 黄色圆圈(负奇数)
 63         yellow_labels = [-1, -3, -5, -7, -9]
 64         yellow_circles = [Circle(radius=0.5, color=YELLOW, stroke_width=5, fill_opacity=0.2).move_to(nodes[label].get_center()) 
 65                           for label in yellow_labels]
 66 
 67         # 蓝色圆圈(dots1, B, D)
 68         blue_targets = [dots1, nodes['B'], nodes['D']]
 69         blue_circles = [Circle(radius=0.5, color=BLUE, stroke_width=5, fill_opacity=0.2).move_to(obj.get_center()) 
 70                         for obj in blue_targets]
 71 
 72         # === 5. 整体布局调整 ===
 73         full_group = VGroup(
 74             *nodes.values(), dots1, dots2, *arrows, *yellow_circles, *blue_circles
 75         )
 76         full_group.scale(0.6).shift(LEFT * 1 + UP * 2)
 77 
 78         # 分组管理
 79         static_elements = VGroup(*nodes.values(), dots1, dots2)
 80         arrow_elements = VGroup(*arrows)
 81         yellow_circle_elements = VGroup(*yellow_circles)
 82         blue_circle_elements = VGroup(*blue_circles)
 83 
 84         # === 6. 动画流程 ===
 85         # 添加静态元素
 86         self.add(static_elements)
 87 
 88         # 动画1:逐步绘制路径(使用基础的rate_func)
 89         self.play(LaggedStart(*[Create(arrow) for arrow in arrow_elements], lag_ratio=0.1), 
 90                   run_time=4, rate_func=smooth)
 91 
 92         self.wait(1.5)
 93 
 94         # === 新增:提前显示问题部分 ===
 95         # 创建问题容器
 96         questions_container = VGroup()
 97         questions_container.next_to(full_group, DOWN, buff=1.5).shift(LEFT * 3)
 98         
 99         # 问题标题
100         questions_title = Text("思考问题", font_size=32, color=YELLOW)
101         
102         # 问题内容
103         questions = [
104             "(1) A位置的数是正数还是负数?",
105             "(2) A,B,C,D中哪些位置是负数?",
106             "(3) 第2046个数是正数还是负数?在哪个位置?"
107         ]
108         
109         question_elements = [questions_title]
110         for q in questions:
111             question = Text(q, font_size=24, color=WHITE)
112             question_elements.append(question)
113         
114         # 排列问题元素
115         questions_container.add(*question_elements)
116         questions_container.arrange(DOWN, aligned_edge=LEFT, buff=0.5)
117         
118         # 逐个显示问题
119         for element in question_elements:
120             self.play(Write(element, run_time=0.8), element.animate.scale(1.05).scale(1), run_time=0.8)
121             self.wait(0.8)
122         
123         self.wait(2)
124         
125         # 问题淡出
126         self.play(FadeOut(questions_container, shift=DOWN*0.3, scale=0.9), run_time=1)
127         self.wait(0.5)
128 
129         # === 7. 步骤说明 ===
130         # 创建步骤容器
131         steps_container = VGroup()
132         steps_container.next_to(full_group, DOWN, buff=1.5).shift(LEFT * 3)
133         
134         # 标题
135         title = Text("规律分析", font_size=32, color=YELLOW)
136         
137         # Step 1
138         step1 = VGroup(
139             Text("步骤 1:符号规律分析", font_size=26, color=YELLOW),
140             Text("排列:-1(负)、2(正)、-3(负)、4(正)、-5(负)、6(正)……", font_size=22),
141             Text("规律:奇数为负数,偶数为正数", font_size=22, color=GREEN)
142         ).arrange(DOWN, aligned_edge=LEFT, buff=0.3)
143         
144         # Step 2
145         step2 = VGroup(
146             Text("步骤 2:位置循环规律", font_size=26, color=YELLOW),
147             Text("每4个数为一个位置循环周期:上 → 下 → 右 → 上", font_size=22),
148             Text("每个周期:上(-奇)→下(+偶)→右(-奇)→上(+偶)", font_size=22, color=GREEN)
149         ).arrange(DOWN, aligned_edge=LEFT, buff=0.3)
150         
151         # 排列所有元素
152         steps_container.add(title, step1, step2)
153         steps_container.arrange(DOWN*0.8, aligned_edge=LEFT, buff=0.4)
154         
155         # 逐个显示元素(带动画)
156         elements_to_show = [title, step1[0], step1[1], step1[2], step2[0], step2[1], step2[2]]
157         
158         for element in elements_to_show:
159             self.play(Write(element, run_time=0.8), element.animate.scale(1.05).scale(1), run_time=0.8)
160             self.wait(0.8)
161         
162         self.wait(2)
163         
164         # 步骤消失(带动画)
165         self.play(FadeOut(steps_container, shift=DOWN*0.3, scale=0.9), run_time=1)
166         self.wait(0.5)
167         
168         # === 8. 圆圈高亮动画(移到规律分析之后)===
169         # 动画2:黄色高亮(同时出现)
170         self.play(FadeIn(yellow_circle_elements, scale=0.8), 
171                   run_time=1.5)
172         self.wait(0.5)
173 
174         # 动画3:蓝色高亮(依次出现)
175         self.play(LaggedStart(*[FadeIn(circle, scale=0.8) for circle in blue_circles], lag_ratio=0.3), 
176                   run_time=2)
177 
178         self.wait(1.5)
179         
180         # === 9. 问答内容 ===
181         qa_container = VGroup()
182         # 设置问答内容的初始位置在图形下方更远的位置
183         qa_container.next_to(full_group, DOWN, buff=3).shift(LEFT * 3)
184         
185         answers = [
186             "A在\"上\"位置,对应周期内第4个数(偶数)→ 正数",
187             "B(第5个,奇数→负)、D(第7个,奇数→负)位置是负数",
188             "2046是偶数→正数;2046÷4=511余2→对应\"下\"位置(C位置)"
189         ]
190         
191         # 创建问答元素
192         qa_elements = []
193         for i, (q, a) in enumerate(zip(questions, answers)):
194             question = Text(q, font_size=24, color=YELLOW)
195             answer = Text(a, font_size=22)
196             
197             # 设置初始位置(在更下方)
198             if i == 0:
199                 question.move_to(qa_container)
200             else:
201                 question.next_to(qa_elements[-1][1], DOWN, buff=0.6)
202             
203             answer.next_to(question, DOWN, buff=0.2)
204             answer.set_color_by_gradient(GREEN, BLUE)
205             
206             qa_elements.append((question, answer))
207         
208         # 逐个显示问答(从下方向上移动到合适位置)
209         for question, answer in qa_elements:
210             # 保存最终位置
211             final_question_pos = question.get_center()
212             final_answer_pos = answer.get_center()
213             
214             # 设置初始位置在更下方
215             question.shift(UP * 1.5)
216             answer.shift(UP * 1.5)
217             
218             # 问题从下方向上移动并显示
219             self.play(
220                 question.animate.move_to(final_question_pos),
221                 FadeIn(question),
222                 run_time=0.8
223             )
224             self.wait(2)
225             
226             # 答案从下方向上移动并显示
227             self.play(
228                 answer.animate.move_to(final_answer_pos),
229                 FadeIn(answer),
230                 run_time=0.8
231             )
232             self.wait(2.5)
233         
234         self.wait(3)
235         
236         # # 最终淡出效果
237         # self.play(
238         #     full_group.animate.scale(0.9).fade(0.5),
239         #     *[FadeOut(elem) for pair in qa_elements for elem in pair],
240         #     run_time=1.5
241         # )
242         # self.wait()

 

manim -pql alam.py ZigzagGraph
View Code

 

posted @ 2025-11-28 16:57  AlamZ  阅读(4)  评论(0)    收藏  举报