mirror of
https://github.com/3b1b/manim.git
synced 2025-09-01 00:48:45 +00:00
Many more scenes from the prime spirals video
This commit is contained in:
parent
ccc51664f4
commit
d80af64798
1 changed files with 601 additions and 19 deletions
|
@ -193,6 +193,64 @@ class SpiralScene(MovingCameraScene):
|
||||||
|
|
||||||
# Scenes
|
# Scenes
|
||||||
|
|
||||||
|
class AltTitle(Scene):
|
||||||
|
def construct(self):
|
||||||
|
title_text = """
|
||||||
|
How pretty but pointless patterns\\\\
|
||||||
|
in polar plots of primes\\\\
|
||||||
|
prompt pretty important ponderings\\\\
|
||||||
|
on properties of those primes.
|
||||||
|
"""
|
||||||
|
words = [w + " " for w in title_text.split(" ") if w]
|
||||||
|
title = TextMobject(*words)
|
||||||
|
title.set_width(FRAME_WIDTH - 1)
|
||||||
|
|
||||||
|
title[2:5].set_color(TEAL)
|
||||||
|
title[12:15].set_color(YELLOW)
|
||||||
|
title.set_stroke(BLACK, 5, background=True)
|
||||||
|
|
||||||
|
image = ImageMobject("PrimeSpiral")
|
||||||
|
image.set_height(FRAME_HEIGHT)
|
||||||
|
rect = FullScreenFadeRectangle(fill_opacity=0.25)
|
||||||
|
|
||||||
|
self.add(image, rect)
|
||||||
|
|
||||||
|
for word in title:
|
||||||
|
self.play(
|
||||||
|
FadeIn(
|
||||||
|
word, run_time=0.05 * len(word),
|
||||||
|
lag_ratio=0.4,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class HoldUpMathExchange(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
title = TextMobject("Mathematics Stack Exchange")
|
||||||
|
title.scale(1.5)
|
||||||
|
title.to_edge(UP)
|
||||||
|
|
||||||
|
self.add(title)
|
||||||
|
self.play(self.teacher.change, "raise_right_hand", ORIGIN),
|
||||||
|
self.change_all_student_modes("thinking", look_at_arg=ORIGIN)
|
||||||
|
self.wait(3)
|
||||||
|
self.change_all_student_modes("confused", look_at_arg=ORIGIN)
|
||||||
|
self.wait(3)
|
||||||
|
|
||||||
|
|
||||||
|
class MathExchangeNames(Scene):
|
||||||
|
def construct(self):
|
||||||
|
names = VGroup(
|
||||||
|
TextMobject("dwymark"),
|
||||||
|
TextMobject("Greg Martin"),
|
||||||
|
)
|
||||||
|
names.arrange(DOWN, buff=1)
|
||||||
|
for name in names:
|
||||||
|
self.play(FadeInFrom(name, RIGHT))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
class MathExchange(ExternallyAnimatedScene):
|
class MathExchange(ExternallyAnimatedScene):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -224,7 +282,7 @@ class PrimesAndPi(Scene):
|
||||||
self.play(
|
self.play(
|
||||||
LaggedStart(*[
|
LaggedStart(*[
|
||||||
ApplyFunction(
|
ApplyFunction(
|
||||||
lambda m: m.set_color(YELLOW).scale(1.2),
|
lambda m: m.set_color(TEAL).scale(1.2),
|
||||||
prime
|
prime
|
||||||
)
|
)
|
||||||
for prime in primes
|
for prime in primes
|
||||||
|
@ -727,6 +785,22 @@ class RefresherOnPolarCoordinates(MovingCameraScene):
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
|
||||||
|
class IntroducePolarPlot(RefresherOnPolarCoordinates):
|
||||||
|
def construct(self):
|
||||||
|
self.plane = NumberPlane()
|
||||||
|
grid = self.get_polar_grid()
|
||||||
|
title = TextMobject("Polar coordinates")
|
||||||
|
title.scale(3)
|
||||||
|
title.set_stroke(BLACK, 10, background=True)
|
||||||
|
title.to_edge(UP)
|
||||||
|
|
||||||
|
self.add(grid, title)
|
||||||
|
self.play(
|
||||||
|
ShowCreation(grid, lag_ratio=0.1),
|
||||||
|
run_time=3,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ReplacePolarCoordinatesWithPrimes(RefresherOnPolarCoordinates):
|
class ReplacePolarCoordinatesWithPrimes(RefresherOnPolarCoordinates):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
coords, p_coords = [
|
coords, p_coords = [
|
||||||
|
@ -742,10 +816,10 @@ class ReplacePolarCoordinatesWithPrimes(RefresherOnPolarCoordinates):
|
||||||
|
|
||||||
some_prime = TextMobject("Some prime")
|
some_prime = TextMobject("Some prime")
|
||||||
some_prime.scale(1.5)
|
some_prime.scale(1.5)
|
||||||
some_prime.next_to(p_coords, UP, buff=1.5)
|
some_prime.next_to(p_coords.get_left(), DOWN, buff=1.5)
|
||||||
arrows = VGroup(*[
|
arrows = VGroup(*[
|
||||||
Arrow(
|
Arrow(
|
||||||
some_prime.get_bottom(), coord.get_top(),
|
some_prime.get_top(), coord.get_bottom(),
|
||||||
stroke_width=5,
|
stroke_width=5,
|
||||||
tip_length=0.4
|
tip_length=0.4
|
||||||
)
|
)
|
||||||
|
@ -859,7 +933,7 @@ class AskWhat(TeacherStudentsScene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
screen = self.screen
|
screen = self.screen
|
||||||
self.student_says(
|
self.student_says(
|
||||||
"I'm sory,\\\\what?!?",
|
"I'm sorry,\\\\what?!?",
|
||||||
target_mode="angry",
|
target_mode="angry",
|
||||||
look_at_arg=screen,
|
look_at_arg=screen,
|
||||||
student_index=2,
|
student_index=2,
|
||||||
|
@ -1079,7 +1153,7 @@ class HighlightGapsInSpirals(IntroducePrimePatterns):
|
||||||
self.set_scale(
|
self.set_scale(
|
||||||
scale=self.spiral_scale,
|
scale=self.spiral_scale,
|
||||||
spiral=p_spiral,
|
spiral=p_spiral,
|
||||||
target_p_spiral_width=5,
|
target_p_spiral_width=8,
|
||||||
run_time=0,
|
run_time=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1107,6 +1181,58 @@ class HighlightGapsInSpirals(IntroducePrimePatterns):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class QuestionIsMisleading(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
self.student_says(
|
||||||
|
"Whoa, is this some\\\\divine hidden structure\\\\in the primes?",
|
||||||
|
target_mode="surprised",
|
||||||
|
student_index=0,
|
||||||
|
added_anims=[
|
||||||
|
self.students[1].change, "pondering",
|
||||||
|
self.students[2].change, "pondering",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.wait(2)
|
||||||
|
|
||||||
|
self.students[0].bubble = None
|
||||||
|
self.teacher_says(
|
||||||
|
"Er...not exactly",
|
||||||
|
bubble_kwargs={"width": 3, "height": 2},
|
||||||
|
target_mode="guilty"
|
||||||
|
)
|
||||||
|
self.wait(3)
|
||||||
|
|
||||||
|
|
||||||
|
class JustPrimesLabel(Scene):
|
||||||
|
def construct(self):
|
||||||
|
text = TextMobject("Just the primes")
|
||||||
|
text.scale(2)
|
||||||
|
text.to_corner(UL)
|
||||||
|
self.play(Write(text))
|
||||||
|
self.wait(3)
|
||||||
|
self.play(FadeOutAndShift(text, DOWN))
|
||||||
|
|
||||||
|
|
||||||
|
class DirichletComingUp(Scene):
|
||||||
|
def construct(self):
|
||||||
|
image = ImageMobject("Dirichlet")
|
||||||
|
image.set_height(3)
|
||||||
|
words = TextMobject(
|
||||||
|
"Coming up: \\\\", "Dirichlet's theorem",
|
||||||
|
alignment="",
|
||||||
|
)
|
||||||
|
words.set_color_by_tex("Dirichlet's", YELLOW)
|
||||||
|
words.scale(1.5)
|
||||||
|
words.next_to(image, RIGHT)
|
||||||
|
Group(words, image).center()
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FadeInFrom(image, RIGHT),
|
||||||
|
FadeInFrom(words, LEFT),
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
class ImagineYouFoundIt(TeacherStudentsScene):
|
class ImagineYouFoundIt(TeacherStudentsScene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
you = self.students[1]
|
you = self.students[1]
|
||||||
|
@ -1116,6 +1242,7 @@ class ImagineYouFoundIt(TeacherStudentsScene):
|
||||||
self.teacher,
|
self.teacher,
|
||||||
)
|
)
|
||||||
bubble = you.get_bubble(direction=LEFT)
|
bubble = you.get_bubble(direction=LEFT)
|
||||||
|
bubble[-1].set_fill(GREEN_SCREEN, 1)
|
||||||
|
|
||||||
you_label = TextMobject("You")
|
you_label = TextMobject("You")
|
||||||
arrow = Vector(DOWN)
|
arrow = Vector(DOWN)
|
||||||
|
@ -1130,19 +1257,19 @@ class ImagineYouFoundIt(TeacherStudentsScene):
|
||||||
)
|
)
|
||||||
self.play(Blink(you))
|
self.play(Blink(you))
|
||||||
self.play(
|
self.play(
|
||||||
ShowCreation(bubble),
|
FadeIn(bubble),
|
||||||
FadeOut(you_label),
|
FadeOut(you_label),
|
||||||
FadeOut(arrow),
|
FadeOut(arrow),
|
||||||
you.change, "pondering",
|
you.change, "pondering",
|
||||||
)
|
)
|
||||||
self.play(you.look_at, bubble.get_corner(UR))
|
self.play(you.look_at, bubble.get_corner(UR))
|
||||||
self.play(Blink(you))
|
self.play(Blink(you))
|
||||||
self.wait(3)
|
self.wait()
|
||||||
self.play(you.change, "hooray")
|
self.play(you.change, "hooray")
|
||||||
self.play(Blink(you))
|
self.play(Blink(you))
|
||||||
self.wait(2)
|
self.wait()
|
||||||
self.play(you.change, "sassy", bubble.get_top())
|
self.play(you.change, "sassy", bubble.get_top())
|
||||||
self.wait(3)
|
self.wait(6)
|
||||||
|
|
||||||
|
|
||||||
class ShowSpiralsForWholeNumbers(CountSpirals):
|
class ShowSpiralsForWholeNumbers(CountSpirals):
|
||||||
|
@ -1248,6 +1375,18 @@ class ShowSpiralsForWholeNumbers(CountSpirals):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PrimeSpiralsAtScale1000(SpiralScene):
|
||||||
|
def construct(self):
|
||||||
|
spiral = self.get_prime_p_spiral(10000)
|
||||||
|
self.add(spiral)
|
||||||
|
self.set_scale(
|
||||||
|
scale=1000,
|
||||||
|
spiral=spiral,
|
||||||
|
target_p_spiral_width=15,
|
||||||
|
run_time=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SeparateIntoTwoQuestions(Scene):
|
class SeparateIntoTwoQuestions(Scene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
top_q = TextMobject("Why do", " primes", " cause", " spirals", "?")
|
top_q = TextMobject("Why do", " primes", " cause", " spirals", "?")
|
||||||
|
@ -1615,11 +1754,30 @@ class IntroduceResidueClassTerminology(Scene):
|
||||||
self.simple_english()
|
self.simple_english()
|
||||||
|
|
||||||
def add_title(self):
|
def add_title(self):
|
||||||
title = TextMobject("Overly-fancy terminology")
|
title = TextMobject("Overly-fancy ", "terminology")
|
||||||
title.scale(1.5)
|
title.scale(1.5)
|
||||||
title.to_edge(UP, buff=MED_SMALL_BUFF)
|
title.to_edge(UP, buff=MED_SMALL_BUFF)
|
||||||
underline = Line().match_width(title)
|
underline = Line().match_width(title)
|
||||||
underline.next_to(title, DOWN, SMALL_BUFF)
|
underline.next_to(title, DOWN, SMALL_BUFF)
|
||||||
|
|
||||||
|
pre_title = TextMobject("Terminology")
|
||||||
|
pre_title.replace(title, dim_to_match=1)
|
||||||
|
|
||||||
|
self.play(FadeInFromDown(pre_title))
|
||||||
|
self.wait()
|
||||||
|
title[0].set_color(BLUE)
|
||||||
|
underline.set_color(BLUE)
|
||||||
|
self.play(
|
||||||
|
ReplacementTransform(pre_title[0], title[1]),
|
||||||
|
FadeInFrom(title[0], RIGHT),
|
||||||
|
GrowFromCenter(underline)
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
title[0].set_color, WHITE,
|
||||||
|
underline.set_color, WHITE,
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
title.add(underline)
|
title.add(underline)
|
||||||
self.add(title)
|
self.add(title)
|
||||||
|
|
||||||
|
@ -1796,6 +1954,63 @@ class IntroduceResidueClassTerminology(Scene):
|
||||||
self.wait()
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleLongDivision(MovingCameraScene):
|
||||||
|
CONFIG = {
|
||||||
|
"camera_config": {
|
||||||
|
"background_color": DARKER_GREY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def construct(self):
|
||||||
|
divisor = Integer(6)
|
||||||
|
num = Integer(20)
|
||||||
|
quotient = Integer(num.get_value() // divisor.get_value())
|
||||||
|
to_subtract = Integer(-1 * quotient.get_value() * divisor.get_value())
|
||||||
|
remainder = Integer(num.get_value() + to_subtract.get_value())
|
||||||
|
|
||||||
|
div_sym = VMobject()
|
||||||
|
div_sym.set_points_as_corners([0.2 * UP, UP, UP + 3 * RIGHT])
|
||||||
|
|
||||||
|
divisor.next_to(div_sym, LEFT, MED_SMALL_BUFF)
|
||||||
|
num.next_to(divisor, RIGHT, MED_LARGE_BUFF)
|
||||||
|
to_subtract.next_to(num, DOWN, buff=MED_LARGE_BUFF, aligned_edge=RIGHT)
|
||||||
|
h_line = Line(LEFT, RIGHT)
|
||||||
|
h_line.next_to(to_subtract, DOWN, buff=MED_SMALL_BUFF)
|
||||||
|
remainder.next_to(to_subtract, DOWN, buff=MED_LARGE_BUFF, aligned_edge=RIGHT)
|
||||||
|
quotient.next_to(num, UP, buff=MED_LARGE_BUFF, aligned_edge=RIGHT)
|
||||||
|
|
||||||
|
remainder_rect = SurroundingRectangle(remainder)
|
||||||
|
remainder_rect.set_color(RED)
|
||||||
|
|
||||||
|
frame = self.camera_frame
|
||||||
|
frame.scale(0.7, about_point=ORIGIN)
|
||||||
|
|
||||||
|
divisor.set_color(YELLOW)
|
||||||
|
num.set_color(RED)
|
||||||
|
|
||||||
|
self.add(divisor)
|
||||||
|
self.add(div_sym)
|
||||||
|
self.add(num)
|
||||||
|
self.play(FadeInFromDown(quotient))
|
||||||
|
self.play(
|
||||||
|
TransformFromCopy(divisor, to_subtract.copy()),
|
||||||
|
TransformFromCopy(quotient, to_subtract),
|
||||||
|
)
|
||||||
|
self.play(ShowCreation(h_line))
|
||||||
|
self.play(Write(remainder))
|
||||||
|
self.play(ShowCreation(remainder_rect))
|
||||||
|
self.wait()
|
||||||
|
self.play(FadeOut(remainder_rect))
|
||||||
|
|
||||||
|
|
||||||
|
class ZoomOutWords(Scene):
|
||||||
|
def construct(self):
|
||||||
|
words = TextMobject("Zoom out!")
|
||||||
|
words.scale(3)
|
||||||
|
self.play(FadeInFromLarge(words))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
class Explain44Spirals(ExplainSixSpirals):
|
class Explain44Spirals(ExplainSixSpirals):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"max_N": 3000,
|
"max_N": 3000,
|
||||||
|
@ -2305,6 +2520,247 @@ class EliminateNonPrimativeResidueClassesOf44(Label44Spirals):
|
||||||
self.wait()
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class IntroduceTotientJargon(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
self.add_title()
|
||||||
|
self.eliminate_non_coprimes()
|
||||||
|
|
||||||
|
def add_title(self):
|
||||||
|
self.teacher_says(
|
||||||
|
"More jargon!",
|
||||||
|
target_mode="hooray",
|
||||||
|
)
|
||||||
|
self.change_all_student_modes("erm")
|
||||||
|
words = self.teacher.bubble.content
|
||||||
|
|
||||||
|
words.generate_target()
|
||||||
|
words.target.scale(1.5)
|
||||||
|
words.target.center().to_edge(UP, buff=MED_SMALL_BUFF)
|
||||||
|
words.target.set_color(BLUE)
|
||||||
|
underline = Line(LEFT, RIGHT)
|
||||||
|
underline.match_width(words.target)
|
||||||
|
underline.next_to(words.target, DOWN, SMALL_BUFF)
|
||||||
|
underline.scale(1.2)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
MoveToTarget(words),
|
||||||
|
FadeOut(self.teacher.bubble),
|
||||||
|
LaggedStart(*[
|
||||||
|
FadeOutAndShift(pi, 4 * DOWN)
|
||||||
|
for pi in self.pi_creatures
|
||||||
|
]),
|
||||||
|
ShowCreation(underline)
|
||||||
|
)
|
||||||
|
|
||||||
|
def eliminate_non_coprimes(self):
|
||||||
|
number_grid = VGroup(*[
|
||||||
|
VGroup(*[
|
||||||
|
Integer(n) for n in range(11 * k, 11 * (k + 1))
|
||||||
|
]).arrange(DOWN)
|
||||||
|
for k in range(4)
|
||||||
|
]).arrange(RIGHT, buff=1)
|
||||||
|
numbers = VGroup(*it.chain(*number_grid))
|
||||||
|
numbers.set_height(6)
|
||||||
|
numbers.move_to(4 * LEFT)
|
||||||
|
numbers.to_edge(DOWN)
|
||||||
|
|
||||||
|
evens = VGroup(*filter(
|
||||||
|
lambda nm: nm.get_value() % 2 == 0,
|
||||||
|
numbers
|
||||||
|
))
|
||||||
|
div11 = VGroup(*filter(
|
||||||
|
lambda nm: nm.get_value() % 11 == 0,
|
||||||
|
numbers
|
||||||
|
))
|
||||||
|
coprimes = VGroup(*filter(
|
||||||
|
lambda nm: nm not in evens and nm not in div11,
|
||||||
|
numbers
|
||||||
|
))
|
||||||
|
|
||||||
|
words = TextMobject(
|
||||||
|
"Which ones ", "don't\\\\",
|
||||||
|
"share any factors\\\\",
|
||||||
|
"with ", "44",
|
||||||
|
alignment=""
|
||||||
|
)
|
||||||
|
words.scale(1.5)
|
||||||
|
words.next_to(ORIGIN, RIGHT)
|
||||||
|
|
||||||
|
ff = words.get_part_by_tex("44")
|
||||||
|
ff.set_color(YELLOW)
|
||||||
|
ff.generate_target()
|
||||||
|
|
||||||
|
# Show coprimes
|
||||||
|
self.play(
|
||||||
|
ShowIncreasingSubsets(numbers, run_time=3),
|
||||||
|
FadeInFrom(words, LEFT)
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
for group in evens, div11:
|
||||||
|
rects = VGroup(*[
|
||||||
|
SurroundingRectangle(number, color=RED)
|
||||||
|
for number in group
|
||||||
|
])
|
||||||
|
self.play(LaggedStartMap(ShowCreation, rects, run_time=1))
|
||||||
|
self.play(
|
||||||
|
LaggedStart(*[
|
||||||
|
ApplyMethod(number.set_opacity, 0.2)
|
||||||
|
for number in group
|
||||||
|
]),
|
||||||
|
LaggedStartMap(FadeOut, rects),
|
||||||
|
run_time=1
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
# Rearrange words
|
||||||
|
dsf = words[1:3]
|
||||||
|
dsf.generate_target()
|
||||||
|
dsf.target.arrange(RIGHT)
|
||||||
|
dsf.target[0].align_to(dsf.target[1][0], DOWN)
|
||||||
|
|
||||||
|
example = numbers[35].copy()
|
||||||
|
example.generate_target()
|
||||||
|
example.target.match_height(ff)
|
||||||
|
num_pair = VGroup(
|
||||||
|
ff.target,
|
||||||
|
TextMobject("and").scale(1.5),
|
||||||
|
example.target,
|
||||||
|
)
|
||||||
|
num_pair.arrange(RIGHT)
|
||||||
|
num_pair.move_to(words.get_top(), DOWN)
|
||||||
|
dsf.target.next_to(num_pair, DOWN, MED_LARGE_BUFF)
|
||||||
|
|
||||||
|
phrase1 = TextMobject("are ", "``relatively prime''")
|
||||||
|
phrase2 = TextMobject("are ", "``coprime''")
|
||||||
|
for phrase in phrase1, phrase2:
|
||||||
|
phrase.scale(1.5)
|
||||||
|
phrase.move_to(dsf.target)
|
||||||
|
phrase[1].set_color(BLUE)
|
||||||
|
phrase.arrow = TexMobject("\\Updownarrow")
|
||||||
|
phrase.arrow.scale(1.5)
|
||||||
|
phrase.arrow.next_to(phrase, DOWN, 2 * SMALL_BUFF)
|
||||||
|
phrase.rect = SurroundingRectangle(phrase[1])
|
||||||
|
phrase.rect.set_stroke(BLUE)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FadeOut(words[0]),
|
||||||
|
FadeOut(words[3]),
|
||||||
|
MoveToTarget(dsf),
|
||||||
|
MoveToTarget(ff),
|
||||||
|
GrowFromCenter(num_pair[1]),
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
MoveToTarget(example, path_arc=30 * DEGREES),
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
self.play(
|
||||||
|
dsf.next_to, phrase1.arrow, DOWN, SMALL_BUFF,
|
||||||
|
GrowFromEdge(phrase1.arrow, UP),
|
||||||
|
GrowFromCenter(phrase1),
|
||||||
|
ShowCreation(phrase1.rect)
|
||||||
|
)
|
||||||
|
self.play(FadeOut(phrase1.rect))
|
||||||
|
self.wait()
|
||||||
|
self.play(
|
||||||
|
VGroup(dsf, phrase1, phrase1.arrow).next_to,
|
||||||
|
phrase2.arrow, DOWN, SMALL_BUFF,
|
||||||
|
GrowFromEdge(phrase2.arrow, UP),
|
||||||
|
GrowFromCenter(phrase2),
|
||||||
|
ShowCreation(phrase2.rect)
|
||||||
|
)
|
||||||
|
self.play(FadeOut(phrase2.rect))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
# Count through coprimes
|
||||||
|
coprime_rects = VGroup(*map(SurroundingRectangle, coprimes))
|
||||||
|
coprime_rects.set_stroke(BLUE, 2)
|
||||||
|
example_anim = UpdateFromFunc(
|
||||||
|
example, lambda m: m.set_value(coprimes[len(coprime_rects) - 1].get_value())
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
ShowIncreasingSubsets(coprime_rects, int_func=np.ceil),
|
||||||
|
example_anim,
|
||||||
|
run_time=3,
|
||||||
|
rate_func=linear,
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
# Show totient function
|
||||||
|
words_to_keep = VGroup(ff, num_pair[1], example, phrase2)
|
||||||
|
to_fade = VGroup(phrase2.arrow, phrase1, phrase1.arrow, dsf)
|
||||||
|
|
||||||
|
totient = TexMobject("\\phi", "(", "44", ")", "=", "20")
|
||||||
|
totient.set_color_by_tex("44", YELLOW)
|
||||||
|
totient.scale(1.5)
|
||||||
|
totient.move_to(num_pair, UP)
|
||||||
|
phi = totient.get_part_by_tex("phi")
|
||||||
|
rhs = Integer(20)
|
||||||
|
rhs.replace(totient[-1], dim_to_match=1)
|
||||||
|
totient.submobjects[-1] = rhs
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
words_to_keep.to_edge, DOWN,
|
||||||
|
MaintainPositionRelativeTo(to_fade, words_to_keep),
|
||||||
|
VFadeOut(to_fade),
|
||||||
|
)
|
||||||
|
self.play(FadeIn(totient))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
# Label totient
|
||||||
|
brace = Brace(phi, DOWN)
|
||||||
|
etf = TextMobject("Euler's totient function")
|
||||||
|
etf.next_to(brace, DOWN)
|
||||||
|
etf.shift(RIGHT)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(brace),
|
||||||
|
FadeInFrom(etf, UP)
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
self.play(
|
||||||
|
ShowIncreasingSubsets(coprime_rects),
|
||||||
|
UpdateFromFunc(
|
||||||
|
rhs, lambda m: m.set_value(len(coprime_rects)),
|
||||||
|
),
|
||||||
|
example_anim,
|
||||||
|
rate_func=linear,
|
||||||
|
run_time=3,
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
# Show totatives
|
||||||
|
totient_group = VGroup(totient, brace, etf)
|
||||||
|
for cp, rect in zip(coprimes, coprime_rects):
|
||||||
|
cp.add(rect)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
coprimes.arrange, RIGHT, {"buff": SMALL_BUFF},
|
||||||
|
coprimes.set_width, FRAME_WIDTH - 1,
|
||||||
|
coprimes.move_to, 2 * UP,
|
||||||
|
FadeOut(evens),
|
||||||
|
FadeOut(div11[1::2]),
|
||||||
|
FadeOutAndShiftDown(words_to_keep),
|
||||||
|
totient_group.center,
|
||||||
|
totient_group.to_edge, DOWN,
|
||||||
|
)
|
||||||
|
|
||||||
|
totatives = TextMobject("``Totatives''")
|
||||||
|
totatives.scale(2)
|
||||||
|
totatives.set_color(BLUE)
|
||||||
|
totatives.move_to(ORIGIN)
|
||||||
|
arrows = VGroup(*[
|
||||||
|
Arrow(totatives.get_top(), coprime.get_bottom())
|
||||||
|
for coprime in coprimes
|
||||||
|
])
|
||||||
|
arrows.set_color(WHITE)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FadeIn(totatives),
|
||||||
|
LaggedStartMap(VFadeInThenOut, arrows, run_time=4, lag_ratio=0.05)
|
||||||
|
)
|
||||||
|
self.wait(2)
|
||||||
|
|
||||||
|
|
||||||
class TwoUnrelatedFacts(Scene):
|
class TwoUnrelatedFacts(Scene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
self.add_title()
|
self.add_title()
|
||||||
|
@ -2730,7 +3186,8 @@ class CompareTauToApprox(Scene):
|
||||||
|
|
||||||
eqs.generate_target()
|
eqs.generate_target()
|
||||||
for eq in eqs.target:
|
for eq in eqs.target:
|
||||||
eq[2][:8].set_color(GREEN)
|
eq[2][:8].set_color(RED)
|
||||||
|
eq.set_stroke(BLACK, 8, background=True)
|
||||||
|
|
||||||
self.play(LaggedStart(
|
self.play(LaggedStart(
|
||||||
FadeInFrom(eqs[0], DOWN),
|
FadeInFrom(eqs[0], DOWN),
|
||||||
|
@ -2740,6 +3197,25 @@ class CompareTauToApprox(Scene):
|
||||||
self.wait()
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class RecommendedMathologerVideo(Scene):
|
||||||
|
def construct(self):
|
||||||
|
full_rect = FullScreenFadeRectangle()
|
||||||
|
full_rect.set_fill(DARK_GREY, 1)
|
||||||
|
self.add(full_rect)
|
||||||
|
|
||||||
|
title = TextMobject("Recommended Mathologer video")
|
||||||
|
title.set_width(FRAME_WIDTH - 1)
|
||||||
|
title.to_edge(UP)
|
||||||
|
screen_rect = SurroundingRectangle(ScreenRectangle(height=5.9), buff=SMALL_BUFF)
|
||||||
|
screen_rect.next_to(title, DOWN)
|
||||||
|
screen_rect.set_fill(BLACK, 1)
|
||||||
|
screen_rect.set_stroke(WHITE, 3)
|
||||||
|
|
||||||
|
self.add(screen_rect)
|
||||||
|
self.play(Write(title))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
class ShowClassesOfPrimeRays(SpiralScene):
|
class ShowClassesOfPrimeRays(SpiralScene):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"max_N": int(1e6),
|
"max_N": int(1e6),
|
||||||
|
@ -2866,7 +3342,7 @@ class LookAtRemainderMod710(Scene):
|
||||||
"r": GREEN
|
"r": GREEN
|
||||||
}
|
}
|
||||||
equation = TexMobject(
|
equation = TexMobject(
|
||||||
"n", "=", "710", "\\cdot", "q", "+", "r",
|
"n", "=", "710", "k", "+", "r",
|
||||||
tex_to_color_map=t2c,
|
tex_to_color_map=t2c,
|
||||||
)
|
)
|
||||||
equation.scale(1.5)
|
equation.scale(1.5)
|
||||||
|
@ -2898,6 +3374,11 @@ class LookAtRemainderMod710(Scene):
|
||||||
|
|
||||||
|
|
||||||
class EliminateNonPrimative710Residues(ShowClassesOfPrimeRays):
|
class EliminateNonPrimative710Residues(ShowClassesOfPrimeRays):
|
||||||
|
CONFIG = {
|
||||||
|
"max_N": int(5e5),
|
||||||
|
"scale": 5e4,
|
||||||
|
}
|
||||||
|
|
||||||
def construct(self):
|
def construct(self):
|
||||||
self.setup_rays()
|
self.setup_rays()
|
||||||
self.eliminate_classes()
|
self.eliminate_classes()
|
||||||
|
@ -2916,7 +3397,6 @@ class EliminateNonPrimative710Residues(ShowClassesOfPrimeRays):
|
||||||
target_p_spiral_width=1,
|
target_p_spiral_width=1,
|
||||||
run_time=0,
|
run_time=0,
|
||||||
)
|
)
|
||||||
self.wait()
|
|
||||||
|
|
||||||
self.rays = rays
|
self.rays = rays
|
||||||
|
|
||||||
|
@ -2925,16 +3405,118 @@ class EliminateNonPrimative710Residues(ShowClassesOfPrimeRays):
|
||||||
rect = FullScreenFadeRectangle()
|
rect = FullScreenFadeRectangle()
|
||||||
rect.set_opacity(0)
|
rect.set_opacity(0)
|
||||||
|
|
||||||
|
for r, ray in enumerate(rays):
|
||||||
|
ray.r = r
|
||||||
|
|
||||||
mod = 710
|
mod = 710
|
||||||
mult2 = PGroup(*[rays[i] for i in range(0, mod, 2)])
|
odds = PGroup(*[rays[i] for i in range(1, mod, 2)])
|
||||||
mult5 = PGroup(*[rays[i] for i in range(0, mod, 5) if i % 2 != 0])
|
mult5 = PGroup(*[rays[i] for i in range(0, mod, 5) if i % 2 != 0])
|
||||||
mult71 = PGroup(*[rays[i] for i in range(0, mod, 71) if (i % 2 != 0 and i % 5 != 0)])
|
mult71 = PGroup(*[rays[i] for i in range(0, mod, 71) if (i % 2 != 0 and i % 5 != 0)])
|
||||||
groups = Group(mult2, mult5, mult71)
|
|
||||||
colors = [RED, BLUE, PINK]
|
colors = [RED, BLUE, PINK]
|
||||||
|
|
||||||
for group, color in zip(groups, colors):
|
pre_label, r_label = label = VGroup(
|
||||||
group.set_stroke_width(2)
|
TexMobject("710k + "),
|
||||||
self.add(rect, group)
|
Integer(100)
|
||||||
|
)
|
||||||
|
label.scale(1.5)
|
||||||
|
label.arrange(RIGHT, buff=SMALL_BUFF)
|
||||||
|
label.set_stroke(BLACK, 5, background=True, family=True)
|
||||||
|
label.next_to(ORIGIN, DOWN)
|
||||||
|
|
||||||
|
r_label.group = odds
|
||||||
|
r_label.add_updater(
|
||||||
|
lambda m: m.set_value(m.group[-1].r if len(m.group) > 0 else 1),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.remove(rays)
|
||||||
|
# Odds
|
||||||
|
odds.set_stroke_width(3)
|
||||||
|
self.add(odds, label)
|
||||||
|
self.play(
|
||||||
|
ShowIncreasingSubsets(odds, int_func=np.ceil),
|
||||||
|
run_time=10,
|
||||||
|
)
|
||||||
|
self.play(FadeOut(label))
|
||||||
|
self.remove(odds)
|
||||||
|
self.add(*odds)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
# Multiples of 5 then 71
|
||||||
|
for i, group in [(1, mult5), (2, mult71)]:
|
||||||
|
group_copy = group.copy()
|
||||||
|
group_copy.set_color(colors[i])
|
||||||
|
group_copy.set_stroke_width(4)
|
||||||
|
r_label.group = group_copy
|
||||||
|
self.add(group_copy, label)
|
||||||
|
self.play(
|
||||||
|
ShowIncreasingSubsets(group_copy, int_func=np.ceil, run_time=10),
|
||||||
|
)
|
||||||
|
self.play(FadeOut(label))
|
||||||
self.wait()
|
self.wait()
|
||||||
self.remove(rect, group)
|
self.remove(group_copy, *group)
|
||||||
self.wait()
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class Show280Computation(Scene):
|
||||||
|
def construct(self):
|
||||||
|
equation = TexMobject(
|
||||||
|
"\\phi(710) = ",
|
||||||
|
"710",
|
||||||
|
"\\left({1 \\over 2}\\right)",
|
||||||
|
"\\left({4 \\over 5}\\right)",
|
||||||
|
"\\left({70 \\over 71}\\right)",
|
||||||
|
"=",
|
||||||
|
"280",
|
||||||
|
)
|
||||||
|
equation.set_width(FRAME_WIDTH - 1)
|
||||||
|
equation.move_to(UP)
|
||||||
|
words = VGroup(
|
||||||
|
TextMobject("Filter out\\\\evens"),
|
||||||
|
TextMobject("Filter out\\\\multiples of 5"),
|
||||||
|
TextMobject("Filter out\\\\multiples of 71"),
|
||||||
|
)
|
||||||
|
vects = [DOWN, UP, DOWN]
|
||||||
|
colors = [RED, BLUE, LIGHT_PINK]
|
||||||
|
for part, word, vect, color in zip(equation[2:5], words, vects, colors):
|
||||||
|
brace = Brace(part, vect)
|
||||||
|
brace.stretch(0.8, 0)
|
||||||
|
word.brace = brace
|
||||||
|
word.next_to(brace, vect)
|
||||||
|
part.set_color(color)
|
||||||
|
word.set_color(color)
|
||||||
|
word.set_stroke(BLACK, 5, background=True)
|
||||||
|
equation.set_stroke(BLACK, 5, background=True)
|
||||||
|
|
||||||
|
rect = FullScreenFadeRectangle(fill_opacity=0.9)
|
||||||
|
self.play(
|
||||||
|
FadeIn(rect),
|
||||||
|
FadeInFromDown(equation),
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
for word in words:
|
||||||
|
self.play(
|
||||||
|
FadeIn(word),
|
||||||
|
GrowFromCenter(word.brace),
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class TeacherHoldUp(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
self.change_all_student_modes(
|
||||||
|
"pondering", look_at_arg=2 * UP,
|
||||||
|
added_anims=[
|
||||||
|
self.teacher.change, "raise_right_hand"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.wait(4)
|
||||||
|
|
||||||
|
|
||||||
|
class DiscussPrimesMod10(Scene):
|
||||||
|
def construct(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BucketPrimesByLastDigit(Scene):
|
||||||
|
def construct(self):
|
||||||
|
pass
|
||||||
|
|
Loading…
Add table
Reference in a new issue