mirror of
https://github.com/3b1b/manim.git
synced 2025-08-21 05:44:04 +00:00
Preliminary end to animations of putnam.py
This commit is contained in:
parent
185097de58
commit
2697c48bf4
1 changed files with 303 additions and 23 deletions
326
putnam.py
326
putnam.py
|
@ -1161,8 +1161,6 @@ class RevisitTwoDCase(TwoDCase):
|
||||||
for x in range(2):
|
for x in range(2):
|
||||||
do_the_rounds()
|
do_the_rounds()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ThisIsWhereItGetsGood(TeacherStudentsScene):
|
class ThisIsWhereItGetsGood(TeacherStudentsScene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
self.teacher_says(
|
self.teacher_says(
|
||||||
|
@ -1172,27 +1170,309 @@ class ThisIsWhereItGetsGood(TeacherStudentsScene):
|
||||||
self.change_student_modes(*["hooray"]*3)
|
self.change_student_modes(*["hooray"]*3)
|
||||||
self.dither(2)
|
self.dither(2)
|
||||||
|
|
||||||
|
class ContrastTwoRandomProcesses(TwoDCase):
|
||||||
|
CONFIG = {
|
||||||
|
"radius" : 1.5,
|
||||||
|
"random_seed" : 0,
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
circle = Circle(color = WHITE, radius = self.radius)
|
||||||
|
point_mobs = self.get_point_mobs()
|
||||||
|
for point in point_mobs:
|
||||||
|
point.scale_in_place(1.5)
|
||||||
|
point.set_stroke(RED, 1)
|
||||||
|
labels = self.get_point_mob_labels()
|
||||||
|
self.get_labels_update(point_mobs, labels).update(1)
|
||||||
|
center_lines = self.get_center_lines()
|
||||||
|
point_label_groups = VGroup(*[
|
||||||
|
VGroup(*pair) for pair in zip(point_mobs, labels)
|
||||||
|
])
|
||||||
|
|
||||||
|
left_circles = VGroup(*[
|
||||||
|
VGroup(circle, *point_label_groups[:i+1]).copy()
|
||||||
|
for i in range(3)
|
||||||
|
])
|
||||||
|
right_circles = VGroup(
|
||||||
|
VGroup(circle, center_lines).copy(),
|
||||||
|
VGroup(
|
||||||
|
circle, center_lines,
|
||||||
|
point_label_groups[2]
|
||||||
|
).copy(),
|
||||||
|
VGroup(
|
||||||
|
circle, center_lines,
|
||||||
|
*point_label_groups[2::-1]
|
||||||
|
).copy(),
|
||||||
|
)
|
||||||
|
for circles in left_circles, right_circles:
|
||||||
|
circles.scale(0.5)
|
||||||
|
circles[0].to_edge(UP, buff = MED_LARGE_BUFF)
|
||||||
|
circles[2].to_edge(DOWN, buff = MED_LARGE_BUFF)
|
||||||
|
for c1, c2 in zip(circles, circles[1:]):
|
||||||
|
circles.add(Arrow(c1[0], c2[0], color = GREEN))
|
||||||
|
left_circles.shift(3*LEFT)
|
||||||
|
right_circles.shift(3*RIGHT)
|
||||||
|
|
||||||
|
vs = TextMobject("vs.")
|
||||||
|
self.show_creation_of_circle_group(left_circles)
|
||||||
|
self.play(Write(vs))
|
||||||
|
self.show_creation_of_circle_group(right_circles)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
def show_creation_of_circle_group(self, group):
|
||||||
|
circles = group[:3]
|
||||||
|
arrows = group[3:]
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
ShowCreation(circles[0][0]),
|
||||||
|
FadeIn(VGroup(*circles[0][1:])),
|
||||||
|
)
|
||||||
|
for c1, c2, arrow in zip(circles, circles[1:], arrows):
|
||||||
|
self.play(
|
||||||
|
GrowArrow(arrow),
|
||||||
|
ApplyMethod(
|
||||||
|
c1.copy().shift,
|
||||||
|
c2[0].get_center() - c1[0].get_center(),
|
||||||
|
remover = True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.add(c2)
|
||||||
|
n = len(c2) - len(c1)
|
||||||
|
self.play(*map(GrowFromCenter, c2[-n:]))
|
||||||
|
|
||||||
|
class Rewrite3DRandomProcedure(Scene):
|
||||||
|
def construct(self):
|
||||||
|
random_procedure = TextMobject("Random procedure")
|
||||||
|
underline = Line(LEFT, RIGHT)
|
||||||
|
underline.stretch_to_fit_width(random_procedure.get_width())
|
||||||
|
underline.scale(1.1)
|
||||||
|
underline.next_to(random_procedure, DOWN)
|
||||||
|
group = VGroup(random_procedure, underline)
|
||||||
|
group.to_corner(UP+LEFT)
|
||||||
|
|
||||||
|
words = VGroup(*map(TextMobject, [
|
||||||
|
"Choose 4 random points",
|
||||||
|
"Choose 3 random lines",
|
||||||
|
"Choose $P_4$ at random",
|
||||||
|
"Flip coin for each line \\\\ to get $P_1$, $P_2$, $P_3$",
|
||||||
|
]))
|
||||||
|
words.scale(0.8)
|
||||||
|
words.arrange_submobjects(DOWN, buff = MED_LARGE_BUFF)
|
||||||
|
words.next_to(underline, DOWN)
|
||||||
|
words[1].highlight(YELLOW)
|
||||||
|
cross = Cross(words[0])
|
||||||
|
cross.set_stroke(RED, 6)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
Write(random_procedure),
|
||||||
|
ShowCreation(underline)
|
||||||
|
)
|
||||||
|
self.play(FadeIn(words[0]))
|
||||||
|
self.play(ShowCreation(cross))
|
||||||
|
self.dither()
|
||||||
|
self.play(LaggedStart(FadeIn, words[1]))
|
||||||
|
self.play(LaggedStart(FadeIn, words[2]))
|
||||||
|
self.dither(2)
|
||||||
|
self.play(Write(words[3]))
|
||||||
|
self.dither(3)
|
||||||
|
|
||||||
|
class AntipodalViewOfThreeDCase(ExternallyAnimatedScene):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ThreeDAnswer(Scene):
|
||||||
|
def construct(self):
|
||||||
|
words = TextMobject(
|
||||||
|
"Probability that the tetrahedron contains center:",
|
||||||
|
"$\\frac{1}{8}$"
|
||||||
|
)
|
||||||
|
words.scale_to_fit_width(2*SPACE_WIDTH - 1)
|
||||||
|
words.to_edge(DOWN)
|
||||||
|
words[1].highlight(BLUE)
|
||||||
|
|
||||||
|
self.play(Write(words))
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
class FormalWriteupScreenCapture(ExternallyAnimatedScene):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Formality(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
words = TextMobject(
|
||||||
|
"Write-up by Ralph Howard and Paul Sisson (link below)"
|
||||||
|
)
|
||||||
|
words.scale(0.7)
|
||||||
|
words.to_corner(UP+LEFT, buff = MED_SMALL_BUFF)
|
||||||
|
|
||||||
|
self.student_says(
|
||||||
|
"How would you \\\\ write that down?",
|
||||||
|
target_mode = "sassy"
|
||||||
|
)
|
||||||
|
self.change_student_modes("confused", "sassy", "erm")
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
Write(words),
|
||||||
|
FadeOut(self.students[1].bubble),
|
||||||
|
FadeOut(self.students[1].bubble.content),
|
||||||
|
self.teacher.change, "raise_right_hand"
|
||||||
|
)
|
||||||
|
self.change_student_modes(
|
||||||
|
*["pondering"]*3,
|
||||||
|
look_at_arg = words
|
||||||
|
)
|
||||||
|
self.dither(8)
|
||||||
|
|
||||||
|
class BrilliantPuzzle(PiCreatureScene):
|
||||||
|
CONFIG = {
|
||||||
|
"random_seed" : 2,
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
students = self.students
|
||||||
|
tests = VGroup()
|
||||||
|
for student in students:
|
||||||
|
test = self.get_test()
|
||||||
|
test.move_to(0.75*student.get_center())
|
||||||
|
tests.add(test)
|
||||||
|
student.test = test
|
||||||
|
arrows = VGroup()
|
||||||
|
for s1, s2 in adjacent_pairs(self.students):
|
||||||
|
arrow = Arrow(
|
||||||
|
s1.get_center(), s2.get_center(),
|
||||||
|
buff = LARGE_BUFF
|
||||||
|
)
|
||||||
|
arrow.shift(-MED_SMALL_BUFF*arrow.get_vector())
|
||||||
|
arrow.highlight(RED)
|
||||||
|
arrows.add(arrow)
|
||||||
|
s1.right_arrow = arrow
|
||||||
|
s2.left_arrow = arrow
|
||||||
|
arrow.counterclockwise = True
|
||||||
|
|
||||||
|
title = TextMobject("Puzzle from Brilliant")
|
||||||
|
title.scale(0.75)
|
||||||
|
title.to_corner(UP+LEFT)
|
||||||
|
|
||||||
|
question = TextMobject("Expecte number of \\\\ circled students?")
|
||||||
|
question.to_corner(UP+RIGHT)
|
||||||
|
|
||||||
|
self.remove(students)
|
||||||
|
self.play(Write(title))
|
||||||
|
self.play(LaggedStart(GrowFromCenter, students))
|
||||||
|
self.play(
|
||||||
|
LaggedStart(Write, tests),
|
||||||
|
LaggedStart(
|
||||||
|
ApplyMethod, students,
|
||||||
|
lambda m : (m.change, "horrified", m.test)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(LaggedStart(
|
||||||
|
ApplyMethod, students,
|
||||||
|
lambda m : (m.change, "conniving")
|
||||||
|
))
|
||||||
|
self.play(LaggedStart(GrowArrow, arrows))
|
||||||
|
for x in range(2):
|
||||||
|
self.swap_arrows_randomly(arrows)
|
||||||
|
self.dither()
|
||||||
|
circles = self.circle_students()
|
||||||
|
self.play(Write(question))
|
||||||
|
for x in range(10):
|
||||||
|
self.swap_arrows_randomly(arrows, FadeOut(circles))
|
||||||
|
circles = self.circle_students()
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
####
|
||||||
|
|
||||||
|
def get_test(self):
|
||||||
|
lines = VGroup(*[Line(ORIGIN, 0.5*RIGHT) for x in range(6)])
|
||||||
|
lines.arrange_submobjects(DOWN, buff = SMALL_BUFF)
|
||||||
|
rect = SurroundingRectangle(lines)
|
||||||
|
rect.set_stroke(WHITE)
|
||||||
|
lines.set_stroke(WHITE, 2)
|
||||||
|
test = VGroup(rect, lines)
|
||||||
|
test.scale_to_fit_height(0.5)
|
||||||
|
return test
|
||||||
|
|
||||||
|
def create_pi_creatures(self):
|
||||||
|
self.students = VGroup(*[
|
||||||
|
PiCreature(
|
||||||
|
color = random.choice([BLUE_C, BLUE_D, BLUE_E, GREY_BROWN])
|
||||||
|
).scale(0.25).move_to(3*vect)
|
||||||
|
for vect in compass_directions(8)
|
||||||
|
])
|
||||||
|
return self.students
|
||||||
|
|
||||||
|
def get_arrow_swap_anim(self, arrow):
|
||||||
|
arrow.generate_target()
|
||||||
|
arrow.target.rotate_in_place(np.pi)
|
||||||
|
if arrow.counterclockwise:
|
||||||
|
arrow.target.highlight(GREEN)
|
||||||
|
else:
|
||||||
|
arrow.target.highlight(RED)
|
||||||
|
arrow.counterclockwise = not arrow.counterclockwise
|
||||||
|
return MoveToTarget(arrow, path_arc = np.pi)
|
||||||
|
|
||||||
|
def swap_arrows_randomly(self, arrows, *added_anims):
|
||||||
|
anims = []
|
||||||
|
for arrow in arrows:
|
||||||
|
if random.choice([True, False]):
|
||||||
|
anims.append(self.get_arrow_swap_anim(arrow))
|
||||||
|
self.play(*anims + list(added_anims))
|
||||||
|
|
||||||
|
def circle_students(self):
|
||||||
|
circles = VGroup()
|
||||||
|
for student in self.students:
|
||||||
|
ra, la = student.right_arrow, student.left_arrow
|
||||||
|
if ra.counterclockwise and not la.counterclockwise:
|
||||||
|
circle = Circle(color = YELLOW)
|
||||||
|
circle.scale_to_fit_height(1.2*student.get_height())
|
||||||
|
circle.move_to(student)
|
||||||
|
circles.add(circle)
|
||||||
|
self.play(
|
||||||
|
ShowCreation(circle),
|
||||||
|
Indicate(VGroup(ra, la))
|
||||||
|
)
|
||||||
|
return circles
|
||||||
|
|
||||||
|
class ScrollThroughBrilliantCourses(ExternallyAnimatedScene):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class BrilliantProbability(ExternallyAnimatedScene):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Promotion(PiCreatureScene):
|
||||||
|
CONFIG = {
|
||||||
|
"seconds_to_blink" : 5,
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
url = TextMobject("https://brilliant.org/3b1b/")
|
||||||
|
url.to_corner(UP+LEFT)
|
||||||
|
|
||||||
|
rect = Rectangle(height = 9, width = 16)
|
||||||
|
rect.scale_to_fit_height(5.5)
|
||||||
|
rect.next_to(url, DOWN)
|
||||||
|
rect.to_edge(LEFT)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
Write(url),
|
||||||
|
self.pi_creature.change, "raise_right_hand"
|
||||||
|
)
|
||||||
|
self.play(ShowCreation(rect))
|
||||||
|
self.dither(2)
|
||||||
|
self.change_mode("thinking")
|
||||||
|
self.dither()
|
||||||
|
self.look_at(url)
|
||||||
|
self.dither(10)
|
||||||
|
self.change_mode("happy")
|
||||||
|
self.dither(10)
|
||||||
|
self.change_mode("raise_right_hand")
|
||||||
|
self.dither(10)
|
||||||
|
|
||||||
|
self.remove(rect)
|
||||||
|
self.play(
|
||||||
|
url.next_to, self.pi_creature, UP+LEFT
|
||||||
|
)
|
||||||
|
url_rect = SurroundingRectangle(url)
|
||||||
|
self.play(ShowCreation(url_rect))
|
||||||
|
self.play(FadeOut(url_rect))
|
||||||
|
self.dither(3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue