def construct(self): axes = Axes(x_min=-0.5, x_max=6.5, y_min=-0.5, y_max=6.5, color=GREY, number_line_config={"tick_size": 0}) axes.center() wallis_rects_5 = WallisRectangles(rect_colors=[ "#FF0000", "#FF8000", "#FFFF00", "#00FF00", "#0080FF" ], order=5) wallis_rects_5.move_corner_to(axes.coords_to_point(0, 0)) quarter_circle = Sector( outer_radius=wallis_rects_5.get_height(), stroke_color=GREY, stroke_width=5.70, fill_opacity=0, ) quarter_circle.move_arc_center_to(wallis_rects_5.get_bottom_left()) self.add(wallis_rects_5, axes, quarter_circle) order = wallis_rects_5.get_order() inner_corners = [ rect.get_critical_point(UP + RIGHT) for rect in wallis_rects_5.get_layer(3) ] outer_corners = [ rect.get_critical_point(UP + RIGHT) for rect in wallis_rects_5.get_layer(4) ] inner_dots = VGroup(*[ Dot(corner, color=PINK, stroke_width=2, stroke_color=BLACK) for corner in inner_corners ]) outer_dots = VGroup(*[ Dot(corner, stroke_width=2, stroke_color=BLACK) for corner in outer_corners ]) inner_texts = VGroup(*[ TexMobject("(s_%d, s_%d)" % (order - k, k)) \ .scale(0.8) \ .set_color(PINK) \ .next_to(dot, LEFT+DOWN, buff = 0.05) for k, dot in zip(range(1, len(inner_dots) + 1), inner_dots) ]) outer_texts = VGroup(*[ TexMobject("(s_%d, s_%d)" % (order + 1 - k, k)) \ .scale(0.8) \ .set_color(WHITE) \ .next_to(dot, RIGHT+UP, buff = 0.05) for k, dot in zip(range(1, len(outer_dots) + 1), outer_dots) ]) self.add(inner_dots, outer_dots, inner_texts, outer_texts) self.wait()
def __init__(self, mobject_or_point, **kwargs): digest_config(self, kwargs) big_dot = Dot( radius=FRAME_X_RADIUS + FRAME_Y_RADIUS, stroke_width=0, fill_color=self.color, fill_opacity=0, ) little_dot = Dot(radius=0) little_dot.set_fill(self.color, opacity=self.opacity) little_dot.move_to(mobject_or_point) Transform.__init__(self, big_dot, little_dot, **kwargs)
def generate_points(self): self.line_group = VGroup() self.dot_group = VGroup() vertices = self.generate_vertices_from_string(self.walk_string) for k in range(len(vertices) - 1): line = Line(vertices[k], vertices[k + 1], color=self.get_mob_color_by_number(k)) dot = Dot(vertices[k], color=self.dot_color) self.line_group.add(line) self.dot_group.add(dot) self.dot_group.add(Dot(vertices[-1], color=self.dot_color)) self.add(self.line_group, self.dot_group) self.horizontally_center()
def increment(self, run_time_per_anim=1): moving_dot = Dot( self.counting_dot_starting_position, radius=self.count_dot_starting_radius, color=self.digit_place_colors[0], ) moving_dot.generate_target() moving_dot.set_fill(opacity=0) kwargs = { "run_time": run_time_per_anim } continue_rolling_over = True first_move = True place = 0 while continue_rolling_over: added_anims = [] if first_move: added_anims += self.get_digit_increment_animations() first_move = False moving_dot.target.replace( self.dot_template_iterators[place].next() ) self.play(MoveToTarget(moving_dot), *added_anims, **kwargs) self.curr_configurations[place].add(moving_dot) if len(self.curr_configurations[place].split()) == self.get_place_max(place): full_configuration = self.curr_configurations[place] self.curr_configurations[place] = VGroup() place += 1 center = full_configuration.get_center_of_mass() radius = 0.6 * max( full_configuration.get_width(), full_configuration.get_height(), ) circle = Circle( radius=radius, stroke_width=0, fill_color=self.digit_place_colors[place], fill_opacity=0.5, ) circle.move_to(center) moving_dot = VGroup(circle, full_configuration) moving_dot.generate_target() moving_dot[0].set_fill(opacity=0) else: continue_rolling_over = False
def get_dot_template(self, place): # This should be replaced for non-base-10 counting scenes dots = VGroup(*[ Dot( point, radius=0.25, fill_opacity=0, stroke_width=2, stroke_color=WHITE, ) for point in self.get_template_configuration(place) ]) dots.scale_to_fit_height(self.dot_configuration_height) return dots
def show_ghost_movement(self, vector): if isinstance(vector, Arrow): vector = vector.get_end() - vector.get_start() elif len(vector) == 2: vector = np.append(np.array(vector), 0.0) x_max = int(FRAME_X_RADIUS + abs(vector[0])) y_max = int(FRAME_Y_RADIUS + abs(vector[1])) dots = VMobject(*[ Dot(x * RIGHT + y * UP) for x in range(-x_max, x_max) for y in range(-y_max, y_max) ]) dots.set_fill(BLACK, opacity=0) dots_halfway = dots.copy().shift(vector / 2).set_fill(WHITE, 1) dots_end = dots.copy().shift(vector) self.play(Transform(dots, dots_halfway, rate_func=rush_into)) self.play(Transform(dots, dots_end, rate_func=rush_from)) self.remove(dots)
def construct(self): # Setup axes_group = self.axes_group pos_axis, time_axis = axes_group[:2] title_pq = self.title_pq walk_q = self.walk_q parts_q = self.parts_q l_arrow = self.l_arrow self.add(axes_group, title_pq, walk_q, l_arrow) walk_q_copy = walk_q.copy() # Q_4 -> P_4 steps_qp = VGroup(*[ TextMobject(text) for text in [ "1. 找到路径终点的位置坐标$h$", "2. 找到最晚一次穿过$\\frac{h}{2}$的时刻", "3. 在这个时刻上进行分割", "4. 将第一段水平翻转", "5. 拼接两个片段" ] ]) for step in steps_qp: step.set_color(YELLOW) step.add_background_rectangle() step1_qp, step2_qp, step3_qp, step4_qp, step5_qp = steps_qp # 1. Find the endpoint step1_qp.next_to(time_axis.number_to_point(4.5), UP) end_horiz_line = DashedLine(LEFT_SIDE, RIGHT_SIDE, color=YELLOW) end_horiz_line.move_to(pos_axis.number_to_point(-4)) end_horiz_line.horizontally_center() end_brace_line = DashedLine(time_axis.number_to_point(8), walk_q.get_end_point()) end_brace = Brace(end_brace_line, direction=RIGHT, color=YELLOW) h = TexMobject("h").set_color(YELLOW) end_brace.put_at_tip(h) self.play(Write(step1_qp), ShowCreation(end_horiz_line), run_time=1) self.play(GrowFromCenter(end_brace), GrowFromCenter(h)) self.wait(1.5) self.play(FadeOut(step1_qp)) # 2. Find the last time it GOES THROUGH half its final value half_point = walk_q.get_arrow_end_point(3) step2_qp.next_to(time_axis.number_to_point(4.5), UP) half_horiz_line = end_horiz_line.copy().shift(2 * UP) half_brace_line = DashedLine(time_axis.number_to_point(4), half_point) half_brace = Brace(half_brace_line, direction=RIGHT, color=YELLOW) half_h = TexMobject("\\frac{h}{2}").set_color(YELLOW) half_brace.put_at_tip(half_h) half_dot = Dot(half_point, color=YELLOW) self.play(FadeIn(step2_qp), run_time=1) self.wait(0.5) self.play( ReplacementTransform(end_brace, half_brace), ReplacementTransform(end_horiz_line, half_horiz_line), ReplacementTransform(h, half_h[0]), Write(half_h[1:]), ) self.play(DrawBorderThenFill(half_dot)) self.wait(1.5) self.play( FadeOut(VGroup(step2_qp, half_horiz_line, half_brace, half_h))) # 3. Split vert_line = DashedLine(2.5 * UP, 2.5 * DOWN, color=YELLOW) vert_line.move_to(half_point) step3_qp.next_to(vert_line, UP) left_part_q, right_part_q = parts_q self.play(ShowCreation(vert_line), Write(step3_qp), run_time=1) self.play( FadeOut(half_dot), left_part_q.shift, 0.5 * DOWN + 0.5 * LEFT, right_part_q.shift, 0.5 * UP + 0.5 * RIGHT, ) self.wait(1.5) self.play(FadeOut(vert_line), FadeOut(step3_qp)) # 4. Flip the first segment horizontally flip_axis = DashedLine(2 * UP, 2 * DOWN, color=GREY) flip_axis.move_to(left_part_q) step4_qp.next_to(flip_axis, DOWN) self.play( ShowCreation(flip_axis), Write(step4_qp), run_time=1, ) self.play( left_part_q.flip, Animation(flip_axis), ) self.wait(1.5) self.play(FadeOut(step4_qp), FadeOut(flip_axis)) # 5. Put the pieces together step5_qp.shift(2.5 * DOWN) flip_arrow_anims = walk_q.get_flip_arrows_animation(3, color=ORANGE) self.play(Write(step5_qp), run_time=1) self.wait(0.5) self.play(flip_arrow_anims, right_part_q.set_color, ORANGE) self.wait(0.5) self.play( left_part_q.shift, 2.5 * UP + 0.5 * RIGHT, right_part_q.shift, 3.5 * UP + 0.5 * LEFT, Animation(step5_qp), ) self.wait(0.5) self.play(FadeOut(step5_qp)) self.wait(1.5) # Now Reset self.play(FadeOut(walk_q)) self.play(FadeIn(walk_q_copy)) self.wait()
def construct(self): # Setup axes_group = self.axes_group title_pq = self.title_pq walk_p = self.walk_p parts_p = self.parts_p r_arrow = self.r_arrow self.add(axes_group, title_pq, walk_p, r_arrow) walk_p_copy = walk_p.copy() # P_4 -> Q_4 steps_pq = VGroup(*[ TextMobject(text) for text in [ "1. 第一步是沿着正方向走的", "2. 找到第一次到达最大值的时刻", "3. 在这个时刻上进行分割", "4. 将第一段水平翻转", "5. 拼接两个片段" ] ]) for step in steps_pq: step.set_color(YELLOW) step.add_background_rectangle() step1_pq, step2_pq, step3_pq, step4_pq, step5_pq = steps_pq # 1. Check the first step of the walk step1_circle = Circle(color=YELLOW) first_arrow = walk_p.get_arrow_by_number(0) step1_circle.surround(first_arrow) step1_pq.next_to(step1_circle, RIGHT + DOWN) self.play(ShowCreation(step1_circle), Write(step1_pq), run_time=1) self.wait(1.5) self.play(FadeOut(step1_circle), FadeOut(step1_pq)) # 2. Find the first time it reaches the maximum peak = walk_p.get_arrow_end_point(3) horiz_line = DashedLine(2.5 * LEFT, 2.5 * RIGHT, color=YELLOW) horiz_line.move_to(peak) dot = Dot(color=YELLOW) dot.move_to(peak) step2_pq.next_to(horiz_line, UP) self.play(ShowCreation(horiz_line), DrawBorderThenFill(dot), Write(step2_pq), run_time=1) self.wait(1.5) self.play(FadeOut(horiz_line), FadeOut(step2_pq)) # 3. Split vert_line = DashedLine(2.5 * UP, 2.5 * DOWN, color=YELLOW) vert_line.move_to(peak) step3_pq.next_to(vert_line, DOWN) left_part_p, right_part_p = parts_p self.play(ShowCreation(vert_line), Write(step3_pq), run_time=1) self.play( FadeOut(dot), left_part_p.shift, 0.5 * DOWN + 0.5 * LEFT, right_part_p.shift, DOWN + 0.5 * RIGHT, ) self.wait(1.5) self.play(FadeOut(vert_line), FadeOut(step3_pq)) # 4. Flip the first segment horizontally flip_axis = DashedLine(2 * UP, 2 * DOWN, color=GREY) flip_axis.move_to(left_part_p) step4_pq.next_to(flip_axis, DOWN) self.play( ShowCreation(flip_axis), Write(step4_pq), run_time=1, ) self.play( left_part_p.flip, Animation(flip_axis), ) self.wait(1.5) self.play(FadeOut(step4_pq), FadeOut(flip_axis)) # 5. Put the pieces together step5_pq.move_to(dot) flip_arrow_anims = walk_p.get_flip_arrows_animation(3, color=GREEN) self.play(Write(step5_pq), run_time=1) self.wait(0.5) self.play(flip_arrow_anims, right_part_p.set_color, GREEN) self.wait(0.5) self.play( left_part_p.shift, 1.5 * DOWN + 0.5 * RIGHT, right_part_p.shift, 3 * DOWN + 0.5 * LEFT, Animation(step5_pq), ) self.wait(0.5) self.play(FadeOut(step5_pq)) self.wait(1.5) # Now Reset self.play(FadeOut(walk_p)) self.play(FadeIn(walk_p_copy)) self.wait()
def label(self, point_or_points): if len(point_or_points.shape) == 1: self.add(Dot(point_or_points, color=RED)) else: for point in point_or_points: self.add(Dot(point, color=RED))