Merge remote-tracking branch '3b1b/master'

This commit is contained in:
Solara570 2017-12-22 10:39:27 +08:00
commit 750caffd95
3 changed files with 1623 additions and 46 deletions

View file

@ -68,10 +68,21 @@ class AmbientRotation(ContinualAnimation):
CONFIG = { CONFIG = {
"axis" : OUT, "axis" : OUT,
"rate" : np.pi/12, #Radians per second "rate" : np.pi/12, #Radians per second
"in_place" : True,
"about_point" : None,
} }
def update_mobject(self, dt): def update_mobject(self, dt):
self.mobject.rotate(dt*self.rate, axis = self.axis) if self.about_point:
about_point = self.about_point
elif self.in_place:
about_point = self.mobject.get_center()
else:
about_point = ORIGIN
self.mobject.rotate(
dt*self.rate, axis = self.axis,
about_point = about_point
)
class AmbientMovement(ContinualAnimation): class AmbientMovement(ContinualAnimation):
CONFIG = { CONFIG = {
@ -102,7 +113,19 @@ class ContinualMaintainPositionRelativeTo(ContinualAnimation):
def update_mobject(self, dt): def update_mobject(self, dt):
self.anim.update(0) self.anim.update(0)
class NormalAnimationAsContinualAnimation(ContinualAnimation):
CONFIG = {
"start_up_time" : 0,
"wind_down_time" : 0,
}
def __init__(self, animation, **kwargs):
self.animation = animation
ContinualAnimation.__init__(self, animation.mobject, **kwargs)
def update_mobject(self, dt):
self.animation.update(
min(float(self.internal_time)/self.animation.run_time, 1)
)

View file

@ -29,6 +29,7 @@ from mobject.svg_mobject import *
from mobject.tex_mobject import * from mobject.tex_mobject import *
from topics.graph_scene import * from topics.graph_scene import *
from topics.probability import * from topics.probability import *
from topics.common_scenes import *
#revert_to_original_skipping_status #revert_to_original_skipping_status
@ -232,8 +233,8 @@ class InitialFiveChooseThreeExample(Scene):
"one_color" : PINK, "one_color" : PINK,
} }
def construct(self): def construct(self):
self.add_title()
self.show_all_stacks() self.show_all_stacks()
self.add_title()
self.show_binomial_name() self.show_binomial_name()
self.issolate_single_stack() self.issolate_single_stack()
self.count_chosen_stack() self.count_chosen_stack()
@ -241,21 +242,32 @@ class InitialFiveChooseThreeExample(Scene):
self.walk_though_notation() self.walk_though_notation()
self.emphasize_pattern_over_number() self.emphasize_pattern_over_number()
def add_title(self):
symbol = TexMobject("n \\choose k")
words = TextMobject("``n choose k''")
group = VGroup(symbol, words)
group.arrange_submobjects(RIGHT)
group.to_edge(UP)
self.add(group)
self.n_choose_k = symbol
self.n_choose_k_words = words
def show_all_stacks(self): def show_all_stacks(self):
stacks = get_stacks(
self.get_obj1(), self.get_obj2(), self.n,
vertical_buff = SMALL_BUFF
)
stacks.to_edge(DOWN, buff = MED_LARGE_BUFF)
for stack in stacks:
self.play(FadeIn(
stack,
run_time = 0.2*len(stack),
submobject_mode = "lagged_start"
))
self.dither()
self.set_variables_as_attrs(stacks)
def add_title(self):
n = self.n n = self.n
n_choose_k = self.n_choose_k stacks = self.stacks
n_choose_k_words = self.n_choose_k_words
n_choose_k = TexMobject("n \\choose k")
n_choose_k_words = TextMobject("``n choose k''")
nCk_group = VGroup(n_choose_k, n_choose_k_words)
nCk_group.arrange_submobjects(RIGHT)
nCk_group.to_edge(UP)
binomials = VGroup(*[ binomials = VGroup(*[
TexMobject("%d \\choose %d"%(n, k)) TexMobject("%d \\choose %d"%(n, k))
@ -271,11 +283,6 @@ class InitialFiveChooseThreeExample(Scene):
equation[1].highlight(WHITE) equation[1].highlight(WHITE)
binomial_equations.add(equation) binomial_equations.add(equation)
stacks = get_stacks(
self.get_obj1(), self.get_obj2(), n,
vertical_buff = SMALL_BUFF
)
stacks.to_edge(DOWN, buff = MED_LARGE_BUFF)
for stack, eq in zip(stacks, binomial_equations): for stack, eq in zip(stacks, binomial_equations):
eq.scale_to_fit_width(0.9*stack.get_width()) eq.scale_to_fit_width(0.9*stack.get_width())
eq.next_to(stack, UP) eq.next_to(stack, UP)
@ -287,11 +294,7 @@ class InitialFiveChooseThreeExample(Scene):
group.target = eq group.target = eq
mover.add(group) mover.add(group)
self.play(FadeIn( self.play(FadeIn(nCk_group))
stacks,
run_time = 2,
submobject_mode = "lagged_start"
))
self.play(LaggedStart( self.play(LaggedStart(
MoveToTarget, mover, MoveToTarget, mover,
run_time = 3, run_time = 3,
@ -300,7 +303,10 @@ class InitialFiveChooseThreeExample(Scene):
self.add(binomial_equations) self.add(binomial_equations)
self.dither() self.dither()
self.set_variables_as_attrs(stacks, binomial_equations) self.set_variables_as_attrs(
n_choose_k, n_choose_k_words,
binomial_equations
)
def show_binomial_name(self): def show_binomial_name(self):
new_words = TextMobject("``Binomial coefficients''") new_words = TextMobject("``Binomial coefficients''")
@ -466,10 +472,12 @@ class SixChooseThreeExample(InitialFiveChooseThreeExample):
equation.highlight_by_tex("=", WHITE) equation.highlight_by_tex("=", WHITE)
equation.next_to(stack, RIGHT, LARGE_BUFF) equation.next_to(stack, RIGHT, LARGE_BUFF)
self.play( self.add(equation)
FadeIn(equation), self.play(LaggedStart(
LaggedStart(FadeIn, stack) FadeIn, stack,
) lag_ratio = 0.1,
run_time = 10,
))
self.dither() self.dither()
self.set_variables_as_attrs(stack) self.set_variables_as_attrs(stack)
@ -987,11 +995,10 @@ class ProbabilityOfKWomenInGroupOfFive(Scene):
CONFIG = { CONFIG = {
"random_seed" : 0, "random_seed" : 0,
"n_people_per_lineup" : 5, "n_people_per_lineup" : 5,
"n_examples" : 16, "n_examples" : 18,
"item_line_width" : 0.4, "item_line_width" : 0.4,
} }
def construct(self): def construct(self):
random.seed(self.random_seed)
self.ask_question() self.ask_question()
self.show_all_possibilities() self.show_all_possibilities()
self.stack_all_choices_by_number_of_women() self.stack_all_choices_by_number_of_women()
@ -1022,19 +1029,15 @@ class ProbabilityOfKWomenInGroupOfFive(Scene):
return lineup return lineup
last_lineup = get_lineup() last_lineup = get_lineup()
self.play( self.play(LaggedStart(FadeIn, last_lineup, run_time = 1))
LaggedStart(FadeIn, last_lineup),
LaggedStart(FadeIn, prob_words),
)
for x in xrange(self.n_examples): for x in xrange(self.n_examples):
lineup = get_lineup() lineup = get_lineup()
self.play( anims = [last_lineup.items.fade, 1]
# last_lineup.items.shift, UP, anims += map(GrowFromCenter, lineup.items)
last_lineup.items.fade, 1, if x >= 12 and x-12 < len(prob_words):
*map(GrowFromCenter, lineup.items), anims.append(FadeIn(prob_words[x-12]))
run_time = 0.75 self.play(*anims, run_time = 0.75)
)
self.remove(last_lineup) self.remove(last_lineup)
self.add(lineup) self.add(lineup)
self.dither(0.25) self.dither(0.25)
@ -1299,12 +1302,42 @@ class ProbabilityOfKWomenInGroupOfFive(Scene):
result.items = items result.items = items
return result return result
class AskAboutAllPossibilities(ProbabilityOfKWomenInGroupOfFive):
def construct(self):
man, woman = Male(), Female()
all_lineups = VGroup()
for bits in it.product(*[[False, True]]*5):
mobs = [
woman.copy() if bit else man.copy()
for bit in bits
]
all_lineups.add(self.get_lineup(*mobs))
brace = Brace(all_lineups, UP)
question = brace.get_text("What are all possibilities?")
self.add(brace, question)
for lineup in all_lineups:
self.add(lineup)
self.dither(0.25)
self.remove(lineup)
class RememberThisSensation(TeacherStudentsScene): class RememberThisSensation(TeacherStudentsScene):
def construct(self): def construct(self):
self.teacher_says("Remember this \\\\ sensation") self.teacher_says("Remember this \\\\ sensation")
self.change_student_modes("confused", "pondering", "erm") self.change_student_modes("confused", "pondering", "erm")
self.dither(2) self.dither(2)
class TeacherHoldingSomething(TeacherStudentsScene):
def construct(self):
self.play(
self.teacher.change, "raise_right_hand",
)
self.change_student_modes(
*["pondering"]*3,
look_at_arg = 2*UP+2*RIGHT
)
self.dither(6)
# class GroupsOf6(Scene): # class GroupsOf6(Scene):
# def construct(self): # def construct(self):
# title = TexMobject("2^6 =", "64", "\\text{ Possibilities}") # title = TexMobject("2^6 =", "64", "\\text{ Possibilities}")
@ -2630,6 +2663,57 @@ class SubsetProbabilityExample(ChooseThreeFromFive):
self.dither(0.25) self.dither(0.25)
self.remove(name_rect) self.remove(name_rect)
class StudentsGetConfused(PiCreatureScene):
def construct(self):
pi1, pi2 = self.pi_creatures
line = VGroup(
Male(), Female(), Female(), Male(), Female()
)
width = line.get_width()
for i, mob in enumerate(line):
mob.shift((i*width+SMALL_BUFF)*RIGHT)
line.scale(1.5)
line.arrange_submobjects(RIGHT, SMALL_BUFF)
line.move_to(self.pi_creatures, UP)
self.add(line)
self.play(
self.get_shuffle_anim(line),
PiCreatureSays(
pi1, "Wait \\dots order matters now?",
target_mode = "confused",
look_at_arg = line
)
)
self.play(
self.get_shuffle_anim(line),
*[
ApplyMethod(pi.change, "confused", line)
for pi in self.pi_creatures
]
)
for x in range(4):
self.play(self.get_shuffle_anim(line))
self.dither()
def create_pi_creatures(self):
pis = VGroup(*[
Randolph(color = color)
for color in BLUE_D, BLUE_B
])
pis[1].flip()
pis.arrange_submobjects(RIGHT, buff = 5)
pis.to_edge(DOWN)
return pis
def get_shuffle_anim(self, line):
indices = range(len(line))
random.shuffle(indices)
line.generate_target()
for i, m in zip(indices, line.target):
m.move_to(line[i])
return MoveToTarget(line, path_arc = np.pi)
class HowToComputeNChooseK(ChooseThreeFromFive): class HowToComputeNChooseK(ChooseThreeFromFive):
CONFIG = { CONFIG = {
"n" : 5, "n" : 5,
@ -2638,6 +2722,8 @@ class HowToComputeNChooseK(ChooseThreeFromFive):
"n_permutaitons_to_show" : 5, "n_permutaitons_to_show" : 5,
} }
def construct(self): def construct(self):
self.force_skipping()
self.setup_people() self.setup_people()
self.choose_example_ordered_triplets() self.choose_example_ordered_triplets()
self.count_possibilities() self.count_possibilities()
@ -2646,6 +2732,9 @@ class HowToComputeNChooseK(ChooseThreeFromFive):
self.reset_stage() self.reset_stage()
self.show_whats_being_counted() self.show_whats_being_counted()
self.revert_to_original_skipping_status()
self.indicate_final_answer()
def setup_people(self): def setup_people(self):
people = self.people people = self.people
names = self.get_names(people) names = self.get_names(people)
@ -2880,6 +2969,30 @@ class HowToComputeNChooseK(ChooseThreeFromFive):
) )
self.dither() self.dither()
self.ordered_triplets = lines
self.triplet_group_rects = rects
self.rhs = rhs
def indicate_final_answer(self):
ordered_triplets = self.ordered_triplets
rects = self.triplet_group_rects
fraction = VGroup(*self.rhs[1:])
frac_rect = SurroundingRectangle(fraction)
brace = Brace(rects, LEFT)
brace_tex = brace.get_tex("10")
self.play(FocusOn(fraction))
self.play(ShowCreation(frac_rect))
self.play(FadeOut(frac_rect))
self.dither()
self.play(
GrowFromCenter(brace),
Write(brace_tex),
)
self.dither()
#### ####
def get_choice_counts(self, n, k): def get_choice_counts(self, n, k):
@ -3179,6 +3292,55 @@ class WeirdKindOfCancelation(TeacherStudentsScene):
for i, m in zip(permutation, mobject) for i, m in zip(permutation, mobject)
]) ])
class ABCNotBCA(Scene):
def construct(self):
words = TextMobject("If order mattered:")
equation = TextMobject("(A, B, C) $\\ne$ (B, C, A)")
equation.highlight(YELLOW)
equation.next_to(words, DOWN)
group = VGroup(words, equation)
group.scale_to_fit_width(2*SPACE_WIDTH - 1)
group.to_edge(DOWN)
self.add(words, equation)
class ShowFormula(Scene):
def construct(self):
specific_formula = TexMobject(
"{9 \\choose 4}", "=",
"{9 \\cdot 8 \\cdot 7 \\cdot 6", "\\over",
"4 \\cdot 3 \\cdot 2 \\cdot 1}"
)
general_formula = TexMobject(
"{n \\choose k}", "=",
"{n \\cdot (n-1) \\cdots (n-k+1)", "\\over",
"k \\cdot (k-1) \\cdots 2 \\cdot 1}"
)
for i, j in (0, 1), (2, 0), (2, 3), (2, 11):
general_formula[i][j].highlight(BLUE)
for i, j in (0, 2), (2, 13), (4, 0), (4, 3):
general_formula[i][j].highlight(YELLOW)
formulas = VGroup(specific_formula, general_formula)
formulas.arrange_submobjects(DOWN, buff = 2)
formulas.to_edge(UP)
self.play(FadeIn(specific_formula))
self.play(FadeIn(general_formula))
self.dither(3)
class ConfusedPi(Scene):
def construct(self):
morty = Mortimer()
morty.scale(2.5)
morty.to_corner(UP+LEFT)
morty.look(UP+LEFT)
self.add(morty)
self.play(Blink(morty))
self.play(morty.change, "confused")
self.dither()
self.play(Blink(morty))
self.dither(2)
class SumsToPowerOf2(Scene): class SumsToPowerOf2(Scene):
CONFIG = { CONFIG = {
"n" : 5, "n" : 5,
@ -3408,9 +3570,94 @@ class NextVideo(Scene):
) )
self.dither() self.dither()
class CombinationsPatreonEndScreen(PatreonEndScreen):
CONFIG = {
"specific_patrons" : [
"Randall Hunt",
"Desmos",
"Burt Humburg",
"CrypticSwarm",
"Juan Benet",
"David Kedmey",
"Ali Yahya",
"Mayank M. Mehrotra",
"Lukas Biewald",
"Yana Chernobilsky",
"Kaustuv DeBiswas",
"Kathryn Schmiedicke",
"Yu Jun",
"Dave Nicponski",
"Damion Kistler",
"Jordan Scales",
"Markus Persson",
"Egor Gumenuk",
"Yoni Nazarathy",
"Ryan Atallah",
"Joseph John Cox",
"Luc Ritchie",
"Supershabam",
"James Park",
"Samantha D. Suplee",
"Delton Ding",
"Thomas Tarler",
"Jonathan Eppele",
"Isak Hietala",
"1stViewMaths",
"Jacob Magnuson",
"Mark Govea",
"Dagan Harrington",
"Clark Gaebel",
"Eric Chow",
"Mathias Jansson",
"David Clark",
"Michael Gardner",
"Mads Elvheim",
"Erik Sundell",
"Awoo",
"Dr. David G. Stork",
"Tianyu Ge",
"Ted Suzman",
"Linh Tran",
"Andrew Busey",
"John Haley",
"Ankalagon",
"Eric Lavault",
"Boris Veselinovich",
"Julian Pulgarin",
"Jeff Linse",
"Cooper Jones",
"Ryan Dahl",
"Robert Teed",
"Jason Hise",
"Meshal Alshammari",
"Bernd Sing",
"James Thornton",
"Mustafa Mahdi",
"Mathew Bramson",
"Jerry Ling",
"Shimin Kuang",
"Rish Kundalia",
"Achille Brighton",
"Ripta Pasay",
]
}
class Thumbnail(Scene):
def construct(self):
n_choose_k = TexMobject("n \\choose k")
n_choose_k[1].highlight(YELLOW)
n_choose_k[2].highlight(YELLOW)
n_choose_k.scale(2)
n_choose_k.to_edge(UP)
stacks = get_stacks(
TexMobject("1").highlight(PINK),
TexMobject("0").highlight(BLUE),
n = 5, vertical_buff = SMALL_BUFF,
)
stacks.to_edge(DOWN)
stacks.shift(MED_SMALL_BUFF*LEFT)
self.add(n_choose_k, stacks)

1307
mug.py Normal file

File diff suppressed because it is too large Load diff