def construct(self): # Setup line = NumberLine() house = House() drunk = Drunk(direction=RIGHT) house.place_on(ORIGIN) drunk.step_on(ORIGIN) t_equals = TexMobject("t = ") time = TexMobject("0") time.next_to(t_equals, RIGHT, buff=0.15) VGroup(t_equals, time).next_to(line, DOWN, buff=0.5) old_drunk = drunk.copy() old_time = time.copy() self.add(house, line, drunk, t_equals) # Start wandering for k in range(20): new_time = TexMobject("%s" % str(k + 1)) new_time.next_to(t_equals, RIGHT, buff=0.15) self.play( DrunkWander(drunk, random.choice([-1, 1]), total_time=0.5), Transform(time, new_time, rate_func=snap_head_and_tail(smooth), run_time=0.5), ) self.wait() # Reset self.play(Transform(time, old_time), Transform(drunk, old_drunk)) self.wait()
def construct(self): line = NumberLine() self.add(line) drunk = Drunk(direction=UP) drunk.step_on(ORIGIN) self.play(DrawBorderThenFill(drunk)) self.wait() for k in range(10): self.play(DrunkWander(drunk, random.choice([-1, 1]))) self.wait()
def get_axis(self, min_val, max_val, extra_config): config = dict(self.number_line_config) config.update(extra_config) return NumberLine(x_min=min_val, x_max=max_val, **config)
def setup_axes(self, animate=False): # TODO, once eoc is done, refactor this to be less redundant. x_num_range = float(self.x_max - self.x_min) self.space_unit_to_x = self.x_axis_width / x_num_range if self.x_labeled_nums is None: self.x_labeled_nums = [] if self.x_leftmost_tick is None: self.x_leftmost_tick = self.x_min x_axis = NumberLine(x_min=self.x_min, x_max=self.x_max, unit_size=self.space_unit_to_x, tick_frequency=self.x_tick_frequency, leftmost_tick=self.x_leftmost_tick, numbers_with_elongated_ticks=self.x_labeled_nums, color=self.axes_color) x_axis.shift(self.graph_origin - x_axis.number_to_point(0)) if len(self.x_labeled_nums) > 0: if self.exclude_zero_label: self.x_labeled_nums = filter(lambda x: x != 0, self.x_labeled_nums) x_axis.add_numbers(*self.x_labeled_nums) if self.x_axis_label: x_label = TextMobject(self.x_axis_label) x_label.next_to(x_axis.get_tick_marks(), UP + RIGHT, buff=SMALL_BUFF) x_label.shift_onto_screen() x_axis.add(x_label) self.x_axis_label_mob = x_label y_num_range = float(self.y_max - self.y_min) self.space_unit_to_y = self.y_axis_height / y_num_range if self.y_labeled_nums is None: self.y_labeled_nums = [] if self.y_bottom_tick is None: self.y_bottom_tick = self.y_min y_axis = NumberLine( x_min=self.y_min, x_max=self.y_max, unit_size=self.space_unit_to_y, tick_frequency=self.y_tick_frequency, leftmost_tick=self.y_bottom_tick, numbers_with_elongated_ticks=self.y_labeled_nums, color=self.axes_color, line_to_number_vect=LEFT, ) y_axis.shift(self.graph_origin - y_axis.number_to_point(0)) y_axis.rotate(np.pi / 2, about_point=y_axis.number_to_point(0)) if len(self.y_labeled_nums) > 0: if self.exclude_zero_label: self.y_labeled_nums = filter(lambda y: y != 0, self.y_labeled_nums) y_axis.add_numbers(*self.y_labeled_nums) if self.y_axis_label: y_label = TextMobject(self.y_axis_label) y_label.next_to(y_axis.get_tick_marks(), UP + RIGHT, buff=SMALL_BUFF) y_label.shift_onto_screen() y_axis.add(y_label) self.y_axis_label_mob = y_label if animate: self.play(Write(VGroup(x_axis, y_axis))) else: self.add(x_axis, y_axis) self.x_axis, self.y_axis = self.axes = VGroup(x_axis, y_axis) self.default_graph_colors = it.cycle(self.default_graph_colors)
def setup(self): pos_axis = NumberLine(x_min=-4.5, x_max=2.5, color=WHITE) pos_axis.rotate(np.pi / 2) pos_axis.add_tip() time_axis = NumberLine(x_min=0, x_max=9.5, color=WHITE) time_axis.add_tip() vec = pos_axis.number_to_point(0) - time_axis.number_to_point(0) time_axis.shift(vec) pos_text = TextMobject("位置") pos_text.next_to(pos_axis.number_to_point(2.5), LEFT) time_text = TextMobject("时间") time_text.next_to(time_axis.number_to_point(9.5), DOWN) axes_group = VGroup(pos_axis, time_axis, pos_text, time_text) axes_group.center() title_pq = TexMobject("P_4", "570", "Q_4") title_pq.scale(1.5) title_pq.to_corner(UP + RIGHT) for part, color in zip(title_pq, [ORANGE, BLACK, GREEN]): part.set_color(color) r_arrow = TexMobject("\\rightarrow") l_arrow = TexMobject("\\leftarrow") for arrow in (r_arrow, l_arrow): arrow.scale(1.5) arrow.move_to(title_pq[1]) sequence_p, sequence_q = sequences = ["UDUUDUDD", "DDUDDUDD"] colors = [ORANGE, GREEN] walk_p, walk_q = walks = [ RandomWalk1DArrow(sequence, up_color = color, down_color = color) \ .move_start_to(pos_axis.number_to_point(0)) for sequence, color in zip(sequences, colors) ] parts_p, parts_q = [walk.split_at(3) for walk in walks] self.axes_group = axes_group self.title_pq = title_pq self.walk_p = walk_p self.walk_q = walk_q self.parts_p = parts_p self.parts_q = parts_q self.r_arrow = r_arrow self.l_arrow = l_arrow
def construct(self): # Chart on the left colors = [WHITE, ORANGE, GREEN] titles = VGroup(*[ TexMobject(text).set_color(color) for text, color in zip(["n", "p_n", "q_n"], colors) ]) contents = VGroup(*[ VGroup(*[ TexMobject("%d" % num) for num in [k, central_binomial_coeff(k), central_binomial_coeff(k)] ]) for k in range(8) ]) titles.arrange_submobjects(RIGHT, buff=1) for num, line in enumerate(contents): for k, element in enumerate(line): buff = 0.6 + 0.8 * num element.next_to(titles[k], DOWN, aligned_edge=LEFT, buff=buff) element.set_color(colors[k]) sep_line = Line(ORIGIN, 4.5 * RIGHT, stroke_width=5) sep_line.next_to(titles, DOWN) chart = VGroup(titles, contents, sep_line) chart.set_height(7) chart.center().to_edge(LEFT) self.add(chart) # Figures on the right std_zero_pos_axis = NumberLine(x_min=-2, x_max=2, color=GREY, unit_size=0.25, tick_size=0.05) std_zero_pos_axis.rotate(np.pi / 2) std_nocross_pos_axis = NumberLine(x_min=-4, x_max=4, color=GREY, unit_size=0.25, tick_size=0.05) std_nocross_pos_axis.rotate(np.pi / 2) std_time_axis = NumberLine(x_min=0, x_max=5.5, color=GREY, unit_size=0.25, tick_size=0.05) std_zero_axes = VGroup(std_zero_pos_axis, std_time_axis) std_nocross_axes = VGroup(std_nocross_pos_axis, std_time_axis) zero_walks = VGroup() for sequence in ["UUDD", "UDUD", "UDDU", "DDUU", "DUDU", "DUUD"]: axes = std_zero_axes.copy() zero_walk = RandomWalk1DArrow(sequence, step_size=0.25) zero_walk.move_start_to(axes[0].number_to_point(0)) zero_walks.add(VGroup(axes, zero_walk)) zero_walks.arrange_submobjects_in_grid(2, 3, buff=0.5) zero_rect = SurroundingRectangle(zero_walks, color=ORANGE, buff=0.4) zero_walks.add(zero_rect) nocross_walks = VGroup() for sequence in ["DDDD", "DDUD", "DDDU", "UUUU", "UUDU", "UUUD"]: axes = std_nocross_axes.copy() nocross_walk = RandomWalk1DArrow(sequence, step_size=0.25) nocross_walk.move_start_to(axes[0].number_to_point(0)) nocross_walks.add(VGroup(axes, nocross_walk)) nocross_walks.arrange_submobjects_in_grid(2, 3, buff=0.5) nocross_rect = SurroundingRectangle(nocross_walks, color=GREEN, buff=0.4) nocross_walks.add(nocross_rect) relation = TexMobject("p_2", "=", "q_2", "=", "6") relation[0].set_color(ORANGE) relation[2].set_color(GREEN) relation.scale(1.5) figure = VGroup(zero_walks, relation, nocross_walks) figure.arrange_submobjects(DOWN) figure.set_height(7) figure.center().to_edge(RIGHT) self.add(figure) self.wait()
def construct(self): # Setup pos_axis = NumberLine(x_min=-3.5, x_max=3.5, color=WHITE) pos_axis.rotate(np.pi / 2) pos_axis.add_tip() time_axis = NumberLine(x_min=0, x_max=9.5, color=WHITE) time_axis.add_tip() pos_text = TextMobject("位置") pos_text.next_to(pos_axis.number_to_point(3.5), LEFT) time_text = TextMobject("时间") time_text.next_to(time_axis.number_to_point(9.5), DOWN) group = VGroup(pos_axis, time_axis, pos_text, time_text) group.to_edge(LEFT, buff=2) self.add(group) # Some preparations sequences = [ "UDDDUDUD", "DUUDDDUD", "DDUUUDUD", "UUUDDUDU", "UDDDUDUD" ] nums = [1, 3, 7, -1, 1] walks = [ RandomWalk1DArrow(sequence).move_start_to( pos_axis.number_to_point(0)) for sequence in sequences ] parts = [walk.split_at(num) for walk, num in zip(walks, nums)] split_lines = [ DashedLine(TOP, BOTTOM, color = GREY) \ .move_to(time_axis.number_to_point(num+1)) for num in nums ] zero_words = [ TextMobject("“正点到家” \\\\ $P_%s$" % str((num+1)//2)) \ .next_to(line, LEFT).shift(2.8 * DOWN).set_color(ORANGE) for num, line in zip(nums, split_lines) ] nocross_words = [ TextMobject("“不经过家门” \\\\ $Q_%s$" % str(4-(num+1)//2)) \ .next_to(line, RIGHT).shift(2.8 * DOWN).set_color(GREEN) for num, line in zip(nums, split_lines) ] for words, direction in zip([zero_words, nocross_words], [RIGHT, LEFT]): for word in words: text, symbol = VGroup(word[:-2]), VGroup(word[-2:]) symbol.scale(1.5) symbol.next_to(text, DOWN, aligned_edge=direction) word.add_background_rectangle() # Demonstrate how to split self.add(walks[0], split_lines[0], zero_words[0], nocross_words[0]) l = len(walks) for k in range(l - 1): cur_walk = walks[k] cur_line = split_lines[k] cur_zero_word = zero_words[k] cur_nocross_word = nocross_words[k] next_walk = walks[k + 1] next_line = split_lines[k + 1] next_zero_word = zero_words[k + 1] next_nocross_word = nocross_words[k + 1] part1, part2 = parts[k] cur_walk.save_state() self.play( part1.set_color, ORANGE, part2.set_color, GREEN, ) self.wait() self.play(cur_walk.restore) self.wait() self.play( ReplacementTransform(cur_walk, next_walk), ReplacementTransform(cur_line, next_line), ReplacementTransform(cur_zero_word, next_zero_word), ReplacementTransform(cur_nocross_word, next_nocross_word), ) self.wait()
def construct(self): # Setup pos_axis = NumberLine(x_min=-3.5, x_max=3.5, color=WHITE) pos_axis.rotate(np.pi / 2) pos_axis.add_tip() time_axis = NumberLine(x_min=0, x_max=9.5, color=WHITE) time_axis.add_tip() house = House() house.rotate(np.pi / 2) house.place_on(pos_axis.number_to_point(0)) zero_drunk = Drunk(direction=UP, color=self.zero_color) zero_drunk.step_on(pos_axis.number_to_point(0)) neg_drunk = Drunk(direction=UP, color=self.neg_color) neg_drunk.step_on(pos_axis.number_to_point(0)) group = VGroup(house, VGroup(pos_axis, time_axis), zero_drunk, neg_drunk) group.to_edge(LEFT) pos_text = TextMobject("位置") pos_text.next_to(pos_axis.number_to_point(3.5), LEFT) time_text = TextMobject("时间") time_text.next_to(time_axis.number_to_point(9.5), DOWN) self.add(group, pos_text, time_text) old_zero_drunk = zero_drunk.copy() old_neg_drunk = neg_drunk.copy() # Start Wandering zero_sequence = "UUUDDDDU" zero_walk = RandomWalk1DArrow( zero_sequence, up_color=self.zero_color, down_color=self.zero_color, ) zero_walk.move_start_to(pos_axis.number_to_point(0)) neg_sequence = "DDUDDUDU" neg_walk = RandomWalk1DArrow( neg_sequence, up_color=self.neg_color, down_color=self.neg_color, ) neg_walk.move_start_to(pos_axis.number_to_point(0)) for k, (zero_char, neg_char) in enumerate(zip(zero_sequence, neg_sequence)): zero_increment = 1 if zero_char == "U" else -1 neg_increment = 1 if neg_char == "U" else -1 zero_arrow = zero_walk.get_arrow_by_number(k) neg_arrow = neg_walk.get_arrow_by_number(k) self.play(DrunkWander(zero_drunk, zero_increment, direction=UP), DrunkWander(neg_drunk, neg_increment, direction=UP), ShowCreation(zero_arrow), ShowCreation(neg_arrow)) self.wait() # Reset self.play( Transform(zero_drunk, old_zero_drunk), Transform(neg_drunk, old_neg_drunk), FadeOut(zero_walk), FadeOut(neg_walk), ) self.wait()
def construct(self): # Setup pos_axis = NumberLine(x_min=-3.5, x_max=3.5, color=WHITE) pos_axis.rotate(np.pi / 2) pos_axis.add_tip() time_axis = NumberLine(x_min=0, x_max=9.5, color=WHITE) time_axis.add_tip() house = House() house.rotate(np.pi / 2) house.place_on(pos_axis.number_to_point(0)) drunk = Drunk(direction=UP) drunk.step_on(pos_axis.number_to_point(0)) group = VGroup(house, VGroup(pos_axis, time_axis), drunk) group.to_edge(LEFT) pos_text = TextMobject("位置") pos_text.next_to(pos_axis.number_to_point(3.5), LEFT) time_text = TextMobject("时间") time_text.next_to(time_axis.number_to_point(9.5), DOWN) self.add(group, pos_text, time_text) old_drunk = drunk.copy() # Start Wandering sequence = "UDUDDDUD" random_walk = RandomWalk1DArrow(sequence) random_walk.move_start_to(pos_axis.number_to_point(0)) for k, walk_char in enumerate(sequence): increment = 1 if walk_char == "U" else -1 arrow = random_walk.get_arrow_by_number(k) self.play( DrunkWander(drunk, increment, direction=UP), ShowCreation(arrow), ) self.wait() # Reset self.play(Transform(drunk, old_drunk), FadeOut(random_walk)) self.wait()