mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
BuildFiveFromFour of eop/combinations
This commit is contained in:
parent
e95acbdce7
commit
0e7fbe73b8
1 changed files with 338 additions and 4 deletions
|
@ -36,6 +36,8 @@ def get_stack(
|
|||
obj1, obj2, n, k,
|
||||
fixed_start = None,
|
||||
fixed_end = None,
|
||||
obj_to_obj_buff = SMALL_BUFF,
|
||||
vertical_buff = MED_SMALL_BUFF,
|
||||
):
|
||||
stack = VGroup()
|
||||
for indices in it.combinations(range(n), k):
|
||||
|
@ -47,9 +49,9 @@ def get_stack(
|
|||
term.add_to_back(fixed_start.copy())
|
||||
if fixed_end:
|
||||
term.add(fixed_end.copy())
|
||||
term.arrange_submobjects(RIGHT, buff = SMALL_BUFF)
|
||||
term.arrange_submobjects(RIGHT, buff = obj_to_obj_buff)
|
||||
stack.add(term)
|
||||
stack.arrange_submobjects(DOWN)
|
||||
stack.arrange_submobjects(DOWN, buff = vertical_buff)
|
||||
return stack
|
||||
|
||||
def get_stacks(obj1, obj2, n, **kwargs):
|
||||
|
@ -802,12 +804,13 @@ class ProbabilityOfThreeWomenInGroupOfFive(Scene):
|
|||
])
|
||||
return lineup
|
||||
|
||||
def get_lineup(self, *mobjects):
|
||||
def get_lineup(self, *mobjects, **kwargs):
|
||||
buff = kwargs.get("buff", MED_SMALL_BUFF)
|
||||
lines = VGroup(*[
|
||||
Line(ORIGIN, self.item_line_width*RIGHT)
|
||||
for mob in mobjects
|
||||
])
|
||||
lines.arrange_submobjects(RIGHT)
|
||||
lines.arrange_submobjects(RIGHT, buff = buff)
|
||||
items = VGroup()
|
||||
for line, mob in zip(lines, mobjects):
|
||||
item = VectorizedPoint() if mob is None else mob.copy()
|
||||
|
@ -824,6 +827,337 @@ class RememberThisSensation(TeacherStudentsScene):
|
|||
self.change_student_modes("confused", "pondering", "erm")
|
||||
self.dither(2)
|
||||
|
||||
class GroupsOf6(Scene):
|
||||
def construct(self):
|
||||
title = TexMobject("2^6 =", "64", "\\text{ Possibilities}")
|
||||
title.to_edge(UP, buff = MED_SMALL_BUFF)
|
||||
title.highlight_by_tex("64", YELLOW)
|
||||
man, woman = Male(), Female()
|
||||
stacks = get_stacks(man, woman, 6, vertical_buff = SMALL_BUFF)
|
||||
stacks.scale_to_fit_height(6.25)
|
||||
stacks.to_edge(DOWN, buff = MED_SMALL_BUFF)
|
||||
women_groups = VGroup()
|
||||
for stack in stacks:
|
||||
for lineup in stack:
|
||||
group = VGroup()
|
||||
for item in lineup:
|
||||
if "female" in item.get_tex_string():
|
||||
group.add(item)
|
||||
women_groups.add(group)
|
||||
|
||||
numbers = VGroup()
|
||||
for stack in stacks:
|
||||
number = TexMobject(str(len(stack)))
|
||||
number.next_to(stack, UP, SMALL_BUFF)
|
||||
numbers.add(number)
|
||||
|
||||
self.add(title)
|
||||
self.play(LaggedStart(
|
||||
LaggedStart, stacks,
|
||||
lambda s : (FadeIn, s),
|
||||
run_time = 3,
|
||||
))
|
||||
self.play(Write(numbers, run_time = 3))
|
||||
self.dither()
|
||||
self.play(LaggedStart(
|
||||
ApplyMethod, women_groups,
|
||||
lambda m : (m.highlight, PINK),
|
||||
lag_ratio = 0.1,
|
||||
rate_func = wiggle,
|
||||
run_time = 6,
|
||||
))
|
||||
|
||||
class GroupsOf7(Scene):
|
||||
def construct(self):
|
||||
stack = get_stack(Male(), Female(), 7, 3)
|
||||
question = TextMobject(
|
||||
"How many groups \\\\ of 7 with 3 ", "$\\female$", "?"
|
||||
)
|
||||
question.highlight_by_tex("female", MAROON_B)
|
||||
question.shift(1.5*UP)
|
||||
|
||||
self.add(question)
|
||||
for n, item in enumerate(stack):
|
||||
item.center()
|
||||
number = TexMobject(str(n))
|
||||
number.next_to(ORIGIN, DOWN, LARGE_BUFF)
|
||||
self.add(item, number)
|
||||
self.dither(0.2)
|
||||
self.remove(item, number)
|
||||
self.add(item, number)
|
||||
self.dither(2)
|
||||
|
||||
class BuildFiveFromFour(ProbabilityOfThreeWomenInGroupOfFive):
|
||||
def construct(self):
|
||||
self.show_all_configurations_of_four()
|
||||
self.organize_into_stacks()
|
||||
self.walk_through_stacks()
|
||||
self.split_into_two_possibilities()
|
||||
self.combine_stacks()
|
||||
|
||||
def show_all_configurations_of_four(self):
|
||||
man, woman = Male(), Female()
|
||||
n = 4
|
||||
vects = [
|
||||
1.5*UP,
|
||||
0.5*UP,
|
||||
3.5*RIGHT,
|
||||
1.5*RIGHT,
|
||||
]
|
||||
lineup_groups = VGroup()
|
||||
for k in range(n+1):
|
||||
lineup_group = VGroup()
|
||||
for tup in it.product(*[[man, woman]]*k):
|
||||
lineup = self.get_lineup(*list(tup) + (n-k)*[None])
|
||||
lineup.scale(1.4*(0.9)**k)
|
||||
lineup.move_to(0.5*DOWN)
|
||||
for mob, vect in zip(tup, vects):
|
||||
if mob is woman:
|
||||
lineup.shift(vect)
|
||||
else:
|
||||
lineup.shift(-vect)
|
||||
lineup_group.add(lineup)
|
||||
lineup_groups.add(lineup_group)
|
||||
|
||||
n_possibilities = TexMobject(
|
||||
"2 \\cdot", "2 \\cdot", "2 \\cdot", "2",
|
||||
"\\text{ Possibilities}"
|
||||
)
|
||||
n_possibilities.to_edge(UP)
|
||||
twos = VGroup(*n_possibilities[-2::-1])
|
||||
two_anims = [
|
||||
ReplacementTransform(
|
||||
VectorizedPoint(twos[0].get_center()),
|
||||
twos[0]
|
||||
)
|
||||
] + [
|
||||
ReplacementTransform(t1.copy(), t2)
|
||||
for t1, t2 in zip(twos, twos[1:])
|
||||
]
|
||||
|
||||
curr_lineup_group = lineup_groups[0]
|
||||
self.play(
|
||||
ShowCreation(curr_lineup_group[0]),
|
||||
)
|
||||
for i, lineup_group in enumerate(lineup_groups[1:]):
|
||||
anims = [ReplacementTransform(curr_lineup_group, lineup_group)]
|
||||
anims += two_anims[:i+1]
|
||||
if i == 0:
|
||||
anims.append(FadeIn(n_possibilities[-1]))
|
||||
self.remove(twos)
|
||||
self.play(*anims)
|
||||
self.dither()
|
||||
curr_lineup_group = lineup_group
|
||||
self.lineups = curr_lineup_group
|
||||
|
||||
eq_16 = TexMobject("=", "16")
|
||||
eq_16.move_to(twos.get_right())
|
||||
eq_16.highlight_by_tex("16", YELLOW)
|
||||
self.play(
|
||||
n_possibilities[-1].next_to, eq_16, RIGHT,
|
||||
twos.next_to, eq_16, LEFT,
|
||||
FadeIn(eq_16),
|
||||
)
|
||||
self.dither()
|
||||
|
||||
n_possibilities.add(eq_16)
|
||||
self.n_possibilities = n_possibilities
|
||||
|
||||
def organize_into_stacks(self):
|
||||
lineups = self.lineups
|
||||
stacks = VGroup(*[VGroup() for x in range(5)])
|
||||
for lineup in lineups:
|
||||
women = filter(
|
||||
lambda m : "female" in m.get_tex_string(),
|
||||
lineup.items
|
||||
)
|
||||
stacks[len(women)].add(lineup)
|
||||
stacks.generate_target()
|
||||
stacks.target.scale(0.75)
|
||||
for stack in stacks.target:
|
||||
stack.arrange_submobjects(DOWN, buff = SMALL_BUFF)
|
||||
stacks.target.arrange_submobjects(
|
||||
RIGHT, buff = MED_LARGE_BUFF, aligned_edge = DOWN
|
||||
)
|
||||
stacks.target.to_edge(DOWN, buff = MED_SMALL_BUFF)
|
||||
|
||||
self.play(MoveToTarget(
|
||||
stacks,
|
||||
run_time = 2,
|
||||
path_arc = np.pi/2
|
||||
))
|
||||
self.dither()
|
||||
|
||||
self.stacks = stacks
|
||||
|
||||
def walk_through_stacks(self):
|
||||
stacks = self.stacks
|
||||
numbers = VGroup()
|
||||
|
||||
for stack in stacks:
|
||||
rect = SurroundingRectangle(stack)
|
||||
rect.set_stroke(WHITE, 2)
|
||||
self.play(ShowCreation(rect))
|
||||
for n, lineup in enumerate(stack):
|
||||
lineup_copy = lineup.copy()
|
||||
lineup_copy.highlight(YELLOW)
|
||||
number = TexMobject(str(n+1))
|
||||
number.next_to(stack, UP)
|
||||
self.add(lineup_copy, number)
|
||||
self.dither(0.25)
|
||||
self.remove(lineup_copy, number)
|
||||
self.add(number)
|
||||
numbers.add(number)
|
||||
self.play(FadeOut(rect))
|
||||
self.dither()
|
||||
|
||||
stacks.numbers = numbers
|
||||
|
||||
def split_into_two_possibilities(self):
|
||||
bottom_stacks = self.stacks
|
||||
top_stacks = bottom_stacks.deepcopy()
|
||||
top_group = VGroup(top_stacks, top_stacks.numbers)
|
||||
|
||||
h_line = DashedLine(SPACE_WIDTH*LEFT, SPACE_WIDTH*RIGHT)
|
||||
|
||||
#Initial split
|
||||
self.play(
|
||||
FadeOut(self.n_possibilities),
|
||||
top_group.to_edge, UP, MED_SMALL_BUFF,
|
||||
)
|
||||
self.play(ShowCreation(h_line))
|
||||
|
||||
#Add extra slot
|
||||
for stacks, sym in (top_stacks, Female()), (bottom_stacks, Male()):
|
||||
sym.set_fill(opacity = 0)
|
||||
new_stacks = VGroup()
|
||||
to_fade_in = VGroup()
|
||||
for stack in stacks:
|
||||
new_stack = VGroup()
|
||||
for lineup in stack:
|
||||
new_lineup = self.get_lineup(*[
|
||||
Female() if "female" in item.get_tex_string() else Male()
|
||||
for item in lineup.items
|
||||
] + [sym], buff = SMALL_BUFF)
|
||||
new_lineup.replace(lineup, dim_to_match = 1)
|
||||
new_stack.add(new_lineup)
|
||||
for group in lineup.items, lineup.lines:
|
||||
point = VectorizedPoint(group[-1].get_center())
|
||||
group.add(point)
|
||||
to_fade_in.add(lineup.items[-1])
|
||||
new_stacks.add(new_stack)
|
||||
new_stacks.arrange_submobjects(
|
||||
RIGHT, buff = MED_LARGE_BUFF, aligned_edge = DOWN
|
||||
)
|
||||
new_stacks.move_to(stacks, DOWN)
|
||||
stacks.target = new_stacks
|
||||
stacks.to_fade_in = to_fade_in
|
||||
|
||||
stacks.numbers.generate_target()
|
||||
for number, stack in zip(stacks.numbers.target, new_stacks):
|
||||
number.next_to(stack, UP)
|
||||
|
||||
for stacks in top_stacks, bottom_stacks:
|
||||
self.play(
|
||||
MoveToTarget(stacks),
|
||||
MoveToTarget(stacks.numbers)
|
||||
)
|
||||
self.dither()
|
||||
|
||||
#Fill extra slot
|
||||
add_man = TextMobject("Add", "$\\male$")
|
||||
add_man.highlight_by_tex("male", BLUE)
|
||||
add_woman = TextMobject("Add", "$\\female$")
|
||||
add_woman.highlight_by_tex("female", MAROON_B)
|
||||
|
||||
add_man.next_to(ORIGIN, DOWN).to_edge(LEFT)
|
||||
add_woman.to_corner(UP+LEFT)
|
||||
|
||||
for stacks, words in (bottom_stacks, add_man), (top_stacks, add_woman):
|
||||
to_fade_in = stacks.to_fade_in
|
||||
to_fade_in.set_fill(opacity = 1)
|
||||
to_fade_in.save_state()
|
||||
Transform(to_fade_in, VGroup(words[-1])).update(1)
|
||||
|
||||
self.play(Write(words, run_time = 1))
|
||||
self.play(to_fade_in.restore)
|
||||
self.dither()
|
||||
|
||||
#Perform shift
|
||||
dist = top_stacks[1].get_center()[0] - top_stacks[0].get_center()[0]
|
||||
self.play(
|
||||
top_stacks.shift, dist*RIGHT/2,
|
||||
top_stacks.numbers.shift, dist*RIGHT/2,
|
||||
bottom_stacks.shift, dist*LEFT/2,
|
||||
bottom_stacks.numbers.shift, dist*LEFT/2,
|
||||
)
|
||||
self.dither()
|
||||
self.play(*map(FadeOut, [add_man, add_woman, h_line]))
|
||||
|
||||
self.set_variables_as_attrs(top_stacks, bottom_stacks)
|
||||
|
||||
def combine_stacks(self):
|
||||
top_stacks = self.top_stacks
|
||||
bottom_stacks = self.bottom_stacks
|
||||
|
||||
rects = VGroup()
|
||||
for stacks, color in (top_stacks, MAROON_C), (bottom_stacks, BLUE_D):
|
||||
for stack in stacks:
|
||||
rect = SurroundingRectangle(stack)
|
||||
rect.set_stroke(color, 2)
|
||||
rects.add(rect)
|
||||
stack.add(rect)
|
||||
|
||||
new_numbers = VGroup()
|
||||
|
||||
self.play(LaggedStart(ShowCreation, rects, run_time = 1))
|
||||
for i, top_stack in enumerate(top_stacks[:-1]):
|
||||
bottom_stack = bottom_stacks[i+1]
|
||||
top_number = top_stacks.numbers[i]
|
||||
bottom_number = bottom_stacks.numbers[i+1]
|
||||
movers = top_stack, top_number, bottom_number
|
||||
for mob in movers:
|
||||
mob.generate_target()
|
||||
top_stack.target.move_to(bottom_stack.get_top(), DOWN)
|
||||
plus = TexMobject("+")
|
||||
expr = VGroup(top_number.target, plus, bottom_number.target)
|
||||
expr.arrange_submobjects(RIGHT, buff = SMALL_BUFF)
|
||||
expr.next_to(top_stack.target.get_top(), UP)
|
||||
|
||||
new_number = TexMobject(str(
|
||||
len(top_stack) + len(bottom_stack) - 2
|
||||
))
|
||||
new_number.next_to(expr, UP)
|
||||
new_numbers.add(new_number)
|
||||
|
||||
self.play(
|
||||
Write(plus),
|
||||
*map(MoveToTarget, movers)
|
||||
)
|
||||
self.play(
|
||||
VGroup(top_stacks[-1], top_stacks.numbers[-1]).align_to,
|
||||
bottom_stacks, DOWN
|
||||
)
|
||||
self.dither()
|
||||
|
||||
new_numbers.add_to_back(bottom_stacks.numbers[0].copy())
|
||||
new_numbers.add(top_stacks.numbers[-1].copy())
|
||||
new_numbers.highlight(PINK)
|
||||
self.play(Write(new_numbers, run_time = 3))
|
||||
self.dither()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue