mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
commit
169f5db9bb
32 changed files with 616 additions and 370 deletions
|
@ -47,18 +47,19 @@ class WriteOpeningWords(Scene):
|
|||
|
||||
class StartingCalc101(PiCreatureScene):
|
||||
CONFIG = {
|
||||
# "default_pi_creature_kwargs": {
|
||||
# "color": BLUE,
|
||||
# "flip_at_start": False,
|
||||
# },
|
||||
}
|
||||
|
||||
def construct(self):
|
||||
randy = self.pi_creature
|
||||
deriv_equation = TexMobject(
|
||||
"\\frac{df}{dx}(x) = \\lim(\\Delta x \\to \\infty)" +
|
||||
"{f(x + \\Delta x) - f(x) \\over \\Delta x}",
|
||||
tex_to_color_map={"\\Delta x": BLUE}
|
||||
deriv_string = "\\frac{df}{dx}(x) = \\lim(\\delta x \\to \\infty)" + \
|
||||
"{f(x + \\delta x) - f(x) \\over \\delta x}"
|
||||
equations = VGroup(
|
||||
TexMobject(*break_up_string_by_terms(deriv_string, "\\delta x"))
|
||||
)
|
||||
self.add(deriv_equation)
|
||||
equations = VGroup(deriv_equation)
|
||||
|
||||
title = TextMobject("Calculus 101")
|
||||
title.to_edge(UP)
|
||||
h_line = Line(LEFT, RIGHT)
|
||||
|
|
62
active_projects/eop/chapter1/all_sequences.py
Normal file
62
active_projects/eop/chapter1/all_sequences.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
from big_ol_pile_of_manim_imports import *
|
||||
from active_projects.eop.reusable_imports import *
|
||||
|
||||
class ShuffleThroughAllSequences(Scene):
|
||||
CONFIG = {
|
||||
"nb_coins" : 14,
|
||||
"run_time" : 5,
|
||||
"fps" : int(1.0/PRODUCTION_QUALITY_FRAME_DURATION),
|
||||
"coin_size" : 0.5,
|
||||
"coin_spacing" : 0.65
|
||||
}
|
||||
|
||||
|
||||
def construct(self):
|
||||
|
||||
nb_frames = self.run_time * self.fps
|
||||
nb_relevant_coins = int(np.log2(nb_frames)) + 1
|
||||
print "relevant coins:", nb_relevant_coins
|
||||
nb_idle_coins = self.nb_coins - nb_relevant_coins
|
||||
|
||||
idle_heads = CoinSequence(nb_idle_coins * ["H"],
|
||||
radius = self.coin_size * 0.5,
|
||||
spacing = self.coin_spacing)
|
||||
idle_tails = CoinSequence(nb_idle_coins * ["T"],
|
||||
radius = self.coin_size * 0.5,
|
||||
spacing = self.coin_spacing)
|
||||
idle_tails.fade(0.5)
|
||||
|
||||
idle_part = VGroup(idle_heads, idle_tails)
|
||||
left_idle_part = CoinSequence(6 * ["H"],
|
||||
radius = self.coin_size * 0.5,
|
||||
spacing = self.coin_spacing)
|
||||
|
||||
self.add(idle_part, left_idle_part)
|
||||
last_coin_seq = VGroup()
|
||||
|
||||
for i in range(2**nb_relevant_coins):
|
||||
binary_seq = binary(i)
|
||||
# pad to the left with 0s
|
||||
nb_leading_zeroes = nb_relevant_coins - len(binary_seq)
|
||||
for j in range(nb_leading_zeroes):
|
||||
binary_seq.insert(0, 0)
|
||||
seq2 = ["H" if x == 0 else "T" for x in binary_seq]
|
||||
coin_seq = CoinSequence(seq2,
|
||||
radius = self.coin_size * 0.5,
|
||||
spacing = self.coin_spacing)
|
||||
coin_seq.next_to(idle_part, LEFT, buff = self.coin_spacing - self.coin_size)
|
||||
left_idle_part.next_to(coin_seq, LEFT, buff = self.coin_spacing - self.coin_size)
|
||||
all_coins = VGroup(left_idle_part, coin_seq, idle_part)
|
||||
all_coins.center()
|
||||
self.remove(last_coin_seq)
|
||||
self.add(coin_seq)
|
||||
#self.wait(1.0/self.fps)
|
||||
self.update_frame()
|
||||
self.add_frames(self.get_frame())
|
||||
last_coin_seq = coin_seq
|
||||
print float(i)/2**nb_relevant_coins
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ class IllustrateAreaModelErf(GraphScene):
|
|||
|
||||
equals_sign = TexMobject("=").next_to(cdf_formula, buff = MED_LARGE_BUFF)
|
||||
|
||||
cdf_value = DecimalNumber(0, color = graph.color, num_decimal_points = 3)
|
||||
cdf_value = DecimalNumber(0, color = graph.color, num_decimal_places = 3)
|
||||
cdf_value.next_to(equals_sign)
|
||||
self.play(
|
||||
FadeIn(equals_sign),
|
||||
|
@ -99,13 +99,13 @@ class IllustrateAreaModelErf(GraphScene):
|
|||
self.add(ContinualChangingDecimal(
|
||||
decimal_number_mobject = cdf_value,
|
||||
number_update_func = integral_update_func,
|
||||
num_decimal_points = 3
|
||||
num_decimal_places = 3
|
||||
))
|
||||
|
||||
self.add(ContinualChangingDecimal(
|
||||
decimal_number_mobject = cdf_percentage,
|
||||
number_update_func = integral_update_func_percent,
|
||||
num_decimal_points = 1
|
||||
num_decimal_places = 1
|
||||
))
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ from active_projects.eop.reusable_imports import *
|
|||
class BrickRowScene(PiCreatureScene):
|
||||
|
||||
|
||||
def split_tallies(self, direction = DOWN):
|
||||
def split_tallies(self, row, direction = DOWN):
|
||||
# Split all tally symbols at once and move the copies
|
||||
# either horizontally on top of the brick row
|
||||
# or diagonally into the bricks
|
||||
|
@ -15,12 +15,12 @@ class BrickRowScene(PiCreatureScene):
|
|||
|
||||
tally_targets_left = [
|
||||
rect.get_center() + 0.25 * rect.get_width() * LEFT
|
||||
for rect in self.row.rects
|
||||
for rect in row.rects
|
||||
]
|
||||
|
||||
tally_targets_right = [
|
||||
rect.get_center() + 0.25 * rect.get_width() * RIGHT
|
||||
for rect in self.row.rects
|
||||
for rect in row.rects
|
||||
]
|
||||
|
||||
if np.all(direction == LEFT) or np.all(direction == RIGHT):
|
||||
|
@ -63,7 +63,7 @@ class BrickRowScene(PiCreatureScene):
|
|||
|
||||
|
||||
|
||||
def tally_split_animations(self, direction = DOWN):
|
||||
def tally_split_animations(self, row, direction = DOWN):
|
||||
# Just creates the animations and returns them
|
||||
# Execution can be timed afterwards
|
||||
# Returns two lists: first all those going left, then those to the right
|
||||
|
@ -73,12 +73,12 @@ class BrickRowScene(PiCreatureScene):
|
|||
|
||||
tally_targets_left = [
|
||||
rect.get_center() + 0.25 * rect.get_width() * LEFT
|
||||
for rect in self.row.rects
|
||||
for rect in row.rects
|
||||
]
|
||||
|
||||
tally_targets_right = [
|
||||
rect.get_center() + 0.25 * rect.get_width() * RIGHT
|
||||
for rect in self.row.rects
|
||||
for rect in row.rects
|
||||
]
|
||||
|
||||
if np.all(direction == LEFT) or np.all(direction == RIGHT):
|
||||
|
@ -122,13 +122,14 @@ class BrickRowScene(PiCreatureScene):
|
|||
return anims1, anims2
|
||||
|
||||
|
||||
def split_tallies_at_once(self, direction = DOWN):
|
||||
anims1, anims2 = self.tally_split_animations(direction = direction)
|
||||
|
||||
def split_tallies_at_once(self, row, direction = DOWN):
|
||||
anims1, anims2 = self.tally_split_animations(row, direction = direction)
|
||||
self.play(*(anims1 + anims2))
|
||||
|
||||
def split_tallies_in_two_steps(self, direction = DOWN):
|
||||
def split_tallies_in_two_steps(self, row, direction = DOWN):
|
||||
# First all those to the left, then those to the right
|
||||
anims1, anims2 = self.tally_split_animations(direction = direction)
|
||||
anims1, anims2 = self.tally_split_animations(row, direction = direction)
|
||||
self.play(*anims1)
|
||||
self.wait(0.3)
|
||||
self.play(*anims2)
|
||||
|
@ -136,31 +137,31 @@ class BrickRowScene(PiCreatureScene):
|
|||
|
||||
|
||||
|
||||
def merge_rects_by_subdiv(self):
|
||||
def merge_rects_by_subdiv(self, row):
|
||||
|
||||
half_merged_row = self.row.copy()
|
||||
half_merged_row = row.copy()
|
||||
half_merged_row.subdiv_level += 1
|
||||
half_merged_row.generate_points()
|
||||
half_merged_row.move_to(self.row)
|
||||
half_merged_row.move_to(row)
|
||||
|
||||
self.play(FadeIn(half_merged_row))
|
||||
self.remove(self.row)
|
||||
self.row = half_merged_row
|
||||
self.remove(row)
|
||||
return half_merged_row
|
||||
|
||||
|
||||
|
||||
|
||||
def merge_tallies(self, target_pos = UP):
|
||||
def merge_tallies(self, row, target_pos = UP):
|
||||
|
||||
r = self.row.subdiv_level
|
||||
r = row.subdiv_level
|
||||
|
||||
if np.all(target_pos == DOWN):
|
||||
tally_targets = [
|
||||
rect.get_center()
|
||||
for rect in self.row.get_rects_for_level(r)
|
||||
for rect in row.get_rects_for_level(r)
|
||||
]
|
||||
elif np.all(target_pos == UP):
|
||||
y_pos = self.row.get_center()[1] + 1.2 * 0.5 * self.row.get_height()
|
||||
y_pos = row.get_center()[1] + 1.2 * 0.5 * row.get_height()
|
||||
for target in tally_targets:
|
||||
target[1] = y_pos
|
||||
else:
|
||||
|
@ -186,25 +187,25 @@ class BrickRowScene(PiCreatureScene):
|
|||
self.tallies.add(self.tallies_copy[-1])
|
||||
|
||||
|
||||
def merge_rects_by_coloring(self):
|
||||
def merge_rects_by_coloring(self, row):
|
||||
|
||||
merged_row = self.row.copy()
|
||||
merged_row = row.copy()
|
||||
merged_row.coloring_level += 1
|
||||
merged_row.generate_points()
|
||||
merged_row.move_to(self.row)
|
||||
merged_row.move_to(row)
|
||||
|
||||
self.play(FadeIn(merged_row))
|
||||
self.remove(self.row)
|
||||
self.row = merged_row
|
||||
self.remove(row)
|
||||
return merged_row
|
||||
|
||||
|
||||
|
||||
def move_tallies_on_top(self):
|
||||
def move_tallies_on_top(self, row):
|
||||
self.play(
|
||||
self.tallies.shift, 1.2 * 0.5 * self.row.height * UP
|
||||
self.tallies.shift, 1.2 * 0.5 * row.height * UP
|
||||
)
|
||||
for tally in self.tallies:
|
||||
tally.anchor += 1.2 * 0.5 * self.row.height * UP
|
||||
tally.anchor += 1.2 * 0.5 * row.height * UP
|
||||
|
||||
def create_pi_creature(self):
|
||||
randy = CoinFlippingPiCreature(color = MAROON_E)
|
||||
|
@ -256,12 +257,11 @@ class BrickRowScene(PiCreatureScene):
|
|||
# # # # # # # #
|
||||
|
||||
|
||||
|
||||
self.play(FlipCoin(randy))
|
||||
|
||||
self.play(SplitRectsInBrickWall(self.row))
|
||||
self.merge_rects_by_subdiv()
|
||||
self.merge_rects_by_coloring()
|
||||
self.row = self.merge_rects_by_subdiv(self.row)
|
||||
self.row = self.merge_rects_by_coloring(self.row)
|
||||
#
|
||||
# put tallies on top
|
||||
|
||||
|
@ -312,7 +312,6 @@ class BrickRowScene(PiCreatureScene):
|
|||
new_tails[i].shift(COIN_SEQUENCE_SPACING * DOWN)
|
||||
self.play(FadeIn(new_tails))
|
||||
|
||||
|
||||
decimal_tallies = VGroup()
|
||||
# introduce notion of tallies
|
||||
for (i, rect) in enumerate(self.row.get_rects_for_level(2)):
|
||||
|
@ -347,6 +346,7 @@ class BrickRowScene(PiCreatureScene):
|
|||
)
|
||||
self.wait()
|
||||
|
||||
|
||||
self.tallies = VGroup()
|
||||
for (i, rect) in enumerate(self.row.get_rects_for_level(2)):
|
||||
tally = TallyStack(2-i, i, show_decimals = False)
|
||||
|
@ -357,6 +357,7 @@ class BrickRowScene(PiCreatureScene):
|
|||
self.play(FadeIn(self.tallies))
|
||||
self.wait()
|
||||
|
||||
|
||||
anims = []
|
||||
for (decimal_tally, tally_stack) in zip(decimal_tallies, self.tallies):
|
||||
anims.append(ApplyFunction(
|
||||
|
@ -366,6 +367,7 @@ class BrickRowScene(PiCreatureScene):
|
|||
self.play(*anims)
|
||||
self.wait()
|
||||
|
||||
|
||||
# replace the original decimal tallies with
|
||||
# the ones that belong to the TallyStacks
|
||||
for (decimal_tally, tally_stack) in zip(decimal_tallies, self.tallies):
|
||||
|
@ -374,9 +376,9 @@ class BrickRowScene(PiCreatureScene):
|
|||
tally_stack.add(tally_stack.decimal_tally)
|
||||
|
||||
self.add_foreground_mobject(self.tallies)
|
||||
self.merge_rects_by_subdiv()
|
||||
self.row = self.merge_rects_by_subdiv(self.row)
|
||||
self.wait()
|
||||
self.merge_rects_by_coloring()
|
||||
self.row = self.merge_rects_by_coloring(self.row)
|
||||
self.wait()
|
||||
|
||||
|
||||
|
@ -494,7 +496,7 @@ class BrickRowScene(PiCreatureScene):
|
|||
)
|
||||
self.wait()
|
||||
|
||||
self.split_tallies_in_two_steps()
|
||||
self.split_tallies_in_two_steps(self.row)
|
||||
self.wait()
|
||||
|
||||
self.add_foreground_mobject(self.tallies)
|
||||
|
@ -554,7 +556,7 @@ class BrickRowScene(PiCreatureScene):
|
|||
|
||||
# self.wait()
|
||||
|
||||
# self.merge_rects_by_subdiv()
|
||||
# self.row = self.merge_rects_by_subdiv(self.row)
|
||||
# self.wait()
|
||||
|
||||
# self.play(
|
||||
|
@ -575,9 +577,9 @@ class BrickRowScene(PiCreatureScene):
|
|||
|
||||
# self.wait()
|
||||
|
||||
# self.merge_tallies(target_pos = DOWN)
|
||||
# self.merge_tallies(self.row, target_pos = DOWN)
|
||||
# self.add_foreground_mobject(self.tallies)
|
||||
# self.merge_rects_by_coloring()
|
||||
# self.row = self.merge_rects_by_coloring(self.row)
|
||||
# self.wait()
|
||||
|
||||
|
||||
|
@ -645,7 +647,7 @@ class BrickRowScene(PiCreatureScene):
|
|||
|
||||
self.wait()
|
||||
|
||||
self.merge_rects_by_subdiv()
|
||||
self.row = self.merge_rects_by_subdiv(self.row)
|
||||
self.wait()
|
||||
|
||||
self.play(
|
||||
|
@ -666,9 +668,9 @@ class BrickRowScene(PiCreatureScene):
|
|||
|
||||
self.wait()
|
||||
|
||||
self.merge_tallies(target_pos = DOWN)
|
||||
self.merge_tallies(self.row, target_pos = DOWN)
|
||||
self.add_foreground_mobject(self.tallies)
|
||||
self.merge_rects_by_coloring()
|
||||
self.row = self.merge_rects_by_coloring(self.row)
|
||||
self.wait()
|
||||
|
||||
|
||||
|
@ -677,11 +679,18 @@ class BrickRowScene(PiCreatureScene):
|
|||
with_labels = True,
|
||||
inset = True)
|
||||
self.play(FadeOut(self.tallies))
|
||||
self.play(LaggedStart(
|
||||
FadeIn, outcomes))
|
||||
self.wait()
|
||||
self.play(LaggedStart(
|
||||
FadeOut, outcomes))
|
||||
FadeIn, outcomes,
|
||||
#rate_func = there_and_back_with_pause,
|
||||
run_time = 5))
|
||||
self.wait()
|
||||
self.play(LaggedStart(
|
||||
FadeOut, outcomes,
|
||||
#rate_func = there_and_back_with_pause,
|
||||
run_time = 5))
|
||||
|
||||
self.wait()
|
||||
self.play(FadeIn(self.tallies))
|
||||
|
||||
brace1 = Brace(self.row.rects[2], UP)
|
||||
|
@ -705,48 +714,54 @@ class BrickRowScene(PiCreatureScene):
|
|||
)
|
||||
self.wait()
|
||||
|
||||
|
||||
|
||||
# put visuals for other probability distribtuions here
|
||||
|
||||
# back to three coin flips, show all 8 outcomes
|
||||
run_time = 5
|
||||
self.play(
|
||||
LaggedStart(FadeIn, outcomes,
|
||||
#rate_func = there_and_back_with_pause,
|
||||
run_time = run_time),
|
||||
FadeOut(self.tallies,
|
||||
run_time = run_time)
|
||||
)
|
||||
self.wait()
|
||||
self.play(
|
||||
LaggedStart(FadeOut, outcomes,
|
||||
#rate_func = there_and_back_with_pause,
|
||||
run_time = 5),
|
||||
FadeIn(self.tallies,
|
||||
run_time = run_time)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
# # # # # # # #
|
||||
# FOURTH FLIP #
|
||||
# # # # # # # #
|
||||
|
||||
|
||||
|
||||
# removing the tallies (boy are they sticky)
|
||||
self.play(FadeOut(self.tallies))
|
||||
self.remove(self.tallies, self.tallies_copy)
|
||||
for tally in self.tallies:
|
||||
self.remove_foreground_mobject(tally)
|
||||
self.remove(tally)
|
||||
for tally in self.tallies_copy:
|
||||
self.remove_foreground_mobject(tally)
|
||||
self.remove(tally)
|
||||
|
||||
|
||||
previous_row = self.row.copy()
|
||||
self.add(previous_row)
|
||||
|
||||
v = 1.25 * self.row.height * UP
|
||||
self.play(
|
||||
previous_row.shift, v,
|
||||
#self.decimals.shift, v,
|
||||
#self.decimal_copies.shift, v
|
||||
)
|
||||
|
||||
self.add(self.row)
|
||||
self.bring_to_back(self.row)
|
||||
self.row.shift(v)
|
||||
|
||||
w = 1.5 * self.row.height * DOWN
|
||||
self.play(
|
||||
self.row.shift, w,
|
||||
Animation(previous_row)
|
||||
self.tallies.shift, v,
|
||||
)
|
||||
self.add_foreground_mobject(self.tallies)
|
||||
|
||||
self.play(
|
||||
SplitRectsInBrickWall(self.row)
|
||||
)
|
||||
self.wait()
|
||||
|
||||
self.merge_rects_by_subdiv()
|
||||
self.row = self.merge_rects_by_subdiv(self.row)
|
||||
|
||||
self.wait()
|
||||
|
||||
|
@ -754,7 +769,10 @@ class BrickRowScene(PiCreatureScene):
|
|||
k = 1 # tally to split
|
||||
|
||||
# show individual outcomes
|
||||
outcomes = previous_row.get_outcome_rects_for_level(n, with_labels = False)
|
||||
outcomes = previous_row.get_outcome_rects_for_level(n,
|
||||
with_labels = False,
|
||||
inset = True
|
||||
)
|
||||
grouped_outcomes = VGroup()
|
||||
index = 0
|
||||
for i in range(n + 1):
|
||||
|
@ -779,7 +797,10 @@ class BrickRowScene(PiCreatureScene):
|
|||
|
||||
#self.revert_to_original_skipping_status()
|
||||
|
||||
target_outcomes = self.row.get_outcome_rects_for_level(n + 1, with_labels = False)
|
||||
target_outcomes = self.row.get_outcome_rects_for_level(n + 1,
|
||||
with_labels = False,
|
||||
inset = True
|
||||
)
|
||||
grouped_target_outcomes = VGroup()
|
||||
index = 0
|
||||
old_tally_sizes = [choose(n,i) for i in range(n + 1)]
|
||||
|
@ -813,6 +834,13 @@ class BrickRowScene(PiCreatureScene):
|
|||
|
||||
self.wait()
|
||||
|
||||
# fade in new tallies
|
||||
new_rects = self.row.get_rects_for_level(4)
|
||||
new_tallies = VGroup(*[
|
||||
TallyStack(n + 1 - i, i).move_to(rect) for (i, rect) in enumerate(new_rects)
|
||||
])
|
||||
self.play(FadeIn(new_tallies))
|
||||
self.add_foreground_mobject(new_tallies[1])
|
||||
# remove outcomes and sizes except for one tally
|
||||
anims = []
|
||||
for i in range(n + 1):
|
||||
|
@ -820,6 +848,11 @@ class BrickRowScene(PiCreatureScene):
|
|||
anims.append(FadeOut(grouped_outcomes_copy[i]))
|
||||
if i != k:
|
||||
anims.append(FadeOut(grouped_outcomes[i]))
|
||||
anims.append(FadeOut(new_tallies[i]))
|
||||
|
||||
#anims.append(FadeOut(self.tallies[0]))
|
||||
#anims.append(FadeOut(self.tallies[2:]))
|
||||
anims.append(FadeOut(new_tallies[-1]))
|
||||
|
||||
self.play(*anims)
|
||||
|
||||
|
@ -828,64 +861,69 @@ class BrickRowScene(PiCreatureScene):
|
|||
self.play(
|
||||
Transform(grouped_outcomes_copy[k - 1], original_grouped_outcomes[k - 1])
|
||||
)
|
||||
|
||||
self.play(
|
||||
Transform(grouped_outcomes[k], original_grouped_outcomes[k])
|
||||
)
|
||||
|
||||
|
||||
new_rects = self.row.get_rects_for_level(n + 1)
|
||||
|
||||
#decimals_copy = self.decimals.copy()
|
||||
#decimals_copy2 = self.decimals.copy()
|
||||
|
||||
self.play(
|
||||
Transform(grouped_outcomes[k][0],grouped_target_outcomes[k][0][old_tally_sizes[k - 1]:]),
|
||||
Transform(grouped_outcomes_copy[k - 1][0],grouped_target_outcomes[k][0][:old_tally_sizes[k]]),
|
||||
#decimals_copy[k - 1].move_to, new_rects[k],
|
||||
#decimals_copy2[k].move_to, new_rects[k],
|
||||
Transform(grouped_outcomes_copy[k - 1][0],grouped_target_outcomes[k][0][:old_tally_sizes[k - 1]]),
|
||||
)
|
||||
|
||||
self.play(
|
||||
FadeOut(previous_row),
|
||||
FadeOut(self.tallies),
|
||||
)
|
||||
|
||||
self.row = self.merge_rects_by_coloring(self.row)
|
||||
|
||||
self.play(
|
||||
FadeIn(new_tallies[0]),
|
||||
FadeIn(new_tallies[2:]),
|
||||
)
|
||||
|
||||
|
||||
# # # # # # # #
|
||||
# FIFTH FLIP #
|
||||
# # # # # # # #
|
||||
|
||||
# self.remove(
|
||||
# grouped_outcomes,
|
||||
# grouped_outcomes_copy,
|
||||
# grouped_target_outcomes,
|
||||
# target_outcomes,
|
||||
# outcomes,
|
||||
# previous_row,
|
||||
# original_grouped_outcomes)
|
||||
|
||||
# # # # # # # # # #
|
||||
# EVEN MORE FLIPS #
|
||||
# # # # # # # # # #
|
||||
|
||||
self.play(FadeOut(new_tallies))
|
||||
self.clear()
|
||||
self.add(randy, self.row)
|
||||
#self.row.shift(0.5 * UP)
|
||||
self.add(randy, self.row)
|
||||
|
||||
#return
|
||||
|
||||
self.merge_rects_by_coloring()
|
||||
|
||||
self.revert_to_original_skipping_status()
|
||||
|
||||
for i in range(1):
|
||||
for i in range(3):
|
||||
|
||||
self.play(FlipCoin(randy))
|
||||
|
||||
self.wait()
|
||||
|
||||
previous_row = self.row.copy()
|
||||
|
||||
self.play(previous_row.shift, 1.25 * self.row.height * UP)
|
||||
|
||||
self.play(
|
||||
SplitRectsInBrickWall(self.row)
|
||||
)
|
||||
self.wait()
|
||||
|
||||
|
||||
#self.split_tallies_at_once(direction = LEFT)
|
||||
self.row = self.merge_rects_by_subdiv(self.row)
|
||||
self.wait()
|
||||
self.merge_rects_by_subdiv()
|
||||
self.wait()
|
||||
#self.merge_tallies(direction = LEFT)
|
||||
self.merge_rects_by_coloring()
|
||||
#self.merge_decimals()
|
||||
self.row = self.merge_rects_by_coloring(self.row)
|
||||
self.wait()
|
||||
|
||||
self.play(FadeOut(previous_row))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,29 +1,31 @@
|
|||
|
||||
from big_ol_pile_of_manim_imports import *
|
||||
from active_projects.eop.reusable_imports import *
|
||||
from active_projects.eop.chapter1.brick_row_scene import BrickRowScene
|
||||
|
||||
|
||||
class EntireBrickWall(Scene):
|
||||
class EntireBrickWall(BrickRowScene):
|
||||
|
||||
def construct(self):
|
||||
|
||||
self.remove(self.get_primary_pi_creature())
|
||||
|
||||
row_height = 0.3
|
||||
nb_rows = 20
|
||||
start_point = 3 * UP + 1 * LEFT
|
||||
|
||||
rows = VMobject()
|
||||
rows.add(BrickRow(0, height = row_height))
|
||||
rows[0].move_to(start_point)
|
||||
rows.move_to(start_point)
|
||||
self.add(rows)
|
||||
|
||||
|
||||
zero_counter = Integer(0).next_to(start_point + 0.5 * rows[0].width * RIGHT)
|
||||
nb_flips_text = TextMobject("\# of flips")
|
||||
nb_flips_text.next_to(zero_counter, RIGHT, buff = LARGE_BUFF)
|
||||
self.add(zero_counter, nb_flips_text)
|
||||
flip_counters = VGroup(zero_counter)
|
||||
|
||||
for i in range(1,nb_rows + 1):
|
||||
rows.add(BrickRow(i, height = row_height))
|
||||
rows[-1].move_to(start_point + (i - 1) * row_height * DOWN)
|
||||
for i in range(1, nb_rows + 1):
|
||||
rows.add(rows[-1].copy())
|
||||
self.bring_to_back(rows[-1])
|
||||
anims = [
|
||||
rows[-1].shift, row_height * DOWN,
|
||||
|
@ -33,10 +35,17 @@ class EntireBrickWall(Scene):
|
|||
if i % 5 == 0:
|
||||
counter = Integer(i)
|
||||
counter.next_to(rows[-1].get_right() + row_height * DOWN, RIGHT)
|
||||
flip_counters.add(counter)
|
||||
anims.append(FadeIn(counter))
|
||||
|
||||
self.play(*anims)
|
||||
|
||||
self.play(SplitRectsInBrickWall(rows[-1]))
|
||||
rows.submobjects[-1] = self.merge_rects_by_subdiv(rows[-1])
|
||||
rows.submobjects[-1] = self.merge_rects_by_coloring(rows[-1])
|
||||
|
||||
|
||||
|
||||
# draw indices under the last row for the number of tails
|
||||
tails_counters = VGroup()
|
||||
for (i, rect) in enumerate(rows[-1].rects):
|
||||
|
@ -62,10 +71,73 @@ class EntireBrickWall(Scene):
|
|||
FadeIn(nb_tails_text)
|
||||
)
|
||||
|
||||
special_brick_copy = rows[-1].rects[13].copy()
|
||||
# remove any hidden brick rows
|
||||
self.clear()
|
||||
self.add(nb_flips_text)
|
||||
|
||||
mobs_to_shift = VGroup(
|
||||
rows, flip_counters, tails_counters, nb_tails_text,
|
||||
)
|
||||
self.play(mobs_to_shift.shift, 3 * UP)
|
||||
|
||||
last_row_rect = SurroundingRectangle(rows[-1], buff = 0)
|
||||
last_row_rect.set_stroke(color = YELLOW, width = 6)
|
||||
|
||||
self.play(
|
||||
rows.fade, 0.9,
|
||||
FadeIn(special_brick_copy)
|
||||
ShowCreation(last_row_rect)
|
||||
)
|
||||
|
||||
def highlighted_brick(row = 20, nb_tails = 10):
|
||||
brick_copy = rows[row].rects[nb_tails].copy()
|
||||
brick_copy.set_fill(color = YELLOW, opacity = 0.8)
|
||||
prob_percentage = float(choose(row, nb_tails)) / 2**row * 100
|
||||
brick_label = DecimalNumber(prob_percentage,
|
||||
unit = "\%", num_decimal_places = 1, color = BLACK)
|
||||
brick_label.move_to(brick_copy)
|
||||
brick_label.scale_to_fit_height(0.8 * brick_copy.get_height())
|
||||
return VGroup(brick_copy, brick_label)
|
||||
|
||||
highlighted_bricks = [
|
||||
highlighted_brick(row = 20, nb_tails = i)
|
||||
for i in range(20)
|
||||
]
|
||||
|
||||
self.play(
|
||||
FadeIn(highlighted_bricks[10])
|
||||
)
|
||||
|
||||
self.play(
|
||||
FadeOut(highlighted_bricks[10]),
|
||||
FadeIn(highlighted_bricks[9]),
|
||||
FadeIn(highlighted_bricks[11]),
|
||||
)
|
||||
|
||||
self.play(
|
||||
FadeOut(highlighted_bricks[9]),
|
||||
FadeOut(highlighted_bricks[11]),
|
||||
FadeIn(highlighted_bricks[8]),
|
||||
FadeIn(highlighted_bricks[12]),
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ class GenericMorphBrickRowIntoHistogram(Scene):
|
|||
"bar_width" : 2.0,
|
||||
"bar_anchor_height" : -3.0,
|
||||
"show_tallies" : False,
|
||||
"show_nb_flips" : True
|
||||
}
|
||||
|
||||
def construct(self):
|
||||
|
@ -25,13 +26,23 @@ class GenericMorphBrickRowIntoHistogram(Scene):
|
|||
|
||||
for (i,brick) in enumerate(self.row.rects):
|
||||
tally = TallyStack(self.level - i, i)
|
||||
tally.next_to(brick, UP)
|
||||
tally.move_to(brick)
|
||||
self.add(tally)
|
||||
tallies.add(tally)
|
||||
brick.set_stroke(width = 3)
|
||||
|
||||
if self.show_nb_flips:
|
||||
nb_flips_text = TextMobject("\# of flips: " + str(self.level))
|
||||
nb_flips_text.to_corner(UR)
|
||||
self.add(nb_flips_text)
|
||||
|
||||
self.remove(self.row.subdivs, self.row.border)
|
||||
|
||||
for rect in self.row.rects:
|
||||
rect.set_stroke(color = WHITE, width = 3)
|
||||
|
||||
self.play(self.row.rects.space_out_submobjects, {"factor" : 1.3})
|
||||
|
||||
anims = []
|
||||
for brick in self.row.rects:
|
||||
anims.append(brick.rotate)
|
||||
|
@ -41,7 +52,7 @@ class GenericMorphBrickRowIntoHistogram(Scene):
|
|||
anims.append(FadeOut(tallies))
|
||||
self.play(*anims)
|
||||
|
||||
|
||||
|
||||
anims = []
|
||||
for (i,brick) in enumerate(self.row.rects):
|
||||
anims.append(brick.next_to)
|
||||
|
@ -50,11 +61,10 @@ class GenericMorphBrickRowIntoHistogram(Scene):
|
|||
self.play(*anims)
|
||||
|
||||
self.bars.create_outline()
|
||||
|
||||
anims = []
|
||||
for bar in self.bars.submobjects:
|
||||
anims.append(bar.set_stroke)
|
||||
anims.append({"width" : 0})
|
||||
anims = [
|
||||
ApplyMethod(rect.set_stroke, {"width" : 0})
|
||||
for rect in self.bars
|
||||
]
|
||||
anims.append(FadeIn(self.bars.outline))
|
||||
self.play(*anims)
|
||||
|
||||
|
@ -67,7 +77,8 @@ class MorphBrickRowIntoHistogram3(GenericMorphBrickRowIntoHistogram):
|
|||
"prob_denominator" : 8,
|
||||
"bar_width" : 2.0,
|
||||
"bar_anchor_height" : -3.0,
|
||||
"show_tallies" : True
|
||||
"show_tallies" : True,
|
||||
"show_nb_flips" : False
|
||||
}
|
||||
|
||||
def construct(self):
|
||||
|
@ -89,56 +100,72 @@ class MorphBrickRowIntoHistogram3(GenericMorphBrickRowIntoHistogram):
|
|||
|
||||
nb_tails_label = TextMobject("\# of tails")
|
||||
nb_tails_label.next_to(x_labels[-1], RIGHT, MED_LARGE_BUFF)
|
||||
|
||||
self.play(
|
||||
FadeIn(x_axis),
|
||||
FadeIn(x_labels),
|
||||
FadeIn(nb_tails_label)
|
||||
)
|
||||
|
||||
|
||||
|
||||
# draw y-guides
|
||||
|
||||
y_guides = VMobject()
|
||||
for i in range(1,self.prob_denominator + 1):
|
||||
for i in range(0,self.prob_denominator + 1):
|
||||
y_guide = Line(5 * LEFT, 5 * RIGHT, stroke_color = GRAY)
|
||||
y_guide.move_to(self.bar_anchor_height * UP + i * float(self.row.width) / self.prob_denominator * UP)
|
||||
y_guide_label = TexMobject("{" + str(i) + "\over " + str(self.prob_denominator) + "}", color = GRAY)
|
||||
y_guide_label.scale(0.7)
|
||||
y_guide_label.next_to(y_guide, LEFT)
|
||||
y_guide.add(y_guide_label)
|
||||
if i != 0:
|
||||
y_guide.add(y_guide_label)
|
||||
y_guides.add(y_guide)
|
||||
|
||||
self.bring_to_back(y_guides)
|
||||
self.play(FadeIn(y_guides), Animation(self.bars))
|
||||
|
||||
|
||||
total_area_text = TextMobject("total area = 1", color = YELLOW)
|
||||
total_area_rect = SurroundingRectangle(total_area_text,
|
||||
buff = MED_SMALL_BUFF,
|
||||
fill_opacity = 0.5,
|
||||
fill_color = BLACK,
|
||||
stroke_color = YELLOW
|
||||
self.play(
|
||||
FadeIn(y_guides),
|
||||
Animation(self.bars.outline),
|
||||
Animation(self.bars)
|
||||
)
|
||||
|
||||
self.play(
|
||||
Write(total_area_text),
|
||||
FadeIn(x_axis),
|
||||
FadeIn(x_labels),
|
||||
FadeIn(nb_tails_label)
|
||||
)
|
||||
|
||||
self.add_foreground_mobject(nb_tails_label)
|
||||
area_color = YELLOW
|
||||
|
||||
total_area_text = TextMobject("total area =", color = area_color)
|
||||
area_decimal = DecimalNumber(0, color = area_color, num_decimal_places = 3)
|
||||
area_decimal.next_to(total_area_text, RIGHT)
|
||||
|
||||
total_area_group = VGroup(total_area_text, area_decimal)
|
||||
total_area_group.move_to(2.7 * UP)
|
||||
|
||||
self.play(
|
||||
FadeIn(total_area_text),
|
||||
)
|
||||
|
||||
cumulative_areas = [0.125, 0.5, 0.875, 1]
|
||||
covering_rects = self.bars.copy()
|
||||
for (i,rect) in enumerate(covering_rects):
|
||||
rect.set_fill(color = area_color, opacity = 0.5)
|
||||
self.play(
|
||||
FadeIn(rect, rate_func = linear),
|
||||
ChangeDecimalToValue(area_decimal, cumulative_areas[i],
|
||||
rate_func = linear)
|
||||
)
|
||||
self.wait(0.2)
|
||||
|
||||
self.wait()
|
||||
|
||||
total_area_rect = SurroundingRectangle(
|
||||
total_area_group,
|
||||
buff = MED_SMALL_BUFF,
|
||||
stroke_color = area_color
|
||||
)
|
||||
|
||||
self.play(
|
||||
FadeOut(covering_rects),
|
||||
ShowCreation(total_area_rect)
|
||||
)
|
||||
|
||||
prob_dist_text = TextMobject("probability distribution", color = YELLOW)
|
||||
prob_dist_text.to_corner(UP, buff = LARGE_BUFF)
|
||||
prob_dist_rect = SurroundingRectangle(prob_dist_text,
|
||||
buff = MED_SMALL_BUFF,
|
||||
stroke_color = YELLOW
|
||||
)
|
||||
|
||||
self.play(
|
||||
Write(prob_dist_text),
|
||||
ShowCreation(prob_dist_rect)
|
||||
)
|
||||
|
||||
|
||||
|
||||
class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram):
|
||||
|
@ -165,9 +192,9 @@ class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram):
|
|||
label.next_to(self.bar_anchors[i], DOWN)
|
||||
x_labels.add(label)
|
||||
|
||||
nb_tails_label = TextMobject("\# of heads")
|
||||
nb_tails_label.next_to(x_labels[-1], RIGHT, MED_LARGE_BUFF)
|
||||
|
||||
nb_tails_label = TextMobject("\# of tails")
|
||||
nb_tails_label.move_to(5 * RIGHT + 2.5 * DOWN)
|
||||
|
||||
self.play(
|
||||
FadeIn(x_axis),
|
||||
FadeIn(x_labels),
|
||||
|
@ -186,7 +213,7 @@ class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram):
|
|||
y_guide_height = self.bar_anchor_height + i * float(self.row.width)
|
||||
y_guide_heights.append(y_guide_height)
|
||||
y_guide.move_to(y_guide_height * UP)
|
||||
y_guide_label = DecimalNumber(i, num_decimal_points = 2, color = GRAY)
|
||||
y_guide_label = DecimalNumber(i, num_decimal_places = 2, color = GRAY)
|
||||
y_guide_label.scale(0.7)
|
||||
y_guide_label.next_to(y_guide, LEFT)
|
||||
y_guide.add(y_guide_label)
|
||||
|
@ -199,7 +226,7 @@ class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram):
|
|||
histogram_height = self.bars.get_height()
|
||||
|
||||
# scale to fit screen
|
||||
self.scale_x = 10.0/(len(self.bars) * self.bar_width)
|
||||
self.scale_x = 10.0/((len(self.bars) - 1) * self.bar_width)
|
||||
self.scale_y = 6.0/histogram_height
|
||||
|
||||
|
||||
|
|
|
@ -14,15 +14,25 @@ class ProbabilityDistributions(PiCreatureScene):
|
|||
def construct(self):
|
||||
|
||||
lag_ratio = 0.2
|
||||
run_time = 5
|
||||
run_time = 3
|
||||
|
||||
|
||||
text = TextMobject("Probability distributions", color = YELLOW)
|
||||
text.to_edge(UP)
|
||||
text_rect = SurroundingRectangle(text, buff = MED_SMALL_BUFF)
|
||||
|
||||
self.play(
|
||||
FadeIn(text),
|
||||
ShowCreation(text_rect)
|
||||
)
|
||||
|
||||
|
||||
# WEATHER FORECAST
|
||||
|
||||
|
||||
unit_rect = Rectangle(
|
||||
height = 4, width = 4
|
||||
)
|
||||
height = 3, width = 3
|
||||
).shift(DOWN)
|
||||
|
||||
p_rain = 0.23
|
||||
p_sun = 1 - p_rain
|
||||
|
@ -38,7 +48,7 @@ class ProbabilityDistributions(PiCreatureScene):
|
|||
sun_rect.set_fill(color = YELLOW, opacity = opacity)
|
||||
sun_rect.set_stroke(width = 0)
|
||||
|
||||
self.add(unit_rect, rain_rect, sun_rect)
|
||||
self.play(FadeIn(VGroup(unit_rect, rain_rect, sun_rect)))
|
||||
|
||||
rain = SVGMobject(file_name = "rain").scale(0.35)
|
||||
sun = SVGMobject(file_name = "sun").scale(0.35)
|
||||
|
@ -189,7 +199,8 @@ class ProbabilityDistributions(PiCreatureScene):
|
|||
coin_flip_rect.add(braces, labels)
|
||||
|
||||
coin_flip_rect.target = coin_flip_rect.copy().scale(0.6)
|
||||
coin_flip_rect.target.to_corner(UR, buff = LARGE_BUFF)
|
||||
coin_flip_rect.target.to_corner(UR, buff = MED_LARGE_BUFF)
|
||||
coin_flip_rect.target.shift(DOWN)
|
||||
|
||||
self.play(
|
||||
MoveToTarget(coin_flip_rect)
|
||||
|
@ -255,25 +266,3 @@ class ProbabilityDistributions(PiCreatureScene):
|
|||
rate_func=there_and_back_with_pause,
|
||||
run_time=run_time
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
|
||||
|
||||
from big_ol_pile_of_manim_imports import *
|
||||
from active_projects.eop.reusable_imports import *
|
||||
from active_projects.eop.independence import *
|
||||
|
||||
from for_3b1b_videos.pi_class import PiCreatureClass
|
||||
|
||||
class QuizResult(Scene):
|
||||
|
||||
class QuizResult(PiCreatureScene):
|
||||
CONFIG = {
|
||||
"pi_creatures_start_on_screen" : False,
|
||||
"random_seed" : 6
|
||||
}
|
||||
def construct(self):
|
||||
|
||||
|
||||
|
@ -23,14 +25,15 @@ class QuizResult(Scene):
|
|||
return quiz
|
||||
|
||||
|
||||
highlight_color = YELLOW
|
||||
highlight_color = WHITE
|
||||
|
||||
nb_students_x = 5
|
||||
nb_students_y = 3
|
||||
spacing_students_x = 2.0
|
||||
spacing_students_y = 2.2
|
||||
|
||||
all_students = VGroup()
|
||||
all_students = PiCreatureClass(
|
||||
width = nb_students_x, height = nb_students_y)# VGroup()
|
||||
student_points = []
|
||||
grades = []
|
||||
grades_count = []
|
||||
|
@ -39,9 +42,10 @@ class QuizResult(Scene):
|
|||
for j in range(nb_students_y):
|
||||
x = i * spacing_students_x
|
||||
y = j * spacing_students_y
|
||||
pi = PiCreature().scale(0.3)
|
||||
pi.move_to([x,y,0])
|
||||
all_students.add(pi)
|
||||
#pi = PiCreature().scale(0.3)
|
||||
#pi.move_to([x,y,0])
|
||||
#all_students.add(pi)
|
||||
all_students[i*nb_students_y + j].move_to([x,y,0])
|
||||
q1 = np.random.choice([True, False])
|
||||
q2 = np.random.choice([True, False])
|
||||
q3 = np.random.choice([True, False])
|
||||
|
@ -55,7 +59,8 @@ class QuizResult(Scene):
|
|||
|
||||
|
||||
all_students.move_to(ORIGIN)
|
||||
self.add(all_students)
|
||||
self.pi_creatures = all_students
|
||||
self.play(FadeIn(all_students))
|
||||
|
||||
all_quizzes = VGroup()
|
||||
|
||||
|
@ -133,17 +138,20 @@ class QuizResult(Scene):
|
|||
)
|
||||
grade_hist.move_to(all_students)
|
||||
|
||||
self.play(FadeIn(grade_hist))
|
||||
self.play(
|
||||
FadeIn(grade_hist),
|
||||
FadeOut(all_students)
|
||||
)
|
||||
|
||||
|
||||
nb_students_label = TextMobject("\# of students", color = highlight_color)
|
||||
nb_students_label.move_to(3 * LEFT + 2 * UP)
|
||||
nb_students_label.move_to(5 * LEFT + 2 * UP)
|
||||
arrows = VGroup(*[
|
||||
Arrow(nb_students_label, grade_hist.bars[i].get_center(),
|
||||
Arrow(nb_students_label.get_right(), grade_hist.bars[i].get_center(),
|
||||
color = highlight_color)
|
||||
for i in range(4)
|
||||
])
|
||||
self.play(Write(nb_students_label), LaggedStart(ShowCreation,arrows))
|
||||
self.play(Write(nb_students_label), LaggedStart(GrowArrow,arrows))
|
||||
|
||||
percentage_label = TextMobject("\% of students", color = highlight_color)
|
||||
percentage_label.move_to(nb_students_label)
|
||||
|
@ -151,10 +159,11 @@ class QuizResult(Scene):
|
|||
anims = []
|
||||
for (label, percentage) in zip(grade_hist.y_labels_group, percentages):
|
||||
new_label = DecimalNumber(percentage,
|
||||
num_decimal_points = 1,
|
||||
num_decimal_places = 1,
|
||||
unit = "\%",
|
||||
color = highlight_color
|
||||
)
|
||||
new_label.scale(0.7)
|
||||
new_label.move_to(label)
|
||||
anims.append(Transform(label, new_label))
|
||||
anims.append(ReplacementTransform(nb_students_label, percentage_label))
|
||||
|
@ -174,8 +183,8 @@ class QuizResult(Scene):
|
|||
prob_label.move_to(percentage_label)
|
||||
self.play(
|
||||
all_students[8].set_color, MAROON_E,
|
||||
all_students[:8].fade, 0.6,
|
||||
all_students[9:].fade, 0.6,
|
||||
#all_students[:8].fade, 0.6,
|
||||
#all_students[9:].fade, 0.6,
|
||||
ReplacementTransform(percentage_label, prob_label)
|
||||
)
|
||||
|
||||
|
@ -184,12 +193,32 @@ class QuizResult(Scene):
|
|||
FadeOut(arrows)
|
||||
)
|
||||
|
||||
for i in range(1):
|
||||
self.play(
|
||||
FlashThroughHistogram(
|
||||
flash_hist = FlashThroughHistogram(
|
||||
grade_hist,
|
||||
direction = "vertical",
|
||||
mode = "random",
|
||||
run_time = 5
|
||||
cell_opacity = 0.5,
|
||||
run_time = 5,
|
||||
rate_func = linear
|
||||
)
|
||||
)
|
||||
|
||||
flash_class = FlashThroughClass(
|
||||
all_students,
|
||||
mode = "random",
|
||||
highlight_color = MAROON_E,
|
||||
run_time = 5,
|
||||
rate_func = linear
|
||||
)
|
||||
|
||||
for i in range(3):
|
||||
self.play(flash_hist, flash_class)
|
||||
self.remove(flash_hist.prototype_cell)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ class BrickRow(VMobject):
|
|||
"height" : 1.0,
|
||||
"width" : 8.0,
|
||||
"outcome_shrinkage_factor_x" : 0.95,
|
||||
"outcome_shrinkage_factor_y" : 0.95
|
||||
"outcome_shrinkage_factor_y" : 0.94
|
||||
}
|
||||
|
||||
def __init__(self, n, **kwargs):
|
||||
|
@ -104,12 +104,12 @@ class BrickRow(VMobject):
|
|||
outcome_width = float(self.width) / (2 ** r)
|
||||
outcome_height = self.height
|
||||
|
||||
corner_radius = 0 # min(0.1, 0.3 * min(outcome_width, outcome_height))
|
||||
corner_radius = min(0.1, 0.3 * min(outcome_width, outcome_height))
|
||||
# this scales down the corner radius for very narrow rects
|
||||
rect = Rectangle( # RoundedRectangle(
|
||||
rect = RoundedRectangle(
|
||||
width = outcome_width,
|
||||
height = outcome_height,
|
||||
#corner_radius = corner_radius,
|
||||
corner_radius = corner_radius,
|
||||
fill_color = WHITE,
|
||||
fill_opacity = 0.2,
|
||||
stroke_width = 0
|
||||
|
@ -205,13 +205,3 @@ class SplitRectsInBrickWall(AnimationGroup):
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
# def update_mobject(self, alpha):
|
||||
# for subdiv in self.subdivs:
|
||||
# x = subdiv.get_start()[0]
|
||||
# start = self.mobject.get_center()
|
||||
# start += x * RIGHT + 0.5 * self.mobject.get_height() * UP
|
||||
# end = start + alpha * self.mobject.get_height() * DOWN
|
||||
# subdiv.put_start_and_end_on(start,end)
|
||||
|
||||
|
|
|
@ -201,7 +201,10 @@ class FlashThroughHistogram(Animation):
|
|||
"hist_opacity" : 0.2
|
||||
}
|
||||
|
||||
def __init__(self, mobject, direction = "horizontal", mode = "random", **kwargs):
|
||||
def __init__(self, mobject,
|
||||
direction = "horizontal",
|
||||
mode = "random",
|
||||
**kwargs):
|
||||
|
||||
digest_config(self, kwargs)
|
||||
|
||||
|
@ -277,6 +280,15 @@ class FlashThroughHistogram(Animation):
|
|||
self.mobject.remove(self.prototype_cell)
|
||||
|
||||
|
||||
def clean_up(self, surrounding_scene = None):
|
||||
Animation.clean_up(self, surrounding_scene)
|
||||
self.update(1)
|
||||
if surrounding_scene is not None:
|
||||
if self.is_remover():
|
||||
surrounding_scene.remove(self.prototype_cell)
|
||||
else:
|
||||
surrounding_scene.add(self.prototype_cell)
|
||||
return self
|
||||
|
||||
|
||||
|
||||
|
@ -290,7 +302,7 @@ class OutlineableBars(VGroup):
|
|||
# We use this to morph a row of bricks into a histogram.
|
||||
|
||||
CONFIG = {
|
||||
"outline_stroke_width" : 5,
|
||||
"outline_stroke_width" : 3,
|
||||
"stroke_color" : WHITE
|
||||
}
|
||||
def create_outline(self, animated = False, **kwargs):
|
||||
|
|
|
@ -37,6 +37,7 @@ class UprightTails(UprightCoin):
|
|||
class CoinSequence(VGroup):
|
||||
CONFIG = {
|
||||
"sequence": [],
|
||||
"radius" : COIN_RADIUS,
|
||||
"spacing": COIN_SEQUENCE_SPACING,
|
||||
"direction": RIGHT
|
||||
}
|
||||
|
@ -47,11 +48,11 @@ class CoinSequence(VGroup):
|
|||
offset = 0
|
||||
for symbol in self.sequence:
|
||||
if symbol == "H":
|
||||
new_coin = UprightHeads()
|
||||
new_coin = UprightHeads(radius = self.radius)
|
||||
elif symbol == "T":
|
||||
new_coin = UprightTails()
|
||||
new_coin = UprightTails(radius = self.radius)
|
||||
else:
|
||||
new_coin = UprightCoin(symbol = symbol)
|
||||
new_coin = UprightCoin(symbol = symbol, radius = self.radius)
|
||||
new_coin.shift(offset * self.direction)
|
||||
self.add(new_coin)
|
||||
offset += self.spacing
|
||||
|
|
|
@ -10,7 +10,7 @@ from utils.config_ops import digest_config
|
|||
|
||||
class ChangingDecimal(Animation):
|
||||
CONFIG = {
|
||||
"num_decimal_points": None,
|
||||
"num_decimal_places": None,
|
||||
"show_ellipsis": None,
|
||||
"position_update_func": None,
|
||||
"tracked_mobject": None,
|
||||
|
@ -21,7 +21,7 @@ class ChangingDecimal(Animation):
|
|||
self.decimal_number_config = dict(
|
||||
decimal_number_mobject.initial_config
|
||||
)
|
||||
for attr in "num_decimal_points", "show_ellipsis":
|
||||
for attr in "num_decimal_places", "show_ellipsis":
|
||||
value = getattr(self, attr)
|
||||
if value is not None:
|
||||
self.decimal_number_config[attr] = value
|
||||
|
|
|
@ -151,11 +151,12 @@ def handle_scene(scene, **config):
|
|||
|
||||
if config["show_file_in_finder"]:
|
||||
commands.append("-R")
|
||||
#
|
||||
|
||||
if config["show_last_frame"]:
|
||||
commands.append(scene.get_image_file_path())
|
||||
else:
|
||||
commands.append(scene.get_movie_file_path())
|
||||
#commands.append("-g")
|
||||
FNULL = open(os.devnull, 'w')
|
||||
sp.call(commands, stdout=FNULL, stderr=sp.STDOUT)
|
||||
FNULL.close()
|
||||
|
@ -223,8 +224,11 @@ def get_module_posix(file_name):
|
|||
module_name = file_name.replace(".py", "")
|
||||
last_module = imp.load_module(".", *imp.find_module("."))
|
||||
for part in module_name.split(os.sep):
|
||||
load_args = imp.find_module(part, last_module.__path__)
|
||||
last_module = imp.load_module(part, *load_args)
|
||||
try:
|
||||
load_args = imp.find_module(part, last_module.__path__)
|
||||
last_module = imp.load_module(part, *load_args)
|
||||
except ImportError:
|
||||
continue
|
||||
return last_module
|
||||
|
||||
|
||||
|
|
23
for_3b1b_videos/pi_class.py
Normal file
23
for_3b1b_videos/pi_class.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
import numpy as np
|
||||
import warnings
|
||||
|
||||
from constants import *
|
||||
|
||||
from mobject.types.vectorized_mobject import VGroup
|
||||
from for_3b1b_videos.pi_creature import PiCreature
|
||||
|
||||
class PiCreatureClass(VGroup):
|
||||
CONFIG = {
|
||||
"width" : 3,
|
||||
"height" : 2
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
VGroup.__init__(self, **kwargs)
|
||||
for i in range(self.width):
|
||||
for j in range(self.height):
|
||||
pi = PiCreature().scale(0.3)
|
||||
pi.move_to(i*DOWN + j* RIGHT)
|
||||
self.add(pi)
|
||||
|
||||
|
|
@ -6,6 +6,7 @@ from mobject.mobject import Group
|
|||
|
||||
from mobject.svg.drawings import SpeechBubble
|
||||
|
||||
from animation.animation import Animation
|
||||
from animation.creation import ShowCreation
|
||||
from animation.creation import Write
|
||||
from animation.composition import AnimationGroup
|
||||
|
@ -16,6 +17,8 @@ from utils.config_ops import digest_config
|
|||
from utils.rate_functions import squish_rate_func
|
||||
from utils.rate_functions import there_and_back
|
||||
|
||||
from for_3b1b_videos.pi_class import PiCreatureClass
|
||||
|
||||
|
||||
class Blink(ApplyMethod):
|
||||
CONFIG = {
|
||||
|
@ -101,3 +104,46 @@ class RemovePiCreatureBubble(AnimationGroup):
|
|||
self.pi_creature.bubble = None
|
||||
if surrounding_scene is not None:
|
||||
surrounding_scene.add(self.pi_creature)
|
||||
|
||||
|
||||
|
||||
class FlashThroughClass(Animation):
|
||||
CONFIG = {
|
||||
"highlight_color" : GREEN,
|
||||
}
|
||||
|
||||
def __init__(self, mobject, mode = "linear", **kwargs):
|
||||
|
||||
if not isinstance(mobject, PiCreatureClass):
|
||||
raise Exception("FlashThroughClass mobject must be a PiCreatureClass")
|
||||
digest_config(self, kwargs)
|
||||
self.indices = range(mobject.height * mobject.width)
|
||||
|
||||
if mode == "random":
|
||||
np.random.shuffle(self.indices)
|
||||
|
||||
Animation.__init__(self, mobject, **kwargs)
|
||||
|
||||
|
||||
def update_mobject(self, alpha):
|
||||
index = int(np.floor(alpha * self.mobject.height * self.mobject.width))
|
||||
|
||||
for pi in self.mobject:
|
||||
pi.set_color(BLUE_E)
|
||||
if index < self.mobject.height * self.mobject.width:
|
||||
self.mobject[self.indices[index]].set_color(self.highlight_color)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ class Matrix(VMobject):
|
|||
class DecimalMatrix(Matrix):
|
||||
CONFIG = {
|
||||
"element_to_mobject": DecimalNumber,
|
||||
"element_to_mobject_config": {"num_decimal_points": 1}
|
||||
"element_to_mobject_config": {"num_decimal_places": 1}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -623,13 +623,17 @@ class Mobject(Container):
|
|||
values = []
|
||||
values += [
|
||||
mob.reduce_across_dimension(points_func, reduce_func, dim)
|
||||
for mob in self.submobjects
|
||||
for mob in self.nonempty_submobjects()
|
||||
]
|
||||
try:
|
||||
return reduce_func(values)
|
||||
except:
|
||||
return 0
|
||||
|
||||
def nonempty_submobjects(self):
|
||||
return [submob for submob in self.submobjects
|
||||
if len(submob.submobjects) != 0 or len(submob.points) != 0]
|
||||
|
||||
def get_merged_array(self, array_attr):
|
||||
result = None
|
||||
for mob in self.family_members_with_points():
|
||||
|
@ -745,6 +749,7 @@ class Mobject(Container):
|
|||
def submobject_family(self):
|
||||
sub_families = map(Mobject.submobject_family, self.submobjects)
|
||||
all_mobjects = [self] + list(it.chain(*sub_families))
|
||||
#all_mobjects = list(it.chain(*sub_families)) + [self]
|
||||
return remove_list_redundancies(all_mobjects)
|
||||
|
||||
def family_members_with_points(self):
|
||||
|
|
|
@ -8,7 +8,7 @@ from mobject.types.vectorized_mobject import VMobject
|
|||
|
||||
class DecimalNumber(VMobject):
|
||||
CONFIG = {
|
||||
"num_decimal_points": 2,
|
||||
"num_decimal_places": 2,
|
||||
"digit_to_digit_buff": 0.05,
|
||||
"show_ellipsis": False,
|
||||
"unit": None, # Aligned to bottom unless it starts with "^"
|
||||
|
@ -18,7 +18,7 @@ class DecimalNumber(VMobject):
|
|||
def __init__(self, number, **kwargs):
|
||||
VMobject.__init__(self, **kwargs)
|
||||
self.number = number
|
||||
ndp = self.num_decimal_points
|
||||
ndp = self.num_decimal_places
|
||||
|
||||
# Build number string
|
||||
if isinstance(number, complex):
|
||||
|
@ -71,5 +71,5 @@ class DecimalNumber(VMobject):
|
|||
|
||||
class Integer(DecimalNumber):
|
||||
CONFIG = {
|
||||
"num_decimal_points": 0,
|
||||
"num_decimal_places": 0,
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ from svg_mobject import VMobjectFromSVGPathstring
|
|||
from utils.config_ops import digest_config
|
||||
from utils.strings import split_string_list_to_isolate_substring
|
||||
from utils.tex_file_writing import tex_to_svg_file
|
||||
from mobject.geometry import Line
|
||||
from mobject.types.vectorized_mobject import VGroup
|
||||
from mobject.types.vectorized_mobject import VectorizedPoint
|
||||
|
||||
|
@ -290,3 +291,27 @@ class TexMobjectFromPresetString(TexMobject):
|
|||
TexMobject.__init__(self, self.tex, **kwargs)
|
||||
self.set_color(self.color)
|
||||
|
||||
|
||||
class Title(TextMobject):
|
||||
CONFIG = {
|
||||
"scale_factor": 1,
|
||||
"include_underline": True,
|
||||
"underline_width": FRAME_WIDTH - 2,
|
||||
# This will override underline_width
|
||||
"match_underline_width_to_text": False,
|
||||
"underline_buff": MED_SMALL_BUFF,
|
||||
}
|
||||
|
||||
def __init__(self, text, **kwargs):
|
||||
TextMobject.__init__(self, text, **kwargs)
|
||||
self.scale(self.scale_factor)
|
||||
self.to_edge(UP)
|
||||
if self.include_underline:
|
||||
underline = Line(LEFT, RIGHT)
|
||||
underline.next_to(self, DOWN, buff=self.underline_buff)
|
||||
if self.match_underline_width_to_text:
|
||||
underline.match_width(self)
|
||||
else:
|
||||
underline.scale_to_fit_width(self.underline_width)
|
||||
self.add(underline)
|
||||
self.underline = underline
|
||||
|
|
|
@ -565,7 +565,7 @@ def walker_animation_with_display(
|
|||
number_update_func = None,
|
||||
show_arrows = True,
|
||||
scale_arrows = False,
|
||||
num_decimal_points = 1,
|
||||
num_decimal_places = 1,
|
||||
include_background_rectangle = True,
|
||||
**kwargs
|
||||
):
|
||||
|
@ -581,7 +581,7 @@ def walker_animation_with_display(
|
|||
|
||||
if number_update_func != None:
|
||||
display = DecimalNumber(0,
|
||||
num_decimal_points = num_decimal_points,
|
||||
num_decimal_places = num_decimal_places,
|
||||
fill_color = WHITE if include_background_rectangle else BLACK,
|
||||
include_background_rectangle = include_background_rectangle)
|
||||
if include_background_rectangle:
|
||||
|
@ -732,7 +732,7 @@ class PiWalker(ColorMappedByFuncScene):
|
|||
"show_num_plane" : False,
|
||||
"draw_lines" : True,
|
||||
"num_checkpoints" : 10,
|
||||
"num_decimal_points" : 1,
|
||||
"num_decimal_places" : 1,
|
||||
"include_background_rectangle" : False,
|
||||
}
|
||||
|
||||
|
@ -788,7 +788,7 @@ class PiWalker(ColorMappedByFuncScene):
|
|||
number_update_func = number_update_func,
|
||||
run_time = self.step_run_time,
|
||||
walker_stroke_color = WALKER_LIGHT_COLOR if self.color_foreground_not_background else BLACK,
|
||||
num_decimal_points = self.num_decimal_points,
|
||||
num_decimal_places = self.num_decimal_places,
|
||||
include_background_rectangle = self.include_background_rectangle,
|
||||
)
|
||||
|
||||
|
@ -2751,7 +2751,7 @@ class OneFifthTwoFifthWinder(SpecifiedWinder):
|
|||
"step_size" : 0.01,
|
||||
"show_num_plane" : False,
|
||||
"step_run_time" : 6,
|
||||
"num_decimal_points" : 2,
|
||||
"num_decimal_places" : 2,
|
||||
}
|
||||
|
||||
class OneFifthOneFifthWinderWithReset(OneFifthTwoFifthWinder):
|
||||
|
|
|
@ -386,7 +386,7 @@ class Introduce1DFunctionCase(Scene):
|
|||
)
|
||||
decimal = DecimalNumber(
|
||||
0,
|
||||
num_decimal_points = 3,
|
||||
num_decimal_places = 3,
|
||||
show_ellipsis = True,
|
||||
)
|
||||
decimal.scale(0.7)
|
||||
|
@ -484,7 +484,7 @@ class Introduce1DFunctionCase(Scene):
|
|||
if show_decimal:
|
||||
decimal = DecimalNumber(
|
||||
axes.x_axis.point_to_number(arrow.get_start()),
|
||||
num_decimal_points = 3,
|
||||
num_decimal_places = 3,
|
||||
# show_ellipsis = True,
|
||||
)
|
||||
height = self.rect.get_height()
|
||||
|
@ -2310,7 +2310,7 @@ class TransitionFromPathsToBoundaries(ColorMappedObjectsScene):
|
|||
)
|
||||
)
|
||||
|
||||
label = DecimalNumber(0, num_decimal_points = 1)
|
||||
label = DecimalNumber(0, num_decimal_places = 1)
|
||||
label_upadte = ContinualChangingDecimal(
|
||||
label, get_total_winding,
|
||||
position_update_func = lambda l : l.next_to(dot, UP+LEFT, SMALL_BUFF)
|
||||
|
|
|
@ -119,7 +119,7 @@ class LightIndicator(VMobject):
|
|||
self.foreground.set_stroke(color=INDICATOR_STROKE_COLOR,width=INDICATOR_STROKE_WIDTH)
|
||||
|
||||
self.add(self.background, self.foreground)
|
||||
self.reading = DecimalNumber(self.intensity,num_decimal_points = self.precision)
|
||||
self.reading = DecimalNumber(self.intensity,num_decimal_places = self.precision)
|
||||
self.reading.set_fill(color=INDICATOR_TEXT_COLOR)
|
||||
self.reading.move_to(self.get_center())
|
||||
if self.show_reading:
|
||||
|
@ -287,7 +287,7 @@ class IntroScene(PiCreatureScene):
|
|||
equals_sign = self.euler_sum.get_part_by_tex("=")
|
||||
|
||||
self.partial_sum_decimal = DecimalNumber(partial_results_values[1],
|
||||
num_decimal_points = 2)
|
||||
num_decimal_places = 2)
|
||||
self.partial_sum_decimal.next_to(equals_sign, RIGHT)
|
||||
|
||||
|
||||
|
@ -313,7 +313,7 @@ class IntroScene(PiCreatureScene):
|
|||
self.partial_sum_decimal,
|
||||
partial_results_values[i+1],
|
||||
run_time = self.duration,
|
||||
num_decimal_points = 6,
|
||||
num_decimal_places = 6,
|
||||
show_ellipsis = True,
|
||||
position_update_func = lambda m: m.next_to(equals_sign, RIGHT)
|
||||
)
|
||||
|
@ -863,7 +863,7 @@ class SingleLighthouseScene(PiCreatureScene):
|
|||
# angle msmt (decimal number)
|
||||
|
||||
self.angle_indicator = DecimalNumber(arc_angle / DEGREES,
|
||||
num_decimal_points = 0,
|
||||
num_decimal_places = 0,
|
||||
unit = "^\\circ",
|
||||
fill_opacity = 1.0,
|
||||
fill_color = WHITE)
|
||||
|
@ -4262,7 +4262,7 @@ class LabeledArc(Arc):
|
|||
|
||||
Arc.__init__(self,angle,**kwargs)
|
||||
|
||||
label = DecimalNumber(self.length, num_decimal_points = 0)
|
||||
label = DecimalNumber(self.length, num_decimal_places = 0)
|
||||
r = BUFFER * self.radius
|
||||
theta = self.start_angle + self.angle/2
|
||||
label_pos = r * np.array([np.cos(theta), np.sin(theta), 0])
|
||||
|
|
|
@ -94,7 +94,7 @@ class LightIndicator(Mobject):
|
|||
self.foreground.set_fill(color = self.fill_color)
|
||||
|
||||
self.add(self.background, self.foreground)
|
||||
self.reading = DecimalNumber(self.intensity,num_decimal_points = self.precision)
|
||||
self.reading = DecimalNumber(self.intensity,num_decimal_places = self.precision)
|
||||
self.reading.set_fill(color=INDICATOR_TEXT_COLOR)
|
||||
self.reading.scale_to_fit_height(self.reading_height)
|
||||
self.reading.move_to(self.get_center())
|
||||
|
@ -317,7 +317,7 @@ class IntroScene(PiCreatureScene):
|
|||
|
||||
partial_sum_decimal = self.partial_sum_decimal = DecimalNumber(
|
||||
series_terms[1],
|
||||
num_decimal_points = 2
|
||||
num_decimal_places = 2
|
||||
)
|
||||
partial_sum_decimal.next_to(equals_sign, RIGHT)
|
||||
|
||||
|
@ -418,7 +418,7 @@ class IntroScene(PiCreatureScene):
|
|||
partial_sum_decimal,
|
||||
series_terms[i+1],
|
||||
run_time = 1,
|
||||
num_decimal_points = 6,
|
||||
num_decimal_places = 6,
|
||||
position_update_func = lambda m: m.next_to(equals_sign, RIGHT)
|
||||
)
|
||||
]
|
||||
|
@ -430,7 +430,7 @@ class IntroScene(PiCreatureScene):
|
|||
ChangeDecimalToValue(
|
||||
partial_sum_decimal,
|
||||
series_terms[i+1],
|
||||
num_decimal_points = 6,
|
||||
num_decimal_places = 6,
|
||||
),
|
||||
]
|
||||
if i == 5:
|
||||
|
@ -451,7 +451,7 @@ class IntroScene(PiCreatureScene):
|
|||
ChangeDecimalToValue(
|
||||
partial_sum_decimal,
|
||||
series_terms[-1],
|
||||
num_decimal_points = 6,
|
||||
num_decimal_places = 6,
|
||||
),
|
||||
morty.change, "confused",
|
||||
)
|
||||
|
@ -1295,7 +1295,7 @@ class IntroduceScreen(Scene):
|
|||
|
||||
self.angle_indicator = DecimalNumber(
|
||||
arc_angle / DEGREES,
|
||||
num_decimal_points = 0,
|
||||
num_decimal_places = 0,
|
||||
unit = "^\\circ"
|
||||
)
|
||||
self.angle_indicator.next_to(self.angle_arc, RIGHT)
|
||||
|
@ -3818,7 +3818,7 @@ class ThinkBackToHowAmazingThisIs(ThreeDScene):
|
|||
dot_pairs = it.starmap(VGroup, zip(positive_dots, negative_dots))
|
||||
|
||||
# Decimal
|
||||
decimal = DecimalNumber(0, num_decimal_points = 6)
|
||||
decimal = DecimalNumber(0, num_decimal_places = 6)
|
||||
decimal.to_edge(UP)
|
||||
terms = [2./(n**2) for n in range(1, 100, 2)]
|
||||
partial_sums = np.cumsum(terms)
|
||||
|
@ -4250,7 +4250,7 @@ class LabeledArc(Arc):
|
|||
|
||||
Arc.__init__(self,angle,**kwargs)
|
||||
|
||||
label = DecimalNumber(self.length, num_decimal_points = 0)
|
||||
label = DecimalNumber(self.length, num_decimal_places = 0)
|
||||
r = BUFFER * self.radius
|
||||
theta = self.start_angle + self.angle/2
|
||||
label_pos = r * np.array([np.cos(theta), np.sin(theta), 0])
|
||||
|
|
|
@ -728,7 +728,7 @@ class UnmixMixedPaint(Scene):
|
|||
class MachineThatTreatsOneFrequencyDifferently(Scene):
|
||||
def construct(self):
|
||||
graph = self.get_cosine_graph(0.5)
|
||||
frequency_mob = DecimalNumber(220, num_decimal_points = 0)
|
||||
frequency_mob = DecimalNumber(220, num_decimal_places = 0)
|
||||
frequency_mob.next_to(graph, UP, buff = MED_LARGE_BUFF)
|
||||
|
||||
self.graph = graph
|
||||
|
@ -1273,7 +1273,7 @@ class WrapCosineGraphAroundCircle(FourierMachineScene):
|
|||
def get_winding_frequency_label(self):
|
||||
freq = self.initial_winding_frequency
|
||||
winding_freq_label = VGroup(
|
||||
DecimalNumber(freq, num_decimal_points = 2),
|
||||
DecimalNumber(freq, num_decimal_places = 2),
|
||||
TextMobject("cycles/second")
|
||||
)
|
||||
winding_freq_label.arrange_submobjects(RIGHT)
|
||||
|
|
|
@ -1805,7 +1805,7 @@ class BoxCountingScene(Scene):
|
|||
return label
|
||||
|
||||
def count_boxes(self, boxes):
|
||||
num = DecimalNumber(len(boxes), num_decimal_points = 0)
|
||||
num = DecimalNumber(len(boxes), num_decimal_places = 0)
|
||||
num.next_to(boxes, RIGHT)
|
||||
num.add_to_back(BackgroundRectangle(num))
|
||||
|
||||
|
|
|
@ -559,7 +559,7 @@ class WriteAProgram(Scene):
|
|||
rgb = square.fill_rgb
|
||||
num = DecimalNumber(
|
||||
square.fill_rgb[0],
|
||||
num_decimal_points = 1
|
||||
num_decimal_places = 1
|
||||
)
|
||||
num.set_stroke(width = 1)
|
||||
color = rgba_to_color(1 - (rgb + 0.2)/1.2)
|
||||
|
@ -1113,7 +1113,7 @@ class IntroduceEachLayer(PreviewMNistNetwork):
|
|||
example_num = None
|
||||
for neuron in neurons:
|
||||
o = neuron.get_fill_opacity()
|
||||
num = DecimalNumber(o, num_decimal_points = 1)
|
||||
num = DecimalNumber(o, num_decimal_places = 1)
|
||||
num.scale_to_fit_width(0.7*neuron.get_width())
|
||||
num.move_to(neuron)
|
||||
if o > 0.8:
|
||||
|
|
|
@ -962,14 +962,14 @@ class IntroduceCostFunction(PreviewLearning):
|
|||
terms = VGroup()
|
||||
term_updates = []
|
||||
for arrow, d1, d2 in zip(arrows, *self.decimal_groups):
|
||||
term = DecimalNumber(0, num_decimal_points = 4)
|
||||
term = DecimalNumber(0, num_decimal_places = 4)
|
||||
term.scale_to_fit_height(d1.get_height())
|
||||
term.next_to(arrow, LEFT)
|
||||
term.num_update_func = generate_term_update_func(d1, d2)
|
||||
terms.add(term)
|
||||
term_updates.append(ChangingDecimalWithColor(
|
||||
term, term.num_update_func,
|
||||
num_decimal_points = 4
|
||||
num_decimal_places = 4
|
||||
))
|
||||
brace.target.next_to(terms, LEFT)
|
||||
|
||||
|
@ -2780,7 +2780,7 @@ class TestPerformance(PreviewLearning):
|
|||
"wrong_wait_time" : 0.5,
|
||||
"stroke_width_exp" : 2,
|
||||
"decimal_kwargs" : {
|
||||
"num_decimal_points" : 3,
|
||||
"num_decimal_places" : 3,
|
||||
}
|
||||
}
|
||||
def construct(self):
|
||||
|
|
|
@ -671,7 +671,7 @@ class WalkThroughTwoExample(ShowAveragingCost):
|
|||
decimals = VGroup()
|
||||
for neuron in neurons:
|
||||
activation = neuron.get_fill_opacity()
|
||||
decimal = DecimalNumber(activation, num_decimal_points = 1)
|
||||
decimal = DecimalNumber(activation, num_decimal_places = 1)
|
||||
decimal.scale_to_fit_width(0.7*neuron.get_width())
|
||||
decimal.move_to(neuron)
|
||||
if activation > 0.8:
|
||||
|
@ -748,7 +748,7 @@ class WalkThroughTwoExample(ShowAveragingCost):
|
|||
anims.append(ChangingDecimal(
|
||||
decimal,
|
||||
get_decimal_update(decimal.number, target),
|
||||
num_decimal_points = 1
|
||||
num_decimal_places = 1
|
||||
))
|
||||
anims.append(UpdateFromFunc(
|
||||
self.decimals[i],
|
||||
|
@ -1076,7 +1076,7 @@ class WalkThroughTwoExample(ShowAveragingCost):
|
|||
ChangingDecimal(
|
||||
two_decimal,
|
||||
lambda a : interpolate(two_activation, 1, a),
|
||||
num_decimal_points = 1,
|
||||
num_decimal_places = 1,
|
||||
),
|
||||
UpdateFromFunc(
|
||||
two_decimal,
|
||||
|
@ -1110,7 +1110,7 @@ class WalkThroughTwoExample(ShowAveragingCost):
|
|||
ChangingDecimal(
|
||||
two_decimal,
|
||||
lambda a : interpolate(1, two_activation, a),
|
||||
num_decimal_points = 1,
|
||||
num_decimal_places = 1,
|
||||
),
|
||||
UpdateFromFunc(
|
||||
two_decimal,
|
||||
|
@ -3613,7 +3613,7 @@ class SimplestNetworkExample(PreviewLearning):
|
|||
|
||||
def get_neuron_activation_decimal(self, neuron):
|
||||
opacity = neuron.get_fill_opacity()
|
||||
decimal = DecimalNumber(opacity, num_decimal_points = 2)
|
||||
decimal = DecimalNumber(opacity, num_decimal_places = 2)
|
||||
decimal.scale_to_fit_width(0.85*neuron.get_width())
|
||||
if decimal.number > 0.8:
|
||||
decimal.set_fill(BLACK)
|
||||
|
|
|
@ -226,7 +226,7 @@ def get_circle_drawing_terms(radius = 1, positioning_func = lambda m : m.center(
|
|||
0.25*rotate_vector(radius.get_vector(), TAU/4)
|
||||
),
|
||||
)
|
||||
decimal = DecimalNumber(0, num_decimal_points = 4, show_ellipsis = True)
|
||||
decimal = DecimalNumber(0, num_decimal_places = 4, show_ellipsis = True)
|
||||
decimal.scale(0.75)
|
||||
def reposition_decimal(decimal):
|
||||
vect = radius.get_vector()
|
||||
|
@ -318,7 +318,7 @@ class PiTauDebate(PiCreatureScene):
|
|||
circum_line.next_to(circle, DOWN, buff = MED_LARGE_BUFF)
|
||||
# circum_line.to_edge(LEFT)
|
||||
brace = Brace(circum_line, DOWN, buff = SMALL_BUFF)
|
||||
decimal = DecimalNumber(np.pi, num_decimal_points = 4, show_ellipsis = True)
|
||||
decimal = DecimalNumber(np.pi, num_decimal_places = 4, show_ellipsis = True)
|
||||
decimal.scale(0.75)
|
||||
decimal.next_to(brace, DOWN, SMALL_BUFF)
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ class Introduction(Scene):
|
|||
)
|
||||
get_arrow_update().update(1)
|
||||
decimal = DecimalNumber(
|
||||
curr_product, num_decimal_points=5, show_ellipsis=True)
|
||||
curr_product, num_decimal_places=5, show_ellipsis=True)
|
||||
decimal.next_to(arrow, UP, SMALL_BUFF, submobject_to_align=decimal[:5])
|
||||
decimal_anim = ChangingDecimal(
|
||||
decimal,
|
||||
|
@ -512,7 +512,7 @@ class ShowProduct(Scene):
|
|||
])
|
||||
|
||||
brace = braces[0].copy()
|
||||
decimal = DecimalNumber(partial_products[0], num_decimal_points=4)
|
||||
decimal = DecimalNumber(partial_products[0], num_decimal_places=4)
|
||||
decimal.next_to(brace, DOWN)
|
||||
|
||||
self.add(brace, decimal, dots[0], parts[0])
|
||||
|
@ -677,7 +677,7 @@ class ShowProduct(Scene):
|
|||
])
|
||||
|
||||
brace = braces[0].copy()
|
||||
decimal = DecimalNumber(partial_products_iter.next(), num_decimal_points=4)
|
||||
decimal = DecimalNumber(partial_products_iter.next(), num_decimal_places=4)
|
||||
decimal.next_to(brace, DOWN)
|
||||
|
||||
self.play(*map(FadeIn, [brace, decimal, dots[0]]))
|
||||
|
@ -894,7 +894,7 @@ class DistanceProductScene(MovingCameraScene):
|
|||
self.d_labels.add(d_label)
|
||||
return self.d_labels
|
||||
|
||||
def get_numeric_distance_labels(self, lines=None, num_decimal_points=3, show_ellipsis=True):
|
||||
def get_numeric_distance_labels(self, lines=None, num_decimal_places=3, show_ellipsis=True):
|
||||
radius = self.circle.get_width() / 2
|
||||
if lines is None:
|
||||
if not hasattr(self, "distance_lines"):
|
||||
|
@ -904,7 +904,7 @@ class DistanceProductScene(MovingCameraScene):
|
|||
for line in lines:
|
||||
label = DecimalNumber(
|
||||
line.get_length() / radius,
|
||||
num_decimal_points=num_decimal_points,
|
||||
num_decimal_places=num_decimal_places,
|
||||
show_ellipsis=show_ellipsis,
|
||||
include_background_rectangle=self.include_distance_labels_background_rectangle,
|
||||
)
|
||||
|
@ -943,7 +943,7 @@ class DistanceProductScene(MovingCameraScene):
|
|||
|
||||
product_decimal = DecimalNumber(
|
||||
self.get_distance_product(fraction),
|
||||
num_decimal_points=3,
|
||||
num_decimal_places=3,
|
||||
show_ellipsis=True,
|
||||
include_background_rectangle=self.include_distance_labels_background_rectangle,
|
||||
)
|
||||
|
@ -1632,7 +1632,7 @@ class FromGeometryToAlgebra(DistanceProductScene):
|
|||
values = map(plane.point_to_number, self.get_lh_points())
|
||||
complex_decimal = self.complex_decimal = DecimalNumber(
|
||||
values[3],
|
||||
num_decimal_points=3,
|
||||
num_decimal_places=3,
|
||||
include_background_rectangle=True
|
||||
)
|
||||
complex_decimal.next_to(outer_arrow.get_start(), LEFT, SMALL_BUFF)
|
||||
|
@ -2190,7 +2190,7 @@ class PlugObserverIntoPolynomial(DistanceProductScene):
|
|||
|
||||
numeric_chord_label = DecimalNumber(
|
||||
np.sqrt(3),
|
||||
num_decimal_points=4,
|
||||
num_decimal_places=4,
|
||||
include_background_rectangle=True,
|
||||
show_ellipsis=True,
|
||||
)
|
||||
|
@ -2907,7 +2907,7 @@ class ProveLemma2(PlugObserverIntoPolynomial):
|
|||
|
||||
product = DecimalNumber(
|
||||
self.num_lighthouses,
|
||||
num_decimal_points=3,
|
||||
num_decimal_places=3,
|
||||
show_ellipsis=True
|
||||
)
|
||||
product.move_to(self.q_marks, LEFT)
|
||||
|
@ -3235,7 +3235,7 @@ class KeeperAndSailor(DistanceProductScene, PiCreatureScene):
|
|||
|
||||
new_keeper_dp_decimal = DecimalNumber(
|
||||
self.num_lighthouses,
|
||||
num_decimal_points=3,
|
||||
num_decimal_places=3,
|
||||
)
|
||||
new_keeper_dp_decimal.replace(keeper_dp_decimal, dim_to_match=1)
|
||||
new_keeper_dp_decimal.set_color(YELLOW)
|
||||
|
|
|
@ -4,6 +4,9 @@ from utils.bezier import bezier
|
|||
from utils.simple_functions import sigmoid
|
||||
|
||||
|
||||
def linear(t):
|
||||
return t
|
||||
|
||||
def smooth(t, inflection=10.0):
|
||||
error = sigmoid(-inflection / 2)
|
||||
return (sigmoid(inflection * (t - 0.5)) - error) / (1 - 2 * error)
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
import os
|
||||
from constants import TEX_DIR
|
||||
from constants import TEX_TEXT_TO_REPLACE
|
||||
|
||||
|
||||
def tex_hash(expression, template_tex_file):
|
||||
return str(hash(expression + template_tex_file))
|
||||
|
||||
|
||||
def tex_to_svg_file(expression, template_tex_file):
|
||||
tex_file = generate_tex_file(expression, template_tex_file)
|
||||
dvi_file = tex_to_dvi(tex_file)
|
||||
return dvi_to_svg(dvi_file)
|
||||
|
||||
|
||||
def generate_tex_file(expression, template_tex_file):
|
||||
result = os.path.join(
|
||||
TEX_DIR,
|
||||
tex_hash(expression, template_tex_file)
|
||||
) + ".tex"
|
||||
if not os.path.exists(result):
|
||||
print("Writing \"%s\" to %s" % (
|
||||
"".join(expression), result
|
||||
))
|
||||
with open(template_tex_file, "r") as infile:
|
||||
body = infile.read()
|
||||
body = body.replace(TEX_TEXT_TO_REPLACE, expression)
|
||||
with open(result, "w") as outfile:
|
||||
outfile.write(body)
|
||||
return result
|
||||
|
||||
|
||||
def get_null():
|
||||
if os.name == "nt":
|
||||
return "NUL"
|
||||
return "/dev/null"
|
||||
|
||||
|
||||
def tex_to_dvi(tex_file):
|
||||
result = tex_file.replace(".tex", ".dvi")
|
||||
if not os.path.exists(result):
|
||||
commands = [
|
||||
"latex",
|
||||
"-interaction=batchmode",
|
||||
"-halt-on-error",
|
||||
"-output-directory=" + TEX_DIR,
|
||||
tex_file,
|
||||
">",
|
||||
get_null()
|
||||
]
|
||||
exit_code = os.system(" ".join(commands))
|
||||
if exit_code != 0:
|
||||
log_file = tex_file.replace(".tex", ".log")
|
||||
raise Exception(
|
||||
"Latex error converting to dvi. "
|
||||
"See log output above or the log file: %s" % log_file)
|
||||
return result
|
||||
|
||||
|
||||
def dvi_to_svg(dvi_file, regen_if_exists=False):
|
||||
"""
|
||||
Converts a dvi, which potentially has multiple slides, into a
|
||||
directory full of enumerated pngs corresponding with these slides.
|
||||
Returns a list of PIL Image objects for these images sorted as they
|
||||
where in the dvi
|
||||
"""
|
||||
result = dvi_file.replace(".dvi", ".svg")
|
||||
if not os.path.exists(result):
|
||||
commands = [
|
||||
"dvisvgm",
|
||||
dvi_file,
|
||||
"-n",
|
||||
"-v",
|
||||
"0",
|
||||
"-o",
|
||||
result,
|
||||
">",
|
||||
get_null()
|
||||
]
|
||||
os.system(" ".join(commands))
|
||||
return result
|
Loading…
Add table
Reference in a new issue