tweaking intro scene

This commit is contained in:
Ben Hambrecht
2018-05-02 17:18:23 +02:00
parent 51129b51ba
commit 337ee743a6
2 changed files with 191 additions and 186 deletions

View File

@ -2,8 +2,10 @@ from big_ol_pile_of_manim_imports import *
from old_projects.eoc.chapter8 import *
from active_projects.eop.histograms import *
from active_projects.eop.independence import *
from active_projects.eop.combinations import *
import scipy.special
import itertools as it
COIN_RADIUS = 0.18
@ -15,7 +17,7 @@ COIN_STROKE_WIDTH = 2
COIN_SEQUENCE_SPACING = 0.1
GRADE_COLOR_1 = COLOR_HEADS = RED
GRADE_COLOR_2 = COLOR_TAILS = BLUE
GRADE_COLOR_2 = COLOR_TAILS = BLUE_E
TALLY_BACKGROUND_WIDTH = 1.0
@ -104,10 +106,10 @@ class PiCreatureCoin(VMobject):
class CoinFlippingPiCreature(PiCreature):
def __init__(self, **kwargs):
def __init__(self, mode = "coin_flip_1", **kwargs):
coin = PiCreatureCoin()
PiCreature.__init__(self,**kwargs)
PiCreature.__init__(self, mode = mode, **kwargs)
self.coin = coin
self.add(coin)
right_arm = self.get_arm_copies()[1]
@ -115,7 +117,9 @@ class CoinFlippingPiCreature(PiCreature):
coin.shift(0.15 * self.get_width() * LEFT)
def flip_coin_up(self):
self.change("raise_right_hand")
self.change("coin_flip_2")
class FlipUpAndDown(Animation):
CONFIG = {
@ -129,13 +133,14 @@ class FlipUpAndDown(Animation):
class FlipCoin(AnimationGroup):
CONFIG = {
"rate_func" : there_and_back
"coin_rate_func" : there_and_back,
"pi_rate_func" : there_and_back_with_pause
}
def __init__(self, pi_creature, **kwargs):
digest_config(self, kwargs)
pi_creature_motion = ApplyMethod(
pi_creature.flip_coin_up,
rate_func = self.rate_func,
rate_func = self.pi_rate_func,
**kwargs
)
coin_motion = Succession(
@ -144,7 +149,7 @@ class FlipCoin(AnimationGroup):
pi_creature.coin,
vector = UP,
nb_turns = 5,
rate_func = self.rate_func,
rate_func = self.coin_rate_func,
**kwargs
)
)
@ -1218,7 +1223,7 @@ class TwoDiceTable(Scene):
table = VGroup()
cell_size = 1
colors = np.random.permutation(color_gradient([RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE], 13))
colors = color_gradient([RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE], 13)
for i in range(1,7):
for j in range(1,7):
@ -1239,13 +1244,94 @@ class TwoDiceTable(Scene):
print row2.is_subpath
row1.next_to(table, UP)
row2.next_to(table, LEFT)
self.add(row1, row2)
table.add(row1, row2)
table.center()
class VisualCovariance(Scene):
def construct(self):
size = 4
square = Square(side_length = size)
n_points = 30
cloud = VGroup(*[
Dot((x + 0.8*y) * RIGHT + y * UP).set_fill(WHITE, 1)
for x, y in zip(
np.random.normal(0, 1, n_points),
np.random.normal(0, 1, n_points)
)
])
self.add_foreground_mobject(cloud)
x_axis = Vector(8*RIGHT, color = WHITE).move_to(2.5*DOWN)
y_axis = Vector(5*UP, color = WHITE).move_to(4*LEFT)
self.add(x_axis, y_axis)
random_pairs = [ (p1, p2) for (p1, p2) in
it.combinations(cloud, 2)
]
np.random.shuffle(random_pairs)
for (p1, p2) in random_pairs:
c1, c2 = p1.get_center(), p2.get_center()
x1, y1, x2, y2 = c1[0], c1[1], c2[0], c2[1]
if x1 >= x2:
continue
if y2 > y1:
# make a red rect
color = RED
opacity = 0.1
elif y2 < y1:
# make a blue rect
color = BLUE
opacity = 0.2
rect = Rectangle(width = x2 - x1, height = abs(y2 - y1))
rect.set_fill(color = color, opacity = opacity)
rect.set_stroke(width = 0)
rect.move_to((c1+c2)/2)
self.play(FadeIn(rect), run_time = 0.05)
class BinaryOption(VMobject):
def __init__(self, mob1, mob2, **kwargs):
VMobject.__init__(self, **kwargs)
text = TextMobject("or").scale(0.5)
mob1.next_to(text, LEFT)
mob2.next_to(text, RIGHT)
self.add(mob1, text, mob2)
class BinaryChoices(Scene):
def construct(self):
example1 = BinaryOption(UprightHeads(), UprightTails())
example2 = BinaryOption(Male(), Female())
example3 = BinaryOption(Checkmark(), Xmark())
example2.next_to(example1, DOWN, buff = MED_LARGE_BUFF)
example3.next_to(example2, DOWN, buff = MED_LARGE_BUFF)
all = VGroup(example1, example2, example3)
all = all.scale(2)
self.play(
LaggedStart(FadeIn, all)
)
class BrickRow(VMobject):
@ -1403,39 +1489,40 @@ class BrickRow(VMobject):
class SplitRectsInBrickWall(Animation):
class SplitRectsInBrickWall(AnimationGroup):
def __init__(self, mobject, **kwargs):
r = self.subdiv_level = mobject.subdiv_level + 1
self.subdivs = VGroup()
x = - 0.5 * mobject.width
subdivs = VGroup()
x = -0.5 * mobject.get_width()
anims = []
for k in range(0, r):
proportion = float(choose(r,k)) / 2**r
x += proportion * mobject.width
x += proportion * mobject.get_width()
subdiv = DashedLine(
mobject.get_center() + x * RIGHT + 0.5 * mobject.height * UP,
mobject.get_center() + x * RIGHT + 0.5 * mobject.height * UP,
mobject.get_top() + x * RIGHT,
mobject.get_bottom() + x * RIGHT,
)
self.subdivs.add(subdiv)
subdivs.add(subdiv)
anims.append(ShowCreation(subdiv))
mobject.add(self.subdivs)
Animation.__init__(self, mobject, **kwargs)
mobject.add(subdivs)
AnimationGroup.__init__(self, *anims, **kwargs)
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.height * UP
end = start + alpha * self.mobject.height * DOWN
subdiv.put_start_and_end_on(start,end)
# 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)
@ -1497,7 +1584,11 @@ class WhatDoesItReallyMean(TeacherStudentsScene):
class BrickRowScene(Scene):
def split_tallies(self, 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
self.tallies_copy = self.tallies.copy()
self.add_foreground_mobject(self.tallies_copy)
@ -1522,11 +1613,6 @@ class BrickRowScene(Scene):
for (i, tally) in enumerate(self.tallies):
# if len(self.decimals) > 0:
# decimal = self.decimals[i]
# else:
# decimal = VMobject()
target_left = tally_targets_left[i]
new_tally_left = TallyStack(tally.nb_heads + 1, tally.nb_tails)
new_tally_left.move_anchor_to(target_left)
@ -1534,13 +1620,11 @@ class BrickRowScene(Scene):
self.play(
tally.move_anchor_to, target_left,
#decimal.shift,v
)
tally.anchor = target_left
self.play(Transform(tally, new_tally_left))
tally_copy = self.tallies_copy[i]
#decimal_copy = decimal.copy()
target_right = tally_targets_right[i]
new_tally_right = TallyStack(tally.nb_heads, tally.nb_tails + 1)
@ -1551,14 +1635,18 @@ class BrickRowScene(Scene):
tally_copy.anchor = target_right
self.play(Transform(tally_copy, new_tally_right))
tally_copy.nb_heads = new_tally_right.nb_heads
tally_copy.nb_tails = new_tally_right.nb_tails
tally.nb_heads = new_tally_left.nb_heads
tally.nb_tails = new_tally_left.nb_tails
def tally_split_animations(self, 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
self.tallies_copy = self.tallies.copy()
self.add_foreground_mobject(self.tallies_copy)
@ -1583,38 +1671,24 @@ class BrickRowScene(Scene):
anims1 = []
# if len(self.decimals) > 0:
# self.decimal_copies = VGroup()
for (i, tally) in enumerate(self.tallies):
# if len(self.decimals) > 0:
# decimal = self.decimals[i]
# else:
# decimal = VMobject()
target_left = tally_targets_left[i]
v = target_left - tally.anchor
anims1.append(tally.move_anchor_to)
anims1.append(target_left)
#anims1.append(decimal.shift)
#anims1.append(v)
tally.anchor = target_left
tally_copy = self.tallies_copy[i]
#decimal_copy = decimal.copy()
target_right = tally_targets_right[i]
v = target_right - tally_copy.anchor
anims1.append(tally_copy.move_anchor_to)
anims1.append(target_right)
#anims1.append(decimal_copy.shift)
#anims1.append(v)
# if len(self.decimals) > 0:
# self.decimal_copies.add(decimal_copy)
tally_copy.anchor = target_right
@ -1637,18 +1711,15 @@ class BrickRowScene(Scene):
tally.nb_heads = new_tally_left.nb_heads
tally.nb_tails = new_tally_left.nb_tails
# if len(self.decimals) > 0:
# self.add_foreground_mobject(self.decimal_copies)
return anims1, anims2
def split_tallies_at_once(self, direction = DOWN):
anims1, anims2 = self.tally_split_animations(direction = direction)
self.play(*(anims1 + anims2))
def split_tallies_in_two_steps(self, direction = DOWN):
# First all thiode to the left, then those to the right
anims1, anims2 = self.tally_split_animations(direction = direction)
self.play(*anims1)
self.wait(0.3)
@ -1657,41 +1728,6 @@ class BrickRowScene(Scene):
# def split_decimals_alone(self):
# r = self.row.coloring_level
# targets_left = []
# targets_right = []
# for rect in self.row.get_rects_for_level(r):
# target = rect.get_center() + 0.25 * rect.get_width() * LEFT
# targets_left.append(target)
# target = rect.get_center() + 0.25 * rect.get_width() * RIGHT
# targets_right.append(target)
# anims = []
# self.decimal_copies = VGroup()
# for (i, decimal) in enumerate(self.decimals):
# anims.append(decimal.move_to)
# anims.append(targets_left[i])
# decimal_copy = decimal.copy()
# anims.append(decimal_copy.move_to)
# anims.append(targets_right[i])
# self.decimal_copies.add(decimal_copy)
# self.play(*anims)
# self.add_foreground_mobject(self.decimal_copies)
def merge_rects_by_subdiv(self):
half_merged_row = self.row.copy()
@ -1739,44 +1775,12 @@ class BrickRowScene(Scene):
merged_row = self.row.copy()
merged_row.coloring_level += 1
merged_row.generate_points()
merged_row.move_to(self.row)
self.play(FadeIn(merged_row))
self.row = merged_row
# def merge_decimals(self):
# anims = []
# self.new_decimals = VGroup()
# self.decimal_copies = VGroup()
# if self.decimals in self.mobjects:
# anims.append(FadeOut(self.decimals))
# if self.decimal_copies in self.mobjects:
# anims.append(FadeOut(self.decimal_copies))
# r = self.row.coloring_level
# for (i, rect) in enumerate(self.row.rects):
# k = choose(r,i)
# decimal = Integer(k)
# decimal.move_to(rect)
# if rect.get_width() < 0.2:
# # then the rect is too narrow,
# # let the decimal go in dignity
# decimal.set_stroke(width = 0)
# decimal.set_fill(opacity = 0)
# self.new_decimals.add(decimal)
# anims.append(FadeIn(self.new_decimals))
# self.play(*anims)
# self.remove(self.decimal_copies)
# self.decimals = self.new_decimals.copy()
# #self.remove(self.new_decimals)
# self.add_foreground_mobject(self.decimals)
def move_tallies_on_top(self):
self.play(
@ -1787,34 +1791,67 @@ class BrickRowScene(Scene):
def construct(self):
self.force_skipping()
randy = CoinFlippingPiCreature()
randy = randy.scale(0.5).move_to(3*DOWN + 6*LEFT)
self.add(randy)
self.row = BrickRow(1, height = 2, width = 10)
#self.decimals = VGroup()
self.row = BrickRow(0, height = 2, width = 10)
self.wait()
self.play(FlipCoin(randy),
FadeIn(self.row))
self.play(FadeIn(self.row))
self.wait()
# move in all kinds of sequences
coin_seqs = VGroup()
for i in range(20):
n = np.random.randint(1,10)
seq = [np.random.choice(["H", "T"]) for j in range(n)]
coin_seq = CoinSequence(seq).scale(1.5)
loc = np.random.uniform(low = -1, high = 1) * FRAME_X_RADIUS * RIGHT
loc += np.random.uniform(low = -1, high = 1) * FRAME_Y_RADIUS * UP
coin_seq.move_to(loc)
coin_seq.target = coin_seq.copy().scale(0.3).move_to(0.4 * loc)
coin_seq.target.fade(1)
coin_seqs.add(coin_seq)
self.play(
LaggedStart(
Succession, coin_seqs, lambda m: (FadeIn(m, run_time = 0.1), MoveToTarget(m)),
run_time = 5,
lag_ratio = 0.5
)
)
self.play(SplitRectsInBrickWall(self.row))
self.merge_rects_by_subdiv()
self.merge_rects_by_coloring()
#
# put tallies on top
self.tallies = VGroup(*[
TallyStack(1 - i, i) for i in range(2)
])
for (tally, rect) in zip(self.tallies, self.row.rects):
new_anchor = rect.get_center() + 1.2 * 0.5 * rect.get_height() * UP
tally.move_anchor_to(new_anchor)
self.play(FadeIn(tally))
self.single_flip_labels = VGroup(UprightHeads(), UprightTails())
for (label, rect) in zip(self.single_flip_labels, self.row.rects):
label.next_to(rect, UP)
self.play(FadeIn(label))
self.wait()
self.add_foreground_mobject(self.tallies)
#self.tallies = VGroup(*[
# TallyStack(1 - i, i) for i in range(2)
#])
# for (label, rect) in zip(self.single_flip_labels, self.row.rects):
# new_anchor = rect.get_center() + 1.2 * 0.5 * rect.get_height() * UP
# label.move_anchor_to(new_anchor)
# self.play(FadeIn(label))
# self.wait()
self.add_foreground_mobject(self.single_flip_labels)
self.wait()
return
# # # # # # # #
# SECOND FLIP #
@ -1890,18 +1927,6 @@ class BrickRowScene(Scene):
LaggedStart(FadeOut, outcomes)
)
# # show their numbers
# nb_outcomes = [1,3,3,1]
# self.decimals = VGroup()
# for (n,rect) in zip(nb_outcomes, self.row.rects):
# decimal = Integer(n).move_to(rect)
# self.decimals.add(decimal)
# self.play(
# LaggedStart(FadeIn, self.decimals)
# )
# self.wait()
# self.add_foreground_mobject(self.decimals)
# # # # # # # # # # # # # #
# # FOURTH FLIP IN DETAIL #
@ -2049,42 +2074,6 @@ class BrickRowScene(Scene):
#decimals_copy2[k].move_to, new_rects[k],
)
# show new outcome sizes
# new_decimals = VGroup()
# for (i,rect) in zip(new_tally_sizes, new_rects):
# decimal = Integer(i).move_to(rect)
# new_decimals.add(decimal)
# self.play(
# FadeOut(decimals_copy[k - 1]),
# FadeOut(decimals_copy2[k]),
# FadeIn(new_decimals[k])
# )
# # move the old decimals into the new row
# anims = []
# anims.append(decimals_copy2[0].move_to)
# anims.append(new_rects[0])
# for i in range(1,k) + range(k + 1, n):
# anims.append(decimals_copy[i - 1].move_to)
# anims.append(new_rects[i])
# anims.append(decimals_copy2[i].move_to)
# anims.append(new_rects[i])
# anims.append(decimals_copy[n].move_to)
# anims.append(new_rects[n + 1])
# # self.play(*anims)
# # fade them out and fade in their sums
# anims = []
# for i in range(1,k) + range(k + 1, n):
# anims.append(FadeOut(decimals_copy[i - 1]))
# anims.append(FadeOut(decimals_copy2[i]))
# anims.append(FadeIn(new_decimals[i]))
# self.play(*anims)
# self.add_foreground_mobject(new_decimals)
# # # # # # # #
# FIFTH FLIP #
@ -2100,14 +2089,15 @@ class BrickRowScene(Scene):
# original_grouped_outcomes)
self.clear()
self.add(randy, self.row)
self.row.shift(0.5 * UP)
#self.row.shift(0.5 * UP)
#return
self.merge_rects_by_coloring()
self.revert_to_original_skipping_status()
for i in range(3):
for i in range(1):
self.play(FlipCoin(randy))
@ -2118,6 +2108,7 @@ class BrickRowScene(Scene):
)
self.wait()
#self.split_tallies_at_once(direction = LEFT)
self.wait()
self.merge_rects_by_subdiv()

View File

@ -32,6 +32,20 @@ def get_quiz(*questions):
quiz.scale(0.7)
return quiz
class Checkmark(TexMobjectFromPresetString):
CONFIG = {
"tex" : "\\checkmark",
"color" : GREEN
}
class Xmark(TexMobjectFromPresetString):
CONFIG = {
"tex" : "\\times",
"color" : RED
}
def get_slot_group(
bool_list,
buff = MED_LARGE_BUFF,