mirror of
https://github.com/3b1b/manim.git
synced 2026-04-26 03:00:23 -04:00
More music_and_measure, animate->play, making NumberLine better
This commit is contained in:
@@ -27,7 +27,6 @@ class Animation(object):
|
||||
raise Exception("Invalid mobject parameter, must be \
|
||||
subclass or instance of Mobject")
|
||||
self.starting_mobject = copy.deepcopy(self.mobject)
|
||||
self.reference_mobjects = [self.starting_mobject]
|
||||
self.alpha_func = alpha_func or (lambda x : x)
|
||||
self.run_time = run_time
|
||||
#TODO, Adress the idea of filtering the animation
|
||||
@@ -36,6 +35,7 @@ class Animation(object):
|
||||
self.restricted_width = SPACE_WIDTH
|
||||
self.spacial_center = np.zeros(3)
|
||||
self.name = name or self.__class__.__name__ + str(self.mobject)
|
||||
self.update(0)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@@ -187,7 +187,6 @@ class Succession(Animation):
|
||||
for index in range(len(self.anims)):
|
||||
self.anims[index].update(scaled_alpha - index)
|
||||
|
||||
|
||||
####### Pi Creature Stuff #############
|
||||
|
||||
class WalkPiCreature(Animation):
|
||||
|
||||
@@ -39,25 +39,27 @@ class Transform(Animation):
|
||||
self.interpolation_function = interpolation_function
|
||||
count1, count2 = mobject1.get_num_points(), mobject2.get_num_points()
|
||||
if count2 == 0:
|
||||
mobject2.add_points([(SPACE_WIDTH, SPACE_HEIGHT, 0)])
|
||||
mobject2.add_points([SPACE_WIDTH*RIGHT+SPACE_HEIGHT*UP])
|
||||
count2 = mobject2.get_num_points()
|
||||
Mobject.align_data(mobject1, mobject2)
|
||||
Animation.__init__(self, mobject1, run_time = run_time, *args, **kwargs)
|
||||
self.ending_mobject = mobject2
|
||||
if black_out_extra_points and count2 < count1:
|
||||
self.black_out_extra_points(count1, count2)
|
||||
|
||||
Animation.__init__(self, mobject1, run_time = run_time, *args, **kwargs)
|
||||
self.name += "To" + str(mobject2)
|
||||
self.mobject.SHOULD_BUFF_POINTS = \
|
||||
mobject1.SHOULD_BUFF_POINTS and mobject2.SHOULD_BUFF_POINTS
|
||||
self.reference_mobjects.append(mobject2)
|
||||
self.name += "To" + str(mobject2)
|
||||
|
||||
if black_out_extra_points and count2 < count1:
|
||||
#Ensure redundant pixels fade to black
|
||||
indices = np.arange(
|
||||
0, count1-1, float(count1) / count2
|
||||
).astype('int')
|
||||
temp = np.zeros(mobject2.points.shape)
|
||||
temp[indices] = mobject2.rgbs[indices]
|
||||
mobject2.rgbs = temp
|
||||
self.non_redundant_m2_indices = indices
|
||||
def black_out_extra_points(self, count1, count2):
|
||||
#Ensure redundant pixels fade to black
|
||||
indices = np.arange(
|
||||
0, count1-1, float(count1) / count2
|
||||
).astype('int')
|
||||
temp = np.zeros(self.ending_mobject.points.shape)
|
||||
temp[indices] = self.ending_mobject.rgbs[indices]
|
||||
self.ending_mobject.rgbs = temp
|
||||
self.non_redundant_m2_indices = indices
|
||||
|
||||
def update_mobject(self, alpha):
|
||||
self.mobject.points = self.interpolation_function(
|
||||
|
||||
@@ -55,9 +55,9 @@ class PiCreature(CompoundMobject):
|
||||
CompoundMobject.__init__(self, *self.get_parts())
|
||||
return self
|
||||
|
||||
def TODO_what_should_I_do_with_this(self):
|
||||
for part_name, mob in zip(self.part_names, self.split()):
|
||||
setattr(self, part_name, mob)
|
||||
# def TODO_what_should_I_do_with_this(self):
|
||||
# for part_name, mob in zip(self.part_names, self.split()):
|
||||
# setattr(self, part_name, mob)
|
||||
|
||||
|
||||
def get_parts(self):
|
||||
|
||||
@@ -92,27 +92,48 @@ class Grid(Mobject1D):
|
||||
|
||||
class NumberLine(Mobject1D):
|
||||
def __init__(self,
|
||||
radius = SPACE_WIDTH+1,
|
||||
interval_size = 0.5, tick_size = 0.1,
|
||||
*args, **kwargs):
|
||||
self.radius = int(radius)
|
||||
self.interval_size = interval_size
|
||||
radius = SPACE_WIDTH,
|
||||
unit_length_to_spacial_width = 1,
|
||||
tick_size = 0.1,
|
||||
tick_frequency = 0.5,
|
||||
number_at_center = 0,
|
||||
numbers_with_elongated_ticks = [0],
|
||||
longer_tick_multiple = 2,
|
||||
**kwargs):
|
||||
#TODO, There must be better (but still safe) way to add all
|
||||
#these config arguments as attributes.
|
||||
self.radius = radius
|
||||
self.unit_length_to_spacial_width = unit_length_to_spacial_width
|
||||
self.tick_size = tick_size
|
||||
Mobject1D.__init__(self, *args, **kwargs)
|
||||
self.tick_frequency = tick_frequency
|
||||
self.numbers_with_elongated_ticks = numbers_with_elongated_ticks
|
||||
self.number_at_center = number_at_center
|
||||
self.longer_tick_multiple = longer_tick_multiple
|
||||
numerical_radius = float(radius) / unit_length_to_spacial_width
|
||||
self.left_num = number_at_center - numerical_radius
|
||||
self.right_num = number_at_center + numerical_radius
|
||||
Mobject1D.__init__(self, **kwargs)
|
||||
|
||||
def generate_points(self):
|
||||
self.add_points([
|
||||
(x, 0, 0)
|
||||
for x in np.arange(-self.radius, self.radius, self.epsilon)
|
||||
(b*x, 0, 0)
|
||||
for x in np.arange(0, self.radius, self.epsilon)
|
||||
for b in [-1, 1]
|
||||
])
|
||||
self.index_of_left = np.argmin(self.points[:,0])
|
||||
self.index_of_right = np.argmax(self.points[:,0])
|
||||
spacial_tick_frequency = self.tick_frequency*self.unit_length_to_spacial_width
|
||||
self.add_points([
|
||||
(x, y, 0)
|
||||
for x in np.arange(-self.radius, self.radius, self.interval_size)
|
||||
(b*x, y, 0)
|
||||
for x in np.arange(0, self.radius, spacial_tick_frequency)
|
||||
for y in np.arange(-self.tick_size, self.tick_size, self.epsilon)
|
||||
for b in ([1, -1] if x > 0 else [1])
|
||||
])
|
||||
self.elongate_tick_at(0)
|
||||
for number in self.numbers_with_elongated_ticks:
|
||||
self.elongate_tick_at(number, self.longer_tick_multiple)
|
||||
|
||||
def elongate_tick_at(self, x, multiple = 2):
|
||||
def elongate_tick_at(self, number, multiple = 2):
|
||||
x = self.number_to_point(number)[0]
|
||||
self.add_points([
|
||||
[x, y, 0]
|
||||
for y in np.arange(
|
||||
@@ -123,17 +144,37 @@ class NumberLine(Mobject1D):
|
||||
])
|
||||
return self
|
||||
|
||||
def add_numbers(self, intervals_per_number = 2):
|
||||
max_val = int(self.radius/self.interval_size/intervals_per_number)
|
||||
for x in range(-max_val, max_val+1):
|
||||
num = tex_mobject(str(x)).scale(0.5)
|
||||
num.shift(
|
||||
DOWN*4*self.tick_size + \
|
||||
RIGHT*x*self.interval_size*intervals_per_number
|
||||
)
|
||||
self.add(num)
|
||||
def number_to_point(self, number):
|
||||
return interpolate(
|
||||
self.points[self.index_of_left],
|
||||
self.points[self.index_of_right],
|
||||
float(number-self.left_num)/(self.right_num - self.left_num)
|
||||
)
|
||||
|
||||
def add_numbers(self, *numbers):
|
||||
if len(numbers) == 0:
|
||||
numbers = range(int(self.left_num), int(self.right_num+1))
|
||||
for number in numbers:
|
||||
mob = tex_mobject(str(number)).scale(0.5)
|
||||
mob.shift(self.number_to_point(number))
|
||||
mob.shift(DOWN*4*self.tick_size)
|
||||
self.add(mob)
|
||||
return self
|
||||
|
||||
class UnitInterval(NumberLine):
|
||||
DEFAULT_CONFIG = {
|
||||
"radius" : SPACE_WIDTH-1,
|
||||
"unit_length_to_spacial_width" : 2*(SPACE_WIDTH-1),
|
||||
"tick_frequency" : 0.1,
|
||||
"number_at_center" : 0.5,
|
||||
"numbers_with_elongated_ticks" : [0, 1],
|
||||
}
|
||||
def __init__(self, **kwargs):
|
||||
config = self.DEFAULT_CONFIG
|
||||
config.update(kwargs)
|
||||
NumberLine.__init__(self, **config)
|
||||
|
||||
|
||||
class Axes(CompoundMobject):
|
||||
def __init__(self, *args, **kwargs):
|
||||
x_axis = NumberLine(*args, **kwargs)
|
||||
|
||||
@@ -21,6 +21,7 @@ class Mobject(object):
|
||||
DEFAULT_COLOR = Color("skyblue")
|
||||
SHOULD_BUFF_POINTS = GENERALLY_BUFF_POINTS
|
||||
EDGE_BUFFER = 0.5
|
||||
NEXT_TO_BUFFER = 0.2
|
||||
|
||||
def __init__(self,
|
||||
color = None,
|
||||
@@ -152,12 +153,17 @@ class Mobject(object):
|
||||
self.shift(shift_val)
|
||||
return self
|
||||
|
||||
def next_to(self, mobject, direction = RIGHT, buff = EDGE_BUFFER):
|
||||
self.shift(
|
||||
mobject.get_edge_center(direction) - \
|
||||
self.get_edge_center(-direction) + \
|
||||
buff * direction
|
||||
)
|
||||
def next_to(self, mobject,
|
||||
direction = RIGHT,
|
||||
buff = NEXT_TO_BUFFER,
|
||||
aligned_edge = None):
|
||||
if aligned_edge is not None:
|
||||
anchor_point = self.get_corner(aligned_edge-direction)
|
||||
target_point = mobject.get_corner(aligned_edge+direction)
|
||||
else:
|
||||
anchor_point = self.get_edge_center(-direction)
|
||||
target_point = mobject.get_edge_center(direction)
|
||||
self.shift(target_point - anchor_point + buff*direction)
|
||||
return self
|
||||
|
||||
def scale(self, scale_factor):
|
||||
@@ -225,8 +231,16 @@ class Mobject(object):
|
||||
self.rgbs[:,:] = rgb
|
||||
return self
|
||||
|
||||
def to_original_color(self):
|
||||
self.highlight(self.color)
|
||||
return self
|
||||
|
||||
def fade_to(self, color, alpha):
|
||||
self.rgbs = interpolate(self.rgbs, Color(color).rgb, alpha)
|
||||
return self
|
||||
|
||||
def fade(self, brightness = 0.5):
|
||||
self.rgbs *= brightness
|
||||
self.fade_to("black", brightness)
|
||||
return self
|
||||
|
||||
def filter_out(self, condition):
|
||||
@@ -268,6 +282,13 @@ class Mobject(object):
|
||||
result[dim] = max_or_min_func(self.points[:,dim])
|
||||
return result
|
||||
|
||||
def get_corner(self, direction):
|
||||
return sum([
|
||||
self.get_edge_center(RIGHT*direction[0]),
|
||||
self.get_edge_center(UP*direction[1]),
|
||||
-self.get_center()
|
||||
])
|
||||
|
||||
def get_top(self):
|
||||
return self.get_edge_center(UP)
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ class Arrow(Line):
|
||||
|
||||
def add_tip(self, tip_length):
|
||||
vect = self.start-self.end
|
||||
vect *= tip_length/np.linalg.norm(vect)
|
||||
vect = vect*tip_length/np.linalg.norm(vect)
|
||||
self.add_points([
|
||||
interpolate(self.end, self.end+v, t)
|
||||
for t in np.arange(0, 1, tip_length*self.epsilon)
|
||||
@@ -217,8 +217,8 @@ class Bubble(Mobject):
|
||||
return self
|
||||
|
||||
class SpeechBubble(Bubble):
|
||||
INITIAL_WIDTH = 6
|
||||
INITIAL_HEIGHT = 4
|
||||
INITIAL_WIDTH = 4
|
||||
INITIAL_HEIGHT = 2
|
||||
def __init__(self, *args, **kwargs):
|
||||
Mobject.__init__(self, *args, **kwargs)
|
||||
complex_power = 0.9
|
||||
|
||||
@@ -56,7 +56,7 @@ class RearrangeEquation(Scene):
|
||||
if leave_start_terms:
|
||||
self.add(CompoundMobject(*start_mobs))
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*pair, **transform_kwargs)
|
||||
for pair in mobject_pairs
|
||||
])
|
||||
|
||||
@@ -52,7 +52,7 @@ class CountingScene(Scene):
|
||||
self.dither(frame_time)
|
||||
mob.highlight(original_color)
|
||||
if mode == "show_creation":
|
||||
self.animate(ShowCreation(mob, run_time = frame_time))
|
||||
self.play(ShowCreation(mob, run_time = frame_time))
|
||||
if mode == "show":
|
||||
self.add(mob)
|
||||
self.dither(frame_time)
|
||||
|
||||
@@ -220,10 +220,10 @@ class GraphScene(Scene):
|
||||
|
||||
def draw_vertices(self, **kwargs):
|
||||
self.clear()
|
||||
self.animate(ShowCreation(CompoundMobject(*self.vertices), **kwargs))
|
||||
self.play(ShowCreation(CompoundMobject(*self.vertices), **kwargs))
|
||||
|
||||
def draw_edges(self):
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(edge, run_time = 1.0)
|
||||
for edge in self.edges
|
||||
])
|
||||
@@ -235,7 +235,7 @@ class GraphScene(Scene):
|
||||
Dot(point, radius = 3*Dot.DEFAULT_RADIUS, color = "lightgreen")
|
||||
for point in self.points
|
||||
])
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
start, end, alpha_func = there_and_back,
|
||||
**kwargs
|
||||
))
|
||||
@@ -246,7 +246,7 @@ class GraphScene(Scene):
|
||||
def replace_vertices_with(self, mobject):
|
||||
mobject.center()
|
||||
diameter = max(mobject.get_height(), mobject.get_width())
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(
|
||||
vertex,
|
||||
deepcopy(mobject).shift(vertex.get_center())
|
||||
@@ -267,7 +267,7 @@ class GraphScene(Scene):
|
||||
for angle, edge in zip(angles, self.edges)
|
||||
]
|
||||
if fade_in:
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
FadeIn(ann, **kwargs)
|
||||
for ann in self.edge_annotations
|
||||
])
|
||||
@@ -282,7 +282,7 @@ class GraphScene(Scene):
|
||||
Line(self.points[i], self.points[j]).highlight(color)
|
||||
for i, j in zip(cycle, next_in_cycle)
|
||||
])
|
||||
self.animate(
|
||||
self.play(
|
||||
ShowCreation(self.traced_cycle),
|
||||
run_time = run_time
|
||||
)
|
||||
|
||||
15
scene/number_line.py
Normal file
15
scene/number_line.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import numpy as np
|
||||
import itertools as it
|
||||
|
||||
from scene import Scene
|
||||
|
||||
from mobject import *
|
||||
from animation import *
|
||||
from region import *
|
||||
from constants import *
|
||||
from helpers import *
|
||||
|
||||
|
||||
class NumberLineScene(Scene):
|
||||
def construct(self):
|
||||
pass
|
||||
@@ -98,7 +98,7 @@ class Scene(object):
|
||||
self.background = self.original_background
|
||||
return self
|
||||
|
||||
def animate(self, *animations, **kwargs):
|
||||
def play(self, *animations, **kwargs):
|
||||
if "run_time" in kwargs:
|
||||
run_time = kwargs["run_time"]
|
||||
else:
|
||||
@@ -127,7 +127,7 @@ class Scene(object):
|
||||
progress_bar.finish()
|
||||
return self
|
||||
|
||||
def animate_over_time_range(self, t0, t1, *animations):
|
||||
def play_over_time_range(self, t0, t1, *animations):
|
||||
needed_scene_time = max(abs(t0), abs(t1))
|
||||
existing_scene_time = len(self.frames)*self.frame_duration
|
||||
if existing_scene_time < needed_scene_time:
|
||||
|
||||
@@ -235,7 +235,7 @@ class Introduction(Scene):
|
||||
|
||||
self.add(words)
|
||||
self.dither()
|
||||
self.animate(DelayByOrder(Transform(words, hand)))
|
||||
self.play(DelayByOrder(Transform(words, hand)))
|
||||
self.dither()
|
||||
|
||||
|
||||
@@ -261,9 +261,9 @@ class ShowReadingRule(Scene):
|
||||
self.add(answer[0])
|
||||
counts = map(finger_tip_power_of_2, range(5))
|
||||
for count in counts:
|
||||
self.animate(SpinInFromNothing(count, run_time = 0.3))
|
||||
self.play(SpinInFromNothing(count, run_time = 0.3))
|
||||
self.dither()
|
||||
self.animate(ShimmerIn(answer[1]))
|
||||
self.play(ShimmerIn(answer[1]))
|
||||
for count in sample_counts:
|
||||
self.clear()
|
||||
self.add(*answer)
|
||||
@@ -283,7 +283,7 @@ class ShowReadingRule(Scene):
|
||||
).to_corner(UP+RIGHT).split()
|
||||
self.add(hand, *count_mobs)
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(count_mobs[n/2], sum_mobs[n])
|
||||
if n%2 == 0 and n/2 < len(counts)
|
||||
else FadeIn(sum_mobs[n])
|
||||
@@ -325,7 +325,7 @@ class ShowIncrementRule(Scene):
|
||||
if pause:
|
||||
self.background = oh.frames[COUNT_TO_FRAME_NUM[start]]
|
||||
self.add(phrase)
|
||||
self.animate(ShimmerIn(self.get_arrow_set(start)))
|
||||
self.play(ShimmerIn(self.get_arrow_set(start)))
|
||||
self.dither()
|
||||
self.clear()
|
||||
self.reset_background()
|
||||
@@ -391,7 +391,7 @@ class MindFindsShortcuts(Scene):
|
||||
seven
|
||||
)
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(compound, Arrow(hand, seven).highlight("yellow")),
|
||||
ShimmerIn(text_mobject("Directly recognize").shift(1.5*DOWN+2*RIGHT))
|
||||
)
|
||||
@@ -413,7 +413,7 @@ class MindFindsShortcuts(Scene):
|
||||
|
||||
self.add(words2, hands[23])
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(
|
||||
deepcopy(hands[16]).highlight("black").center().shift(hands[23].get_center()),
|
||||
hands[16]
|
||||
@@ -427,7 +427,7 @@ class MindFindsShortcuts(Scene):
|
||||
FadeIn(plus)
|
||||
)
|
||||
self.dither()
|
||||
self.animate(ShimmerIn(equals23))
|
||||
self.play(ShimmerIn(equals23))
|
||||
self.dither()
|
||||
|
||||
|
||||
@@ -452,7 +452,7 @@ class FinishCountingExampleSentence(Scene):
|
||||
comp = CompoundMobject(sixteen, two)
|
||||
self.add(hand, comp, words)
|
||||
self.dither()
|
||||
self.animate(Transform(comp, eightteen))
|
||||
self.play(Transform(comp, eightteen))
|
||||
self.dither()
|
||||
|
||||
class Question(Scene):
|
||||
@@ -474,7 +474,7 @@ class WithToes(Scene):
|
||||
]).split()
|
||||
self.add(words[0])
|
||||
self.dither()
|
||||
self.animate(ShimmerIn(words[1]))
|
||||
self.play(ShimmerIn(words[1]))
|
||||
self.dither()
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class PreferOtherProofDialogue(Scene):
|
||||
|
||||
self.add(student, teacher, teacher_bubble, teacher_bubble.text)
|
||||
self.dither(2)
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
Dot(student_bubble.tip).highlight("black"),
|
||||
CompoundMobject(student_bubble, student_bubble.text)
|
||||
))
|
||||
@@ -76,7 +76,7 @@ class IllustrateDuality(GraphScene):
|
||||
"run_time" : 5.0,
|
||||
"alpha_func" : special_alpha
|
||||
}
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*edge_pair, **kwargs)
|
||||
for edge_pair in zip(self.edges, self.dual_edges)
|
||||
] + [
|
||||
@@ -129,7 +129,7 @@ class IntroduceGraph(GraphScene):
|
||||
"run_time" : 5.0
|
||||
}
|
||||
self.add(not_okay)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*pair, **kwargs)
|
||||
for pair in zip(
|
||||
self.edges + self.vertices,
|
||||
@@ -142,7 +142,7 @@ class IntroduceGraph(GraphScene):
|
||||
self.remove(planar_explanation)
|
||||
self.add(not_okay)
|
||||
self.remove(*edges_to_remove)
|
||||
self.animate(ShowCreation(
|
||||
self.play(ShowCreation(
|
||||
CompoundMobject(*edges_to_remove),
|
||||
alpha_func = lambda t : 1 - t,
|
||||
run_time = 1.0
|
||||
@@ -164,7 +164,7 @@ class OldIntroduceGraphs(GraphScene):
|
||||
self.replace_vertices_with(Face().scale(0.4))
|
||||
friends = text_mobject("Friends").scale(EDGE_ANNOTATION_SCALE_VAL)
|
||||
self.annotate_edges(friends.shift((0, friends.get_height()/2, 0)))
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(vertex, Dot(point))
|
||||
for vertex, point in zip(self.vertices, self.points)
|
||||
]+[
|
||||
@@ -195,7 +195,7 @@ class PlanarGraphDefinition(Scene):
|
||||
|
||||
self.add(quote, planar, end_quote)
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
FadeOut(quote),
|
||||
FadeOut(end_quote),
|
||||
ApplyMethod(planar.shift, shift_val),
|
||||
@@ -238,26 +238,26 @@ class TerminologyFromPolyhedra(GraphScene):
|
||||
regions_to_faces = text_mobject("Regions $\\to$ Faces").to_corner()
|
||||
|
||||
self.clear()
|
||||
# self.animate(TransformAnimations(
|
||||
# self.play(TransformAnimations(
|
||||
# Rotating(Dodecahedron(), **rot_kwargs),
|
||||
# Rotating(cube, **rot_kwargs)
|
||||
# ))
|
||||
self.animate(Rotating(cube, **rot_kwargs))
|
||||
self.play(Rotating(cube, **rot_kwargs))
|
||||
self.clear()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(l1, l2)
|
||||
for l1, l2 in zip(cube.split(), self.edges)
|
||||
])
|
||||
self.dither()
|
||||
self.add(dots_to_vertices)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(dot, run_time = 1.0)
|
||||
for dot in self.vertices
|
||||
])
|
||||
self.dither(2)
|
||||
self.remove(dots_to_vertices, *self.vertices)
|
||||
self.add(lines_to_edges)
|
||||
self.animate(ApplyMethod(
|
||||
self.play(ApplyMethod(
|
||||
CompoundMobject(*self.edges).highlight, "yellow"
|
||||
))
|
||||
self.dither(2)
|
||||
@@ -295,7 +295,7 @@ class ThreePiecesOfTerminology(GraphScene):
|
||||
self.remove(self.traced_cycle)
|
||||
|
||||
self.add(accent(spanning_trees))
|
||||
self.animate(ShowCreation(self.spanning_tree), run_time = 1.0)
|
||||
self.play(ShowCreation(self.spanning_tree), run_time = 1.0)
|
||||
self.dither()
|
||||
tone_down(spanning_trees)
|
||||
self.remove(self.spanning_tree)
|
||||
@@ -304,14 +304,14 @@ class ThreePiecesOfTerminology(GraphScene):
|
||||
self.generate_dual_graph()
|
||||
for mob in self.mobjects:
|
||||
mob.fade
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(mob, run_time = 1.0)
|
||||
for mob in self.dual_vertices + self.dual_edges
|
||||
])
|
||||
self.dither()
|
||||
|
||||
self.clear()
|
||||
self.animate(ApplyMethod(
|
||||
self.play(ApplyMethod(
|
||||
CompoundMobject(*terms).center
|
||||
))
|
||||
self.dither()
|
||||
@@ -335,7 +335,7 @@ class WalkingRandolph(GraphScene):
|
||||
randy.scale(RANDOLPH_SCALE_VAL)
|
||||
randy.move_to(point_path[0])
|
||||
for next, last in zip(point_path[1:], point_path):
|
||||
self.animate(
|
||||
self.play(
|
||||
WalkPiCreature(randy, next),
|
||||
ShowCreation(Line(last, next).highlight("yellow")),
|
||||
run_time = 2.0
|
||||
@@ -378,13 +378,13 @@ class PathExamples(GraphScene):
|
||||
|
||||
self.remove(not_a_path)
|
||||
self.add(valid_path)
|
||||
self.animate(ShowCreation(path_lines, **kwargs))
|
||||
self.play(ShowCreation(path_lines, **kwargs))
|
||||
self.dither(2)
|
||||
self.remove(path_lines)
|
||||
|
||||
self.remove(valid_path)
|
||||
self.add(not_a_path)
|
||||
self.animate(ShowCreation(non_path_lines, **kwargs))
|
||||
self.play(ShowCreation(non_path_lines, **kwargs))
|
||||
self.dither(2)
|
||||
self.remove(non_path_lines)
|
||||
|
||||
@@ -414,7 +414,7 @@ class IntroduceRandolph(GraphScene):
|
||||
GraphScene.construct(self)
|
||||
randy = Randolph().move_to((-3, 0, 0))
|
||||
name = text_mobject("Randolph")
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
randy,
|
||||
deepcopy(randy).scale(RANDOLPH_SCALE_VAL).move_to(self.points[0]),
|
||||
))
|
||||
@@ -454,19 +454,19 @@ class DefineSpanningTree(GraphScene):
|
||||
self.dither(2)
|
||||
self.remove(dollar_signs)
|
||||
run_time_per_branch = 0.5
|
||||
self.animate(
|
||||
self.play(
|
||||
ShowCreation(green_dot_at_index(0)),
|
||||
run_time = run_time_per_branch
|
||||
)
|
||||
for pair in self.spanning_tree_index_pairs:
|
||||
self.animate(ShowCreation(
|
||||
self.play(ShowCreation(
|
||||
Line(
|
||||
self.points[pair[0]],
|
||||
self.points[pair[1]]
|
||||
).highlight("yellow"),
|
||||
run_time = run_time_per_branch
|
||||
))
|
||||
self.animate(ShowCreation(
|
||||
self.play(ShowCreation(
|
||||
green_dot_at_index(pair[1]),
|
||||
run_time = run_time_per_branch
|
||||
))
|
||||
@@ -476,7 +476,7 @@ class DefineSpanningTree(GraphScene):
|
||||
for edge, limit in zip(unneeded_edges, range(5)):
|
||||
line = Line(self.points[edge[0]], self.points[edge[1]])
|
||||
line.highlight("red")
|
||||
self.animate(ShowCreation(line, run_time = 1.0))
|
||||
self.play(ShowCreation(line, run_time = 1.0))
|
||||
self.add(unneeded.center().shift(line.get_center() + 0.2*UP))
|
||||
self.dither()
|
||||
self.remove(line, unneeded)
|
||||
@@ -493,19 +493,19 @@ class NamingTree(GraphScene):
|
||||
spanning_tree = text_mobject("``Spanning Tree''").to_edge(UP)
|
||||
|
||||
self.add(*branches)
|
||||
self.animate(
|
||||
self.play(
|
||||
FadeOut(CompoundMobject(*self.edges + self.vertices)),
|
||||
Animation(CompoundMobject(*branches)),
|
||||
)
|
||||
self.clear()
|
||||
self.add(tree, *branches)
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(b1, b2, run_time = 2)
|
||||
for b1, b2 in zip(branches, treeified_branches)
|
||||
])
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
FadeIn(mob)
|
||||
for mob in self.edges + self.vertices
|
||||
] + [
|
||||
@@ -522,7 +522,7 @@ class DualGraph(GraphScene):
|
||||
GraphScene.construct(self)
|
||||
self.generate_dual_graph()
|
||||
self.add(text_mobject("Dual Graph").to_edge(UP).shift(2*LEFT))
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(mob)
|
||||
for mob in self.dual_edges + self.dual_vertices
|
||||
])
|
||||
@@ -557,12 +557,12 @@ class FacebookGraph(GraphScene):
|
||||
self.dither()
|
||||
self.annotate_edges(friends)
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(account, vertex)
|
||||
for account, vertex in zip(accounts, self.vertices)
|
||||
])
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(ann, edge)
|
||||
for ann, edge in zip(self.edge_annotations, self.edges)
|
||||
])
|
||||
@@ -607,7 +607,7 @@ class FacebookGraphAsAbstractSet(Scene):
|
||||
self.add(accounts, friendships, lines)
|
||||
self.dither()
|
||||
for mob in names_mob, friends_mob:
|
||||
self.animate(ShowCreation(
|
||||
self.play(ShowCreation(
|
||||
mob, run_time = 1.0
|
||||
))
|
||||
self.dither()
|
||||
@@ -690,10 +690,10 @@ class ExamplesOfGraphs(GraphScene):
|
||||
comp_words = CompoundMobject(*words)
|
||||
comp_lines = CompoundMobject(*lines)
|
||||
self.add(words1)
|
||||
self.animate(ShowCreation(comp_words, run_time = 1.0))
|
||||
self.play(ShowCreation(comp_words, run_time = 1.0))
|
||||
self.dither()
|
||||
self.add(words2)
|
||||
self.animate(ShowCreation(comp_lines, run_time = 1.0))
|
||||
self.play(ShowCreation(comp_lines, run_time = 1.0))
|
||||
self.dither()
|
||||
self.remove(comp_words, comp_lines)
|
||||
|
||||
@@ -708,7 +708,7 @@ class ExamplesOfGraphs(GraphScene):
|
||||
for mob in connected, not_connected:
|
||||
mob.shift(self.points[3] + UP)
|
||||
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(mob, run_time = 1.0)
|
||||
for mob in self.edges + self.vertices
|
||||
])
|
||||
@@ -745,7 +745,7 @@ class ExamplesOfGraphs(GraphScene):
|
||||
tup = tuple(reversed(tup))
|
||||
edge = deepcopy(self.edges[self.graph.edges.index(tup)])
|
||||
edge.highlight("red")
|
||||
self.animate(ShowCreation(edge), run_time = 1.0)
|
||||
self.play(ShowCreation(edge), run_time = 1.0)
|
||||
self.dither()
|
||||
self.remove(edge)
|
||||
else:
|
||||
@@ -787,19 +787,19 @@ class DrawDualGraph(GraphScene):
|
||||
self.dither()
|
||||
self.reset_background()
|
||||
self.highlight_region(outer_region, outer_region_mob.get_color())
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(reg_mob, dot)
|
||||
for reg_mob, dot in zip(region_mobs, self.dual_vertices)
|
||||
])
|
||||
self.dither()
|
||||
self.reset_background()
|
||||
self.animate(ApplyFunction(
|
||||
self.play(ApplyFunction(
|
||||
lambda p : (SPACE_WIDTH + SPACE_HEIGHT)*p/np.linalg.norm(p),
|
||||
outer_region_mob
|
||||
))
|
||||
self.dither()
|
||||
for edges in internal_edges, external_edges:
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(edge, run_time = 2.0)
|
||||
for edge in edges
|
||||
])
|
||||
@@ -812,7 +812,7 @@ class EdgesAreTheSame(GraphScene):
|
||||
self.remove(*self.vertices)
|
||||
self.add(*self.dual_edges)
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*pair, run_time = 2.0)
|
||||
for pair in zip(self.dual_edges, self.edges)
|
||||
])
|
||||
@@ -880,7 +880,7 @@ class CyclesCorrespondWithConnectedComponents(GraphScene):
|
||||
for last, next in zip(cycle, cycle[1:]):
|
||||
line = Line(self.points[last], self.points[next])
|
||||
line.highlight("yellow")
|
||||
self.animate(
|
||||
self.play(
|
||||
ShowCreation(line),
|
||||
WalkPiCreature(randy, self.points[next]),
|
||||
run_time = 1.0
|
||||
@@ -896,8 +896,8 @@ class CyclesCorrespondWithConnectedComponents(GraphScene):
|
||||
Line(self.dual_points[last], self.dual_points[next])
|
||||
for last, next in zip(dual_cycle, dual_cycle[1:])
|
||||
]).highlight("red")
|
||||
self.animate(ShowCreation(lines))
|
||||
self.animate(*[
|
||||
self.play(ShowCreation(lines))
|
||||
self.play(*[
|
||||
Transform(v, Dot(
|
||||
v.get_center(),
|
||||
radius = 3*Dot.DEFAULT_RADIUS
|
||||
@@ -937,7 +937,7 @@ class IntroduceMortimer(GraphScene):
|
||||
small_morty = deepcopy(morty).scale(RANDOLPH_SCALE_VAL)
|
||||
small_randy.move_to(self.points[randy_path[0]])
|
||||
small_morty.move_to(self.dual_points[morty_path[0]])
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
FadeIn(mob)
|
||||
for mob in self.vertices + self.edges
|
||||
] + [
|
||||
@@ -949,19 +949,19 @@ class IntroduceMortimer(GraphScene):
|
||||
|
||||
self.highlight_region(self.regions[morty_path[0]])
|
||||
for last, next in zip(morty_path, morty_path[1:]):
|
||||
self.animate(WalkPiCreature(morty, self.dual_points[next]),**kwargs)
|
||||
self.play(WalkPiCreature(morty, self.dual_points[next]),**kwargs)
|
||||
self.highlight_region(self.regions[next])
|
||||
self.dither()
|
||||
for last, next in zip(randy_path, randy_path[1:]):
|
||||
line = Line(self.points[last], self.points[next])
|
||||
line.highlight("yellow")
|
||||
self.animate(
|
||||
self.play(
|
||||
WalkPiCreature(randy, self.points[next]),
|
||||
ShowCreation(line),
|
||||
**kwargs
|
||||
)
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyMethod(
|
||||
line.rotate_in_place,
|
||||
np.pi/10,
|
||||
@@ -988,9 +988,9 @@ class RandolphMortimerSpanningTreeGame(GraphScene):
|
||||
time_per_dual_edge = 0.5
|
||||
|
||||
self.add(randy, morty)
|
||||
self.animate(ShowCreation(self.spanning_tree))
|
||||
self.play(ShowCreation(self.spanning_tree))
|
||||
self.dither()
|
||||
self.animate(WalkPiCreature(
|
||||
self.play(WalkPiCreature(
|
||||
morty, self.dual_points[attempted_dual_point_index],
|
||||
alpha_func = lambda t : 0.3 * there_and_back(t),
|
||||
run_time = 2.0,
|
||||
@@ -1000,7 +1000,7 @@ class RandolphMortimerSpanningTreeGame(GraphScene):
|
||||
# if index > 0:
|
||||
# edge = self.edges[dual_edges[index-1]]
|
||||
# midpoint = edge.get_center()
|
||||
# self.animate(*[
|
||||
# self.play(*[
|
||||
# ShowCreation(Line(
|
||||
# midpoint,
|
||||
# tip
|
||||
@@ -1015,7 +1015,7 @@ class RandolphMortimerSpanningTreeGame(GraphScene):
|
||||
cycle_index = region_ordering[-1]
|
||||
cycle = self.graph.region_cycles[cycle_index]
|
||||
self.highlight_region(self.regions[cycle_index], "black")
|
||||
self.animate(ShowCreation(CompoundMobject(*[
|
||||
self.play(ShowCreation(CompoundMobject(*[
|
||||
Line(self.points[last], self.points[next]).highlight("green")
|
||||
for last, next in zip(cycle, list(cycle)[1:] + [cycle[0]])
|
||||
])))
|
||||
@@ -1043,7 +1043,7 @@ class MortimerCannotTraverseCycle(GraphScene):
|
||||
for last, next in zip(dual_cycle, dual_cycle[1:]):
|
||||
line = Line(self.dual_points[last], self.dual_points[next])
|
||||
line.highlight("red")
|
||||
self.animate(
|
||||
self.play(
|
||||
WalkPiCreature(morty, self.dual_points[next], **kwargs),
|
||||
ShowCreation(line, **kwargs),
|
||||
)
|
||||
@@ -1056,7 +1056,7 @@ class MortimerCannotTraverseCycle(GraphScene):
|
||||
matching_edges.append(
|
||||
self.edges[distances.index(min(distances))]
|
||||
)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(v, Dot(
|
||||
v.get_center(),
|
||||
radius = 3*Dot.DEFAULT_RADIUS,
|
||||
@@ -1065,7 +1065,7 @@ class MortimerCannotTraverseCycle(GraphScene):
|
||||
for v in np.array(self.vertices)[trapped_points]
|
||||
])
|
||||
self.add(text)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(line, deepcopy(edge).highlight(line.get_color()))
|
||||
for line, edge in zip(all_lines, matching_edges)
|
||||
])
|
||||
@@ -1095,7 +1095,7 @@ class TwoPropertiesOfSpanningTree(Scene):
|
||||
explanation.get_center() + vect,
|
||||
tail = word.get_center() - vect,
|
||||
))
|
||||
self.animate(ApplyMethod(word.highlight, "yellow"))
|
||||
self.play(ApplyMethod(word.highlight, "yellow"))
|
||||
self.dither()
|
||||
|
||||
|
||||
@@ -1116,7 +1116,7 @@ class DualSpanningTree(GraphScene):
|
||||
""").to_edge(UP)
|
||||
|
||||
self.add(self.spanning_tree, randy, morty)
|
||||
self.animate(ShowCreation(CompoundMobject(
|
||||
self.play(ShowCreation(CompoundMobject(
|
||||
*np.array(self.edges)[dual_edges]
|
||||
).highlight("red")))
|
||||
self.add(words)
|
||||
@@ -1136,7 +1136,7 @@ class TreeCountFormula(Scene):
|
||||
all_dots = [Dot(branches[0].points[0])]
|
||||
self.add(text, all_dots[0])
|
||||
for branch in branches:
|
||||
self.animate(
|
||||
self.play(
|
||||
ShowCreation(branch),
|
||||
run_time = time_per_branch
|
||||
)
|
||||
@@ -1145,7 +1145,7 @@ class TreeCountFormula(Scene):
|
||||
all_dots.append(dot)
|
||||
self.dither()
|
||||
self.remove(*all_dots)
|
||||
self.animate(
|
||||
self.play(
|
||||
FadeOut(text),
|
||||
FadeIn(CompoundMobject(*gs.edges + gs.vertices)),
|
||||
*[
|
||||
@@ -1178,7 +1178,7 @@ class FinalSum(Scene):
|
||||
copy.scale_in_place(lines[index].get_width()/mob.get_width())
|
||||
anims.append(CounterclockwiseTransform(copy, mob))
|
||||
self.clear()
|
||||
self.animate(*anims, run_time = 2.0)
|
||||
self.play(*anims, run_time = 2.0)
|
||||
self.dither()
|
||||
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class LogoGeneration(Scene):
|
||||
name.highlight("grey")
|
||||
name.shift(2*DOWN)
|
||||
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
circle, iris,
|
||||
run_time = DEFAULT_ANIMATION_RUN_TIME
|
||||
))
|
||||
|
||||
@@ -15,7 +15,7 @@ from region import *
|
||||
from scene import Scene, RearrangeEquation
|
||||
from script_wrapper import command_line_create_scene
|
||||
|
||||
from inventing_math_images import *
|
||||
# from inventing_math_images import *
|
||||
|
||||
MOVIE_PREFIX = "inventing_math/"
|
||||
DIVERGENT_SUM_TEXT = [
|
||||
@@ -191,7 +191,7 @@ class IntroduceDivergentSum(Scene):
|
||||
**kwargs
|
||||
)
|
||||
self.add(ellipses)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(brace, end_brace, **kwargs),
|
||||
flip_through,
|
||||
)
|
||||
@@ -220,17 +220,17 @@ class ClearlyNonsense(Scene):
|
||||
this_way.highlight("yellow")
|
||||
right_arrow.highlight("yellow")
|
||||
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
div_sum,
|
||||
deepcopy(div_sum).scale(0.5).shift(3*UP)
|
||||
))
|
||||
self.animate(ShowCreation(number_line))
|
||||
self.play(ShowCreation(number_line))
|
||||
self.dither()
|
||||
self.add(how_here)
|
||||
self.animate(ShowCreation(neg_1_arrow))
|
||||
self.play(ShowCreation(neg_1_arrow))
|
||||
self.dither()
|
||||
self.add(this_way)
|
||||
self.animate(ShowCreation(right_arrow))
|
||||
self.play(ShowCreation(right_arrow))
|
||||
self.dither()
|
||||
|
||||
class OutlineOfVideo(Scene):
|
||||
@@ -280,7 +280,7 @@ class OutlineOfVideo(Scene):
|
||||
[texts[3]]
|
||||
]
|
||||
for group in groups:
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
DelayByOrder(FadeIn(element))
|
||||
for element in group
|
||||
])
|
||||
@@ -309,7 +309,7 @@ class OutlineOfVideo(Scene):
|
||||
# # div_sum = divergent_sum().scale(0.5).shift(3*UP)
|
||||
|
||||
# # self.add(div_sum)
|
||||
# # self.animate(
|
||||
# # self.play(
|
||||
# # ApplyMethod(div_sum.replace, equation),
|
||||
# # FadeIn(line_one_first),
|
||||
# # FadeIn(line_one_last)
|
||||
@@ -333,9 +333,9 @@ class OutlineOfVideo(Scene):
|
||||
# define_parts[1].highlight("skyblue")
|
||||
|
||||
# self.add(sum_mob)
|
||||
# self.animate(FadeIn(discover))
|
||||
# self.play(FadeIn(discover))
|
||||
# self.dither()
|
||||
# self.animate(FadeIn(CompoundMobject(*define_parts)))
|
||||
# self.play(FadeIn(CompoundMobject(*define_parts)))
|
||||
# self.dither()
|
||||
|
||||
class YouAsMathematician(Scene):
|
||||
@@ -359,16 +359,16 @@ class YouAsMathematician(Scene):
|
||||
for x in LEFT, RIGHT
|
||||
]
|
||||
self.add(you, explanation)
|
||||
self.animate(
|
||||
self.play(
|
||||
ShowCreation(arrow),
|
||||
BlinkPiCreature(you)
|
||||
)
|
||||
self.dither()
|
||||
self.animate(ShowCreation(bubble))
|
||||
self.play(ShowCreation(bubble))
|
||||
for part in equation_parts:
|
||||
self.animate(DelayByOrder(FadeIn(part)), run_time = 0.5)
|
||||
self.play(DelayByOrder(FadeIn(part)), run_time = 0.5)
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
BlinkPiCreature(you),
|
||||
FadeOut(explanation),
|
||||
FadeOut(arrow)
|
||||
@@ -376,19 +376,19 @@ class YouAsMathematician(Scene):
|
||||
self.remove(bubble, *equation_parts)
|
||||
self.disapproving_friend()
|
||||
self.add(bubble, equation)
|
||||
self.animate(Transform(equation, CompoundMobject(*dot_pair)))
|
||||
self.play(Transform(equation, CompoundMobject(*dot_pair)))
|
||||
self.remove(equation)
|
||||
self.add(*dot_pair)
|
||||
two_arrows = [
|
||||
Arrow(x, direction = x).shift(UP).nudge()
|
||||
for x in LEFT, RIGHT
|
||||
]
|
||||
self.animate(*[ShowCreation(a) for a in two_arrows])
|
||||
self.animate(BlinkPiCreature(you))
|
||||
self.play(*[ShowCreation(a) for a in two_arrows])
|
||||
self.play(BlinkPiCreature(you))
|
||||
self.remove(*dot_pair+two_arrows)
|
||||
everything = CompoundMobject(*self.mobjects)
|
||||
self.clear()
|
||||
self.animate(
|
||||
self.play(
|
||||
ApplyPointwiseFunction(
|
||||
lambda p : 3*SPACE_WIDTH*p/np.linalg.norm(p),
|
||||
everything
|
||||
@@ -408,7 +408,7 @@ class YouAsMathematician(Scene):
|
||||
bubble.content.sort_points(lambda p : np.dot(p, DOWN+RIGHT))
|
||||
|
||||
self.add(friend, bubble)
|
||||
self.animate(DelayByOrder(FadeIn(bubble.content)))
|
||||
self.play(DelayByOrder(FadeIn(bubble.content)))
|
||||
self.dither()
|
||||
self.remove(friend, bubble, bubble.content)
|
||||
|
||||
@@ -423,7 +423,7 @@ class DotsGettingCloser(Scene):
|
||||
self.dither()
|
||||
for x in range(10):
|
||||
distance = min(dots[1].points[:,0])-max(dots[0].points[:,0])
|
||||
self.animate(ApplyMethod(dots[0].shift, 0.5*distance*RIGHT))
|
||||
self.play(ApplyMethod(dots[0].shift, 0.5*distance*RIGHT))
|
||||
|
||||
|
||||
class ZoomInOnInterval(Scene):
|
||||
@@ -441,10 +441,10 @@ class ZoomInOnInterval(Scene):
|
||||
|
||||
self.add(number_line)
|
||||
self.dither()
|
||||
self.animate(Transform(number_line, new_line))
|
||||
self.play(Transform(number_line, new_line))
|
||||
self.clear()
|
||||
squish = lambda p : (p[0], 0, 0)
|
||||
self.animate(
|
||||
self.play(
|
||||
ApplyMethod(new_line.apply_function, squish),
|
||||
ApplyMethod(
|
||||
interval[0].apply_function, squish,
|
||||
@@ -476,7 +476,7 @@ class DanceDotOnInterval(Scene):
|
||||
conv_sum = tex_mobject(sum_terms, size = "\\large").split()
|
||||
|
||||
self.add(interval)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyMethod(dot.shift, DOWN)
|
||||
for dot in dots
|
||||
])
|
||||
@@ -486,7 +486,7 @@ class DanceDotOnInterval(Scene):
|
||||
start = dots[0].get_center()
|
||||
line = Line(start, start + shift_val*RIGHT)
|
||||
line.highlight(color_range.next())
|
||||
self.animate(
|
||||
self.play(
|
||||
ApplyMethod(dots[0].shift, shift_val),
|
||||
ShowCreation(line)
|
||||
)
|
||||
@@ -500,7 +500,7 @@ class DanceDotOnInterval(Scene):
|
||||
line.get_center()+2*DOWN,
|
||||
tail = num.get_center()+0.5*num.get_height()*UP
|
||||
)
|
||||
self.animate(
|
||||
self.play(
|
||||
ApplyMethod(line.shift, 2*DOWN),
|
||||
FadeIn(num),
|
||||
FadeIn(arrow),
|
||||
@@ -517,7 +517,7 @@ class DanceDotOnInterval(Scene):
|
||||
|
||||
for x in range(0, len(partial_sum_parts), 4):
|
||||
partial_sum_parts[x+2].highlight("yellow")
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
FadeIn(partial_sum_parts[y])
|
||||
for y in range(x, x+4)
|
||||
])
|
||||
@@ -541,7 +541,7 @@ class OrganizePartialSums(Scene):
|
||||
|
||||
self.add(*partial_sum_parts)
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ClockwiseTransform(*pair)
|
||||
for pair in zip(pure_sums, new_pure_sums)
|
||||
]+[
|
||||
@@ -557,9 +557,9 @@ class OrganizePartialSums(Scene):
|
||||
infinite_sum.scale(1.5/1.25)
|
||||
infinite_sum.to_corner(DOWN+LEFT).shift(2*RIGHT)
|
||||
|
||||
self.animate(ShowCreation(dots))
|
||||
self.play(ShowCreation(dots))
|
||||
self.dither()
|
||||
self.animate(FadeIn(CompoundMobject(down_arrow, infinite_sum)))
|
||||
self.play(FadeIn(CompoundMobject(down_arrow, infinite_sum)))
|
||||
self.dither()
|
||||
|
||||
class SeeNumbersApproachOne(Scene):
|
||||
@@ -580,7 +580,7 @@ class SeeNumbersApproachOne(Scene):
|
||||
])
|
||||
|
||||
self.add(interval)
|
||||
self.animate(
|
||||
self.play(
|
||||
ShowCreation(arrow),
|
||||
ShowCreation(dots),
|
||||
run_time = 2.0
|
||||
@@ -598,7 +598,7 @@ class OneAndInfiniteSumAreTheSameThing(Scene):
|
||||
self.dither()
|
||||
self.add(inf_sum.shift(RIGHT))
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
ApplyMethod(one.shift, RIGHT),
|
||||
ApplyMethod(inf_sum.shift, LEFT),
|
||||
CounterclockwiseTransform(point, equals)
|
||||
@@ -623,7 +623,7 @@ class HowDoYouDefineInfiniteSums(Scene):
|
||||
for mob in text[:-1]:
|
||||
self.add(mob)
|
||||
self.dither(0.1)
|
||||
self.animate(BlinkPiCreature(you))
|
||||
self.play(BlinkPiCreature(you))
|
||||
self.dither()
|
||||
self.add(text[-1])
|
||||
self.dither()
|
||||
@@ -650,8 +650,8 @@ class LessAboutNewThoughts(Scene):
|
||||
kwargs = {"run_time" : 0.25}
|
||||
self.add(*words)
|
||||
self.dither()
|
||||
self.animate(ShowCreation(gen_cross, **kwargs))
|
||||
self.animate(ShowCreation(new_cross, **kwargs))
|
||||
self.play(ShowCreation(gen_cross, **kwargs))
|
||||
self.play(ShowCreation(new_cross, **kwargs))
|
||||
self.dither()
|
||||
self.add(disecting)
|
||||
self.dither(0.5)
|
||||
@@ -679,9 +679,9 @@ class ListOfPartialSums(Scene):
|
||||
display_numbers = False,
|
||||
run_time = 1.0
|
||||
)
|
||||
self.animate(ShowCreation(dots))
|
||||
self.play(ShowCreation(dots))
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
FadeIn(CompoundMobject(*equals)),
|
||||
*[
|
||||
Transform(deepcopy(number), finite_sum)
|
||||
@@ -689,7 +689,7 @@ class ListOfPartialSums(Scene):
|
||||
]
|
||||
)
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyMethod(s.highlight, "yellow", alpha_func = there_and_back)
|
||||
for s in sums
|
||||
])
|
||||
@@ -720,7 +720,7 @@ class ShowDecreasingDistance(Scene):
|
||||
self.add(dots.split()[0])
|
||||
self.add(number_line, *lines)
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
ApplyMethod(vert_line0.shift, RIGHT),
|
||||
Transform(
|
||||
horiz_line,
|
||||
@@ -753,19 +753,19 @@ class CircleZoomInOnOne(Scene):
|
||||
arrow = Arrow(2*RIGHT, direction = 1.5*(DOWN+RIGHT)).nudge()
|
||||
|
||||
self.add(number_line, dots)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(circle, Point(2*RIGHT).highlight("white")),
|
||||
run_time = 5.0
|
||||
)
|
||||
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
DelayByOrder(FadeIn(mob))
|
||||
for mob in arrow, curr_num
|
||||
])
|
||||
self.dither()
|
||||
for num in numbers[1:] + [text]:
|
||||
curr_num.points = np.array(list(reversed(curr_num.points)))
|
||||
self.animate(
|
||||
self.play(
|
||||
ShowCreation(
|
||||
curr_num,
|
||||
alpha_func = lambda t : smooth(1-t)
|
||||
@@ -782,12 +782,12 @@ class ZoomInOnOne(Scene):
|
||||
number_line = NumberLine(interval_size = 1, radius = SPACE_WIDTH+2)
|
||||
number_line.filter_out(lambda (x, y, z):abs(y)>0.1)
|
||||
nl_with_nums = deepcopy(number_line).add_numbers()
|
||||
self.animate(ApplyMethod(nl_with_nums.shift, 2*LEFT))
|
||||
self.play(ApplyMethod(nl_with_nums.shift, 2*LEFT))
|
||||
zero, one, two = [
|
||||
tex_mobject(str(n)).scale(0.5).shift(0.4*DOWN+2*(-1+n)*RIGHT)
|
||||
for n in 0, 1, 2
|
||||
]
|
||||
self.animate(
|
||||
self.play(
|
||||
FadeOut(nl_with_nums),
|
||||
*[Animation(mob) for mob in zero, one, two, number_line]
|
||||
)
|
||||
@@ -817,7 +817,7 @@ class ZoomInOnOne(Scene):
|
||||
for x in range(num_levels)
|
||||
]
|
||||
kwargs = {"alpha_func" : None}
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyMethod(number_lines[x].scale, scale_val, **kwargs)
|
||||
for x in range(1, num_levels)
|
||||
]+[
|
||||
@@ -853,7 +853,7 @@ class DefineInfiniteSum(Scene):
|
||||
|
||||
self.add(expression)
|
||||
self.dither()
|
||||
self.animate(ApplyFunction(
|
||||
self.play(ApplyFunction(
|
||||
lambda mob : mob.scale(0.5).to_corner(UP+LEFT, buff = buff),
|
||||
expression
|
||||
))
|
||||
@@ -863,7 +863,7 @@ class DefineInfiniteSum(Scene):
|
||||
Line(SPACE_WIDTH*LEFT+bottom, side+bottom),
|
||||
Line(SPACE_HEIGHT*UP+side, side+bottom)
|
||||
]
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(line.highlight("white"))
|
||||
for line in lines
|
||||
])
|
||||
@@ -893,7 +893,7 @@ class DefineInfiniteSum(Scene):
|
||||
self.dither()
|
||||
esses = np.array(terms)[range(0, len(terms), 3)]
|
||||
other_terms = filter(lambda m : m not in esses, terms)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyMethod(ess.highlight, "yellow")
|
||||
for ess in esses
|
||||
])
|
||||
@@ -903,7 +903,7 @@ class DefineInfiniteSum(Scene):
|
||||
s.scale(1.0/(n+1))
|
||||
s.shift(ex_point-RIGHT*2.0/2**n)
|
||||
return s
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
FadeOut(term)
|
||||
for term in other_terms
|
||||
]+[
|
||||
@@ -920,7 +920,7 @@ class DefineInfiniteSum(Scene):
|
||||
for y in [-1, -0.01, 1, 0.01]
|
||||
for x in [ex_point+y*RIGHT]
|
||||
]
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(lines[x], lines[x+1], run_time = 3.0)
|
||||
for x in 0, 2
|
||||
])
|
||||
@@ -944,8 +944,8 @@ class YouJustInventedSomeMath(Scene):
|
||||
for mob in text:
|
||||
self.add(mob)
|
||||
self.dither(0.2)
|
||||
self.animate(WaveArm(you))
|
||||
self.animate(BlinkPiCreature(you))
|
||||
self.play(WaveArm(you))
|
||||
self.play(BlinkPiCreature(you))
|
||||
|
||||
|
||||
|
||||
@@ -968,7 +968,7 @@ class SeekMoreGeneralTruths(Scene):
|
||||
|
||||
for qsum in sums.split():
|
||||
qsum.sort_points(lambda p : np.dot(p, DOWN+RIGHT))
|
||||
self.animate(DelayByOrder(FadeIn(qsum)))
|
||||
self.play(DelayByOrder(FadeIn(qsum)))
|
||||
self.dither(0.5)
|
||||
self.dither()
|
||||
|
||||
@@ -1036,7 +1036,7 @@ class ChopIntervalInProportions(Scene):
|
||||
new_term_to_replace = deepcopy(term_to_replace)
|
||||
new_term_to_replace.center().shift(last+UP+0.3*LEFT)
|
||||
left_paren.center().shift(last+1.1*UP)
|
||||
self.animate(
|
||||
self.play(
|
||||
FadeIn(lt[1]),
|
||||
FadeIn(rt[0]),
|
||||
Transform(
|
||||
@@ -1049,7 +1049,7 @@ class ChopIntervalInProportions(Scene):
|
||||
*additional_anims
|
||||
)
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(
|
||||
term_to_replace,
|
||||
CompoundMobject(lt[0], rt[1])
|
||||
@@ -1059,7 +1059,7 @@ class ChopIntervalInProportions(Scene):
|
||||
)
|
||||
self.remove(left_paren, right_paren)
|
||||
else:
|
||||
self.animate(
|
||||
self.play(
|
||||
FadeIn(lt[1]),
|
||||
FadeIn(rt[0]),
|
||||
Transform(
|
||||
@@ -1076,7 +1076,7 @@ class ChopIntervalInProportions(Scene):
|
||||
lt, rt = CompoundMobject(*lt), CompoundMobject(*rt)
|
||||
self.add(lt, rt)
|
||||
else:
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(
|
||||
brace_to_replace.repeat(2),
|
||||
CompoundMobject(*braces)
|
||||
@@ -1090,7 +1090,7 @@ class ChopIntervalInProportions(Scene):
|
||||
self.remove(brace_to_replace, term_to_replace)
|
||||
self.add(lt, rt, *braces)
|
||||
else:
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
FadeIn(mob)
|
||||
for mob in braces + [lt, rt]
|
||||
] + additional_anims)
|
||||
@@ -1104,7 +1104,7 @@ class ChopIntervalInProportions(Scene):
|
||||
split_100.to_edge(RIGHT)
|
||||
split_100.sort_points()
|
||||
right_terms[-1].sort_points()
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
right_terms[-1], split_100
|
||||
))
|
||||
self.dither()
|
||||
@@ -1225,13 +1225,13 @@ class PlugNumbersIntoRightside(Scene):
|
||||
|
||||
self.add(lhs, *rhs)
|
||||
self.dither()
|
||||
self.animate(FadeIn(right_words))
|
||||
self.play(FadeIn(right_words))
|
||||
curr = rhs[1]
|
||||
for num, count in zip(nums, it.count()):
|
||||
self.animate(CounterclockwiseTransform(curr, num))
|
||||
self.play(CounterclockwiseTransform(curr, num))
|
||||
self.dither()
|
||||
if count == 2:
|
||||
self.animate(FadeIn(left_words))
|
||||
self.play(FadeIn(left_words))
|
||||
|
||||
|
||||
class PlugInNegativeOne(RearrangeEquation):
|
||||
@@ -1327,10 +1327,10 @@ class ListPartialDivergentSums(Scene):
|
||||
arrow = Arrow(3*DOWN+2*LEFT, direction = DOWN, length = 6)
|
||||
|
||||
for x in range(0, len(terms), 2):
|
||||
self.animate(FadeIn(terms[x]), FadeIn(terms[x+1]))
|
||||
self.animate(FadeIn(words), ShowCreation(arrow))
|
||||
self.play(FadeIn(terms[x]), FadeIn(terms[x+1]))
|
||||
self.play(FadeIn(words), ShowCreation(arrow))
|
||||
for x in range(0, len(terms), 2):
|
||||
self.animate(
|
||||
self.play(
|
||||
ApplyMethod(terms[x].highlight, "green"),
|
||||
run_time = 0.1
|
||||
)
|
||||
@@ -1345,8 +1345,8 @@ class NotARobot(Scene):
|
||||
low_words.shift(1.5*DOWN)
|
||||
|
||||
self.add(you)
|
||||
self.animate(ShimmerIn(top_words))
|
||||
self.animate(ShimmerIn(low_words))
|
||||
self.play(ShimmerIn(top_words))
|
||||
self.play(ShimmerIn(low_words))
|
||||
|
||||
|
||||
class SumPowersOfTwoAnimation(Scene):
|
||||
@@ -1412,7 +1412,7 @@ class SumPowersOfTwoAnimation(Scene):
|
||||
new_top_sum_end = new_top_sum[-1]
|
||||
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
FadeIn(mob)
|
||||
for mob in [
|
||||
new_dots,
|
||||
@@ -1423,7 +1423,7 @@ class SumPowersOfTwoAnimation(Scene):
|
||||
]
|
||||
])
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(topbrace, new_topbrace),
|
||||
Transform(alt_topbrace, new_topbrace),
|
||||
Transform(bottombrace, new_bottombrace),
|
||||
@@ -1463,11 +1463,11 @@ class PretendTheyDoApproachNegativeOne(RearrangeEquation):
|
||||
for column in columns:
|
||||
column.shift(shift_val)
|
||||
shift_val = shift_val + (column.get_width()+0.2)*RIGHT
|
||||
self.animate(ShimmerIn(columns[0]))
|
||||
self.play(ShimmerIn(columns[0]))
|
||||
self.dither()
|
||||
self.add(columns[1])
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
DelayByOrder(Transform(deepcopy(columns[0]), columns[-1])),
|
||||
FadeIn(columns[2])
|
||||
)
|
||||
@@ -1488,16 +1488,16 @@ class DistanceBetweenRationalNumbers(Scene):
|
||||
text = text_mobject("How we define distance between rational numbers")
|
||||
text.to_edge(UP)
|
||||
self.add(text, *nums)
|
||||
self.animate(*[ShowCreation(arrow) for arrow in arrows])
|
||||
self.animate(ShimmerIn(dist))
|
||||
self.play(*[ShowCreation(arrow) for arrow in arrows])
|
||||
self.play(ShimmerIn(dist))
|
||||
self.dither()
|
||||
|
||||
class NotTheOnlyWayToOrganize(Scene):
|
||||
def construct(self):
|
||||
self.animate(ShowCreation(NumberLine().add_numbers()))
|
||||
self.play(ShowCreation(NumberLine().add_numbers()))
|
||||
self.dither()
|
||||
words = "Is there any other reasonable way to organize numbers?"
|
||||
self.animate(FadeIn(text_mobject(words).shift(2*UP)))
|
||||
self.play(FadeIn(text_mobject(words).shift(2*UP)))
|
||||
self.dither()
|
||||
|
||||
class DistanceIsAFunction(Scene):
|
||||
@@ -1563,11 +1563,11 @@ class DistanceIsAFunction(Scene):
|
||||
kwargs = {"run_time" : 0.5}
|
||||
for mobs in example_mobs:
|
||||
if previous:
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
DelayByOrder(Transform(prev, mob, **kwargs))
|
||||
for prev, mob in zip(previous, mobs)[:-1]
|
||||
])
|
||||
self.animate(DelayByOrder(Transform(
|
||||
self.play(DelayByOrder(Transform(
|
||||
previous[-1], mobs[-1], **kwargs
|
||||
)))
|
||||
self.remove(*previous)
|
||||
@@ -1595,7 +1595,7 @@ class ShiftInvarianceNumberLine(Scene):
|
||||
self.add(number_line, topbrace, dist0, footnote)
|
||||
self.dither()
|
||||
self.remove(dist0)
|
||||
self.animate(
|
||||
self.play(
|
||||
ApplyMethod(topbrace.shift, 2*RIGHT),
|
||||
*[
|
||||
Transform(*pair)
|
||||
@@ -1624,9 +1624,9 @@ class NameShiftInvarianceProperty(Scene):
|
||||
mob.highlight("yellow")
|
||||
|
||||
self.add(prop)
|
||||
self.animate(ShimmerIn(label), ShimmerIn(u_brace))
|
||||
self.play(ShimmerIn(label), ShimmerIn(u_brace))
|
||||
self.dither()
|
||||
self.animate(ShimmerIn(name))
|
||||
self.play(ShimmerIn(name))
|
||||
self.dither()
|
||||
|
||||
|
||||
@@ -1657,15 +1657,15 @@ class TriangleInequality(Scene):
|
||||
]
|
||||
for symbol, loc in zip(symbols, locations):
|
||||
self.add(tex_mobject(symbol).shift(loc))
|
||||
self.animate(ShowCreation(ac_line), FadeIn(ac_copy))
|
||||
self.play(ShowCreation(ac_line), FadeIn(ac_copy))
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(line) for line in ab_line, bc_line
|
||||
]+[
|
||||
FadeIn(dist) for dist in ab_copy, bc_copy
|
||||
])
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*pair)
|
||||
for pair in zip(all_copies, all_dists)
|
||||
]+[
|
||||
@@ -1696,7 +1696,7 @@ class StruggleToFindFrameOfMind(Scene):
|
||||
bubble.add_content(mob)
|
||||
for first, second in [(curr, questions), (questions, mob)]:
|
||||
copy = deepcopy(first)
|
||||
self.animate(DelayByOrder(Transform(
|
||||
self.play(DelayByOrder(Transform(
|
||||
copy, second, **kwargs
|
||||
)))
|
||||
self.remove(copy)
|
||||
@@ -1732,7 +1732,7 @@ class RoomsAndSubrooms(Scene):
|
||||
for group in rectangle_groups:
|
||||
mob = CompoundMobject(*group)
|
||||
mob.sort_points(np.linalg.norm)
|
||||
self.animate(ShowCreation(mob))
|
||||
self.play(ShowCreation(mob))
|
||||
|
||||
self.dither()
|
||||
|
||||
@@ -1771,7 +1771,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
LEFT*0.05*n+\
|
||||
(0.4*RIGHT if n == 0 else ORIGIN) #Stupid
|
||||
)
|
||||
self.animate(FadeIn(num, run_time = 0.5))
|
||||
self.play(FadeIn(num, run_time = 0.5))
|
||||
nums.append(num)
|
||||
return zero, nums
|
||||
|
||||
@@ -1790,7 +1790,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
rect.highlight(colors[n])
|
||||
rectangles.append(rect)
|
||||
for rect in rectangles:
|
||||
self.animate(ShowCreation(rect))
|
||||
self.play(ShowCreation(rect))
|
||||
self.dither()
|
||||
return rectangles
|
||||
|
||||
@@ -1810,7 +1810,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
)
|
||||
clusters.append(cluster)
|
||||
for rect in cluster[1:]:
|
||||
self.animate(FadeIn(rect, run_time = 0.6**(count-1)))
|
||||
self.play(FadeIn(rect, run_time = 0.6**(count-1)))
|
||||
return clusters
|
||||
|
||||
def adjust_power_mobs(self, zero, power_mobs, small_rects):
|
||||
@@ -1822,7 +1822,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
new_power_mobs[-1].shift(DOWN)
|
||||
dots = tex_mobject("\\vdots")
|
||||
dots.scale(0.5).shift(new_zero.get_center()+0.5*DOWN)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(zero, new_zero),
|
||||
FadeIn(dots),
|
||||
*[
|
||||
@@ -1847,7 +1847,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
self.center_in_closest_rect(mob, small_rects)
|
||||
mob.shift(UP)
|
||||
return mob
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyFunction(transform, mob)
|
||||
for mob in zero_copy, power_mob_copy
|
||||
])
|
||||
@@ -1855,7 +1855,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
for n in range(power+1, 2*power):
|
||||
left_mob = num_mobs[n-power]
|
||||
shift_val = left_mob.get_center()-last_left_mob.get_center()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyMethod(mob.shift, shift_val)
|
||||
for mob in zero_copy, power_mob_copy
|
||||
])
|
||||
@@ -1867,7 +1867,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
num_mobs[n].shift(power_mob_copy.get_center()+DOWN)
|
||||
self.center_in_closest_rect(num_mobs[n], small_rects)
|
||||
point = Point(power_mob_copy.get_center())
|
||||
self.animate(Transform(point, num_mobs[n]))
|
||||
self.play(Transform(point, num_mobs[n]))
|
||||
self.remove(point)
|
||||
self.add(num_mobs[n])
|
||||
last_left_mob = left_mob
|
||||
@@ -1885,7 +1885,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
neg_one = tex_mobject("-1").scale(0.5)
|
||||
shift_val = num_mobs[15].get_center()-neg_one.get_center()
|
||||
neg_one.shift(UP)
|
||||
self.animate(ApplyMethod(neg_one.shift, shift_val))
|
||||
self.play(ApplyMethod(neg_one.shift, shift_val))
|
||||
|
||||
def show_distances(self, num_mobs, rect_clusters):
|
||||
self.remove(*[r for c in rect_clusters for r in c])
|
||||
@@ -1912,7 +1912,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
for pair in sample(pairs, min(10, len(pairs))):
|
||||
for index in pair:
|
||||
num_mobs[index].highlight("green")
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyMethod(
|
||||
num_mobs[index].rotate_in_place, np.pi/10,
|
||||
alpha_func = wiggle
|
||||
@@ -1967,7 +1967,7 @@ class DeduceWhereNegativeOneFalls(Scene):
|
||||
for new_arg, old_arg in zip(new_args, last_args):
|
||||
new_arg.shift(old_arg.get_center())
|
||||
if last_args != [arg0, arg1]:
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
DelayByOrder(Transform(*pair, run_time = 0.5*rest_time))
|
||||
for pair in zip(last_args, new_args)
|
||||
])
|
||||
@@ -2003,7 +2003,7 @@ class OtherRationalNumbers(Scene):
|
||||
]
|
||||
for pair, locus in zip(pairs, locii):
|
||||
fraction = tex_mobject("\\frac{%d}{%d}"%pair).shift(locus)
|
||||
self.animate(ShimmerIn(fraction))
|
||||
self.play(ShimmerIn(fraction))
|
||||
self.dither()
|
||||
|
||||
class PAdicMetric(Scene):
|
||||
@@ -2022,18 +2022,18 @@ class PAdicMetric(Scene):
|
||||
for prime, count in zip(primes, it.count()):
|
||||
prime.scale(1.0).highlight(colors.next())
|
||||
prime.shift(center_of_mass([p_str.get_top(), p_str.get_center()]))
|
||||
self.animate(DelayByOrder(Transform(curr, prime)))
|
||||
self.play(DelayByOrder(Transform(curr, prime)))
|
||||
self.dither()
|
||||
if count == 2:
|
||||
self.spill(CompoundMobject(curr, text), arrow, new_numbers)
|
||||
self.remove(curr)
|
||||
curr = prime
|
||||
self.animate(DelayByOrder(Transform(curr, p_str)))
|
||||
self.play(DelayByOrder(Transform(curr, p_str)))
|
||||
self.dither()
|
||||
|
||||
def spill(self, start, arrow, end):
|
||||
start.sort_points(lambda p : p[1])
|
||||
self.animate(
|
||||
self.play(
|
||||
ShowCreation(
|
||||
arrow,
|
||||
alpha_func = squish_alpha_func(smooth, 0.5, 1.0)
|
||||
@@ -2043,7 +2043,7 @@ class PAdicMetric(Scene):
|
||||
Point(arrow.points[0]).highlight("white")
|
||||
))
|
||||
)
|
||||
self.animate(ShimmerIn(end))
|
||||
self.play(ShimmerIn(end))
|
||||
|
||||
|
||||
class FuzzyDiscoveryToNewMath(Scene):
|
||||
@@ -2098,12 +2098,12 @@ class FuzzyDiscoveryToNewMath(Scene):
|
||||
midpoints.append(count*UP)
|
||||
|
||||
self.add(fuzzy, lines)
|
||||
self.animate(*map(ShimmerIn, fuzzy_discoveries))
|
||||
self.play(*map(ShimmerIn, fuzzy_discoveries))
|
||||
self.dither()
|
||||
self.animate(DelayByOrder(Transform(
|
||||
self.play(DelayByOrder(Transform(
|
||||
deepcopy(fuzzy), new_math
|
||||
)))
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
DelayByOrder(Transform(deepcopy(disc), math))
|
||||
for disc, math in zip(fuzzy_discoveries, new_maths)
|
||||
])
|
||||
@@ -2129,7 +2129,7 @@ class DiscoveryAndInvention(Scene):
|
||||
nrd.get_bottom(),
|
||||
tail = discovery.get_top()
|
||||
)
|
||||
self.animate(
|
||||
self.play(
|
||||
FadeIn(nrd),
|
||||
ShowCreation(arrow)
|
||||
)
|
||||
@@ -2139,14 +2139,14 @@ class DiscoveryAndInvention(Scene):
|
||||
invention.get_top(),
|
||||
tail = nrd.get_bottom()
|
||||
)
|
||||
self.animate(ShowCreation(arrow))
|
||||
self.play(ShowCreation(arrow))
|
||||
arrows.append(arrow)
|
||||
self.dither()
|
||||
arrow = Arrow(
|
||||
rt.get_top(),
|
||||
tail = invention.get_bottom()
|
||||
)
|
||||
self.animate(
|
||||
self.play(
|
||||
FadeIn(rt),
|
||||
ShowCreation(arrow)
|
||||
)
|
||||
@@ -2156,12 +2156,12 @@ class DiscoveryAndInvention(Scene):
|
||||
discovery.get_bottom(),
|
||||
tail = rt.get_top()
|
||||
)
|
||||
self.animate(ShowCreation(arrow))
|
||||
self.play(ShowCreation(arrow))
|
||||
self.dither()
|
||||
arrows.append(arrow)
|
||||
for color in Color("yellow").range_to("red", 4):
|
||||
for arrow in arrows:
|
||||
self.animate(
|
||||
self.play(
|
||||
ShowCreation(deepcopy(arrow).highlight(color)),
|
||||
run_time = 0.25
|
||||
)
|
||||
|
||||
@@ -133,7 +133,7 @@ class CountSections(CircleScene):
|
||||
def __init__(self, *args, **kwargs):
|
||||
CircleScene.__init__(self, *args, **kwargs)
|
||||
self.remove(*self.lines)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(Dot(points[i]),Line(points[i], points[1-i]))
|
||||
for points in it.combinations(self.points, 2)
|
||||
for i in (0, 1)
|
||||
@@ -219,13 +219,13 @@ class HardProblemsSimplerQuestions(Scene):
|
||||
for c in [left_center, right_center]
|
||||
]
|
||||
self.add(fermat["n"])
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(deepcopy(fermat["n"]), f_copy)
|
||||
for f_copy in copies
|
||||
])
|
||||
self.remove(*self.mobjects)
|
||||
self.add(fermat["n"])
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(mobs[0], mobs[1])
|
||||
for f_copy, sym in zip(copies, ["3", "2"])
|
||||
for mobs in zip(f_copy.split(), fermat[sym].split())
|
||||
@@ -257,7 +257,7 @@ class HardProblemsSimplerQuestions(Scene):
|
||||
mob.scale(0.5).shift(left_center + (0, 2, 0))
|
||||
|
||||
self.add(circle_grid, other_grid)
|
||||
self.animate(
|
||||
self.play(
|
||||
FadeIn(fermat2_jargon),
|
||||
FadeIn(fermat3_jargon),
|
||||
CounterclockwiseTransform(start_line, end_line),
|
||||
@@ -266,7 +266,7 @@ class HardProblemsSimplerQuestions(Scene):
|
||||
self.dither()
|
||||
all_mobjects = CompoundMobject(*self.mobjects)
|
||||
self.remove(*self.mobjects)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(
|
||||
all_mobjects,
|
||||
Point((SPACE_WIDTH, 0, 0))
|
||||
@@ -301,7 +301,7 @@ class CountLines(CircleScene):
|
||||
]
|
||||
self.add(text)
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(line1, line2, run_time = 2)
|
||||
for line1, line2 in zip(self.lines, new_lines)
|
||||
])
|
||||
@@ -314,7 +314,7 @@ class CountLines(CircleScene):
|
||||
anims.append(Transform(mob, answer))
|
||||
else:
|
||||
anims.append(FadeOut(mob))
|
||||
self.animate(*anims, run_time = 1)
|
||||
self.play(*anims, run_time = 1)
|
||||
|
||||
class CountIntersectionPoints(CircleScene):
|
||||
def __init__(self, radians, *args, **kwargs):
|
||||
@@ -347,7 +347,7 @@ class CountIntersectionPoints(CircleScene):
|
||||
else:
|
||||
anims.append(FadeOut(mob))
|
||||
anims.append(Animation(formula))
|
||||
self.animate(*anims, run_time = 1)
|
||||
self.play(*anims, run_time = 1)
|
||||
|
||||
class NonGeneralPosition(CircleScene):
|
||||
args_list = []
|
||||
@@ -383,7 +383,7 @@ class NonGeneralPosition(CircleScene):
|
||||
self.dither(2)
|
||||
self.remove(text, arrow)
|
||||
self.reset_background()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(mob1, mob2, run_time = DEFAULT_ANIMATION_RUN_TIME)
|
||||
for mob1, mob2 in zip(self.mobjects, new_self.mobjects)
|
||||
])
|
||||
@@ -430,12 +430,12 @@ class GeneralPositionRule(Scene):
|
||||
for i, j in pairs
|
||||
for line in [Line(cs.points[i], cs.points[j])]
|
||||
]
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(line, run_time = 1.0)
|
||||
for line in intersecting_lines
|
||||
])
|
||||
if first_time:
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
CompoundMobject(*intersecting_lines),
|
||||
words_mob
|
||||
))
|
||||
@@ -465,18 +465,18 @@ class LineCorrespondsWithPair(CircleScene):
|
||||
self.dots.remove(dot0)
|
||||
self.dots.remove(dot1)
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyMethod(mob.fade, 0.2)
|
||||
for mob in self.lines + self.dots
|
||||
])
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(
|
||||
dot, Dot(dot.get_center(), 3*dot.radius),
|
||||
alpha_func = there_and_back
|
||||
)
|
||||
for dot in (dot0, dot1)
|
||||
])
|
||||
self.animate(Transform(line, dot0))
|
||||
self.play(Transform(line, dot0))
|
||||
|
||||
class IllustrateNChooseK(Scene):
|
||||
args_list = [
|
||||
@@ -550,7 +550,7 @@ class IllustrateNChooseK(Scene):
|
||||
self.remove(count_mob)
|
||||
self.remove(tuple_copy)
|
||||
self.add(count_mob)
|
||||
self.animate(FadeIn(CompoundMobject(form1, form2, pronunciation)))
|
||||
self.play(FadeIn(CompoundMobject(form1, form2, pronunciation)))
|
||||
|
||||
class IntersectionPointCorrespondances(CircleScene):
|
||||
args_list = [
|
||||
@@ -602,16 +602,16 @@ class IntersectionPointCorrespondances(CircleScene):
|
||||
fade_outs.append(FadeOut(mob, alpha_func = not_quite_there))
|
||||
|
||||
self.add(intersection_dot_arrow)
|
||||
self.animate(Highlight(intersection_dot))
|
||||
self.play(Highlight(intersection_dot))
|
||||
self.remove(intersection_dot_arrow)
|
||||
self.animate(*fade_outs)
|
||||
self.play(*fade_outs)
|
||||
self.dither()
|
||||
self.add(line_statement)
|
||||
self.animate(*line_highlights)
|
||||
self.play(*line_highlights)
|
||||
self.remove(line_statement)
|
||||
self.dither()
|
||||
self.add(dots_statement, *dot_pointers)
|
||||
self.animate(*dot_highlights)
|
||||
self.play(*dot_highlights)
|
||||
self.remove(dots_statement, *dot_pointers)
|
||||
|
||||
class LinesIntersectOutside(CircleScene):
|
||||
@@ -637,11 +637,11 @@ class LinesIntersectOutside(CircleScene):
|
||||
self.lines[pairs.index((indices[p0], indices[p1]))]
|
||||
for p0, p1 in [(0, 1), (2, 3)]
|
||||
]
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
FadeOut(mob, alpha_func = not_quite_there)
|
||||
for mob in self.mobjects if mob not in lines_to_save
|
||||
])
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(
|
||||
Line(self.points[indices[p0]], self.points[indices[p1]]),
|
||||
Line(self.points[indices[p0]], intersection_point))
|
||||
@@ -665,7 +665,7 @@ class QuadrupletsToIntersections(CircleScene):
|
||||
dot_quad.highlight()
|
||||
self.add(dot_quad)
|
||||
self.dither(frame_time / 3)
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
dot_quad,
|
||||
intersection_dot,
|
||||
run_time = 3*frame_time/2
|
||||
@@ -684,19 +684,19 @@ class GraphsAndEulersFormulaJoke(Scene):
|
||||
)
|
||||
graph.filter_out(lambda (x, y, z) : abs(y) > SPACE_HEIGHT)
|
||||
self.add(axes)
|
||||
self.animate(ShowCreation(graph), run_time = 1.0)
|
||||
self.play(ShowCreation(graph), run_time = 1.0)
|
||||
eulers = tex_mobject("e^{\pi i} = -1").shift((0, 3, 0))
|
||||
self.animate(CounterclockwiseTransform(
|
||||
self.play(CounterclockwiseTransform(
|
||||
deepcopy(graph), eulers
|
||||
))
|
||||
self.dither()
|
||||
self.remove(*self.mobjects)
|
||||
self.add(eulers)
|
||||
self.animate(CounterclockwiseTransform(
|
||||
self.play(CounterclockwiseTransform(
|
||||
CompoundMobject(axes, graph),
|
||||
Point((-SPACE_WIDTH, SPACE_HEIGHT, 0))
|
||||
))
|
||||
self.animate(CounterclockwiseTransform(
|
||||
self.play(CounterclockwiseTransform(
|
||||
eulers,
|
||||
Point((SPACE_WIDTH, SPACE_HEIGHT, 0))
|
||||
))
|
||||
@@ -710,16 +710,16 @@ class DefiningGraph(GraphScene):
|
||||
dots, lines = self.vertices, self.edges
|
||||
self.remove(*dots + lines)
|
||||
all_dots = CompoundMobject(*dots)
|
||||
self.animate(ShowCreation(all_dots))
|
||||
self.play(ShowCreation(all_dots))
|
||||
self.remove(all_dots)
|
||||
self.add(*dots)
|
||||
self.animate(FadeIn(vertices_word))
|
||||
self.play(FadeIn(vertices_word))
|
||||
self.dither()
|
||||
self.remove(vertices_word)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(line) for line in lines
|
||||
])
|
||||
self.animate(FadeIn(edges_word))
|
||||
self.play(FadeIn(edges_word))
|
||||
|
||||
#Move to new graph
|
||||
# new_graph = deepcopy(self.graph)
|
||||
@@ -728,7 +728,7 @@ class DefiningGraph(GraphScene):
|
||||
# for v in new_graph.vertices
|
||||
# ]
|
||||
# new_graph_scene = GraphScene(new_graph)
|
||||
# self.animate(*[
|
||||
# self.play(*[
|
||||
# Transform(m[0], m[1])
|
||||
# for m in zip(self.mobjects, new_graph_scene.mobjects)
|
||||
# ], run_time = 7.0)
|
||||
@@ -741,7 +741,7 @@ class IntersectCubeGraphEdges(GraphScene):
|
||||
def __init__(self, *args, **kwargs):
|
||||
GraphScene.__init__(self, CubeGraph(), *args, **kwargs)
|
||||
self.remove(self.edges[0], self.edges[4])
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(
|
||||
Line(self.points[i], self.points[j]),
|
||||
CurvedLine(self.points[i], self.points[j]),
|
||||
@@ -772,7 +772,7 @@ class DoubledEdges(GraphScene):
|
||||
Transform(backwards, outward, **kwargs),
|
||||
]
|
||||
outward_curved_lines.append(outward)
|
||||
self.animate(*anims)
|
||||
self.play(*anims)
|
||||
self.dither()
|
||||
self.remove(*outward_curved_lines)
|
||||
|
||||
@@ -846,12 +846,12 @@ class CannotDirectlyApplyEulerToMoser(CircleScene):
|
||||
yellow_lines = CompoundMobject(*[
|
||||
l.highlight("yellow") for l in deepcopy(self.lines)
|
||||
])
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(dot) for dot in yellow_dots
|
||||
], run_time = 1.0)
|
||||
self.dither()
|
||||
self.remove(*yellow_dots)
|
||||
self.animate(ShowCreation(yellow_lines))
|
||||
self.play(ShowCreation(yellow_lines))
|
||||
self.dither()
|
||||
self.remove(yellow_lines)
|
||||
cannot_intersect = text_mobject(r"""
|
||||
@@ -868,7 +868,7 @@ class CannotDirectlyApplyEulerToMoser(CircleScene):
|
||||
for mob in self.mobjects:
|
||||
mob.fade(1/0.3)
|
||||
self.generate_intersection_dots()
|
||||
self.animate(FadeIn(intersection_count), *[
|
||||
self.play(FadeIn(intersection_count), *[
|
||||
ShowCreation(dot) for dot in self.intersection_dots
|
||||
])
|
||||
|
||||
@@ -899,7 +899,7 @@ class ShowMoserGraphLines(CircleScene):
|
||||
compound = CompoundMobject(*mobs)
|
||||
if mobs in (self.dots, self.intersection_dots):
|
||||
self.remove(*mobs)
|
||||
self.animate(CounterclockwiseTransform(
|
||||
self.play(CounterclockwiseTransform(
|
||||
compound,
|
||||
deepcopy(compound).scale(1.05),
|
||||
alpha_func = there_and_back,
|
||||
@@ -907,12 +907,12 @@ class ShowMoserGraphLines(CircleScene):
|
||||
))
|
||||
else:
|
||||
compound.highlight("yellow")
|
||||
self.animate(ShowCreation(compound))
|
||||
self.play(ShowCreation(compound))
|
||||
self.remove(compound)
|
||||
if mobs == self.intersection_dots:
|
||||
self.remove(n, plus_n_choose_4)
|
||||
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(line, small_line, run_time = 3.0)
|
||||
for line, small_line in zip(self.lines, small_lines)
|
||||
])
|
||||
@@ -920,16 +920,16 @@ class ShowMoserGraphLines(CircleScene):
|
||||
line.highlight("yellow") for line in small_lines
|
||||
])
|
||||
self.add(plus_2_n_choose_4)
|
||||
self.animate(ShowCreation(yellow_lines))
|
||||
self.play(ShowCreation(yellow_lines))
|
||||
self.dither()
|
||||
self.remove(yellow_lines)
|
||||
self.chop_circle_at_points()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(p, sp, run_time = 3.0)
|
||||
for p, sp in zip(self.circle_pieces, self.smaller_circle_pieces)
|
||||
])
|
||||
self.add(plus_n)
|
||||
self.animate(ShowCreation(CompoundMobject(*[
|
||||
self.play(ShowCreation(CompoundMobject(*[
|
||||
mob.highlight("yellow") for mob in self.circle_pieces
|
||||
])))
|
||||
|
||||
@@ -961,7 +961,7 @@ class HowIntersectionChopsLine(CircleScene):
|
||||
for p0, p1 in [(0, 2), (1, 3)]
|
||||
])
|
||||
self.add(*lines)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
FadeOut(mob)
|
||||
for mob in self.mobjects
|
||||
if mob not in lines
|
||||
@@ -973,7 +973,7 @@ class HowIntersectionChopsLine(CircleScene):
|
||||
Line(intersection_point, line.end)
|
||||
for line in lines
|
||||
]
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(
|
||||
line,
|
||||
Line(
|
||||
@@ -986,7 +986,7 @@ class HowIntersectionChopsLine(CircleScene):
|
||||
for line, h in zip(lines, (-1, 1))
|
||||
])
|
||||
self.remove(*lines)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(
|
||||
line,
|
||||
deepcopy(line).scale(1.1).scale_in_place(1/1.1),
|
||||
@@ -1054,7 +1054,7 @@ class ApplyEulerToMoser(CircleScene):
|
||||
d[key].get_center() - main_center
|
||||
)
|
||||
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(d[1], d[2], run_time = 2.0)
|
||||
for d in [V, minus, E, plus, F, equals, two]
|
||||
])
|
||||
@@ -1069,7 +1069,7 @@ class ApplyEulerToMoser(CircleScene):
|
||||
F[1].highlight("white")
|
||||
E[1].highlight()
|
||||
self.remove(*self.lines + self.circle_pieces)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(
|
||||
deepcopy(line),
|
||||
deepcopy(line).scale_in_place(0.5),
|
||||
@@ -1088,7 +1088,7 @@ class ApplyEulerToMoser(CircleScene):
|
||||
V[1].highlight()
|
||||
self.add(*self.dots + self.intersection_dots)
|
||||
self.remove(*self.lines + self.circle_pieces)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(
|
||||
deepcopy(dot),
|
||||
deepcopy(dot).scale_in_place(1.4).highlight("yellow")
|
||||
@@ -1110,7 +1110,7 @@ class ApplyEulerToMoser(CircleScene):
|
||||
self.dither()
|
||||
self.add(*all_mobs)
|
||||
self.remove(*[d[1] for d in [V, minus, E, plus, F, equals, two]])
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(V[2].repeat(2), CompoundMobject(n[3], minus1[3], nc4[3])),
|
||||
*[
|
||||
Transform(d[2], d[3])
|
||||
@@ -1119,7 +1119,7 @@ class ApplyEulerToMoser(CircleScene):
|
||||
)
|
||||
self.dither()
|
||||
self.remove(*self.mobjects)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(E[3], CompoundMobject(
|
||||
nc2[4], plus1[4], two1[4], nc41[4], plus2[4], n1[4]
|
||||
)),
|
||||
@@ -1140,7 +1140,7 @@ class ApplyEulerToMoser(CircleScene):
|
||||
)
|
||||
self.dither()
|
||||
self.remove(*self.mobjects)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(
|
||||
CompoundMobject(plus2[4], n1[4], minus[4], n[4]),
|
||||
Point((SPACE_WIDTH, SPACE_HEIGHT, 0))
|
||||
@@ -1153,7 +1153,7 @@ class ApplyEulerToMoser(CircleScene):
|
||||
)
|
||||
self.dither()
|
||||
self.remove(*self.mobjects)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(nc41[5], nc4[6]),
|
||||
Transform(two1[5], Point(nc4[6].get_center())),
|
||||
*[
|
||||
@@ -1163,7 +1163,7 @@ class ApplyEulerToMoser(CircleScene):
|
||||
)
|
||||
self.dither()
|
||||
self.remove(*self.mobjects)
|
||||
self.animate(
|
||||
self.play(
|
||||
CounterclockwiseTransform(two[6], two[7]),
|
||||
CounterclockwiseTransform(plus[6], plus[7]),
|
||||
*[
|
||||
@@ -1184,7 +1184,7 @@ class ApplyEulerToMoser(CircleScene):
|
||||
one = tex_mobject("1").shift(two.get_center())
|
||||
two.highlight("red")
|
||||
self.add(two)
|
||||
self.animate(CounterclockwiseTransform(two, one))
|
||||
self.play(CounterclockwiseTransform(two, one))
|
||||
|
||||
class FormulaRelatesToPowersOfTwo(Scene):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -1207,11 +1207,11 @@ class FormulaRelatesToPowersOfTwo(Scene):
|
||||
sums = everything[1::3]
|
||||
results = everything[2::3]
|
||||
self.add(*forms)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
FadeIn(s) for s in sums
|
||||
])
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(deepcopy(s), result)
|
||||
for s, result in zip(sums, results)
|
||||
])
|
||||
@@ -1225,7 +1225,7 @@ class FormulaRelatesToPowersOfTwo(Scene):
|
||||
self.dither()
|
||||
self.remove(*self.mobjects)
|
||||
self.add(*forms + sums + results)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(result, pof2)
|
||||
for result, pof2 in zip(results, powers_of_two)
|
||||
])
|
||||
@@ -1245,7 +1245,7 @@ class DrawPascalsTriangle(PascalsTriangleScene):
|
||||
for k in range(1, n)
|
||||
]
|
||||
starts.append(deepcopy(self.coords_to_mobs[n-1][n-1]))
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(starts[i], self.coords_to_mobs[n][i],
|
||||
run_time = 1.5, black_out_extra_points = False)
|
||||
for i in range(n+1)
|
||||
@@ -1276,7 +1276,7 @@ class PascalsTriangleWithNChooseK(PascalsTriangleScene):
|
||||
for i in [0, 1]:
|
||||
self.dither()
|
||||
self.remove(*self.mobjects)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(
|
||||
deepcopy(mob_dicts[i][n][k]),
|
||||
mob_dicts[1-i][n][k]
|
||||
@@ -1305,7 +1305,7 @@ class PascalsTriangleNChooseKExample(PascalsTriangleScene):
|
||||
self.remove(*triangle_terms)
|
||||
self.add(*formula_terms)
|
||||
self.dither()
|
||||
self.animate(*
|
||||
self.play(*
|
||||
[
|
||||
ShowCreation(mob) for mob in triangle_terms
|
||||
]+[
|
||||
@@ -1339,7 +1339,7 @@ class PascalsTriangleNChooseKExample(PascalsTriangleScene):
|
||||
if b < k:
|
||||
self.coords_to_mobs[n][b].highlight("green")
|
||||
self.remove(b_mob)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyMethod(mob.fade, 0.2)
|
||||
for mob in triangle_terms
|
||||
if mob != self.coords_to_mobs[n][k]
|
||||
@@ -1384,13 +1384,13 @@ class PascalsTriangleSumRows(PascalsTriangleScene):
|
||||
powers_of_two.append(pof2)
|
||||
equalses.append(new_equals)
|
||||
powers_of_two_symbols.append(symbol)
|
||||
self.animate(FadeIn(CompoundMobject(*pluses)))
|
||||
self.play(FadeIn(CompoundMobject(*pluses)))
|
||||
run_time = 0.5
|
||||
to_remove = []
|
||||
for n in range(self.nrows):
|
||||
start = CompoundMobject(*[self.coords_to_mobs[n][k] for k in range(n+1)])
|
||||
to_remove.append(start)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(start, powers_of_two[n]),
|
||||
FadeIn(equalses[n]),
|
||||
run_time = run_time
|
||||
@@ -1399,7 +1399,7 @@ class PascalsTriangleSumRows(PascalsTriangleScene):
|
||||
self.remove(*to_remove)
|
||||
self.add(*powers_of_two)
|
||||
for n in range(self.nrows):
|
||||
self.animate(CounterclockwiseTransform(
|
||||
self.play(CounterclockwiseTransform(
|
||||
powers_of_two[n], powers_of_two_symbols[n],
|
||||
run_time = run_time
|
||||
))
|
||||
@@ -1438,7 +1438,7 @@ class MoserSolutionInPascal(PascalsTriangleScene):
|
||||
target_terms.append(new_term)
|
||||
self.add(*terms)
|
||||
self.dither()
|
||||
self.animate(*
|
||||
self.play(*
|
||||
[
|
||||
FadeIn(self.coords_to_n_choose_k[n0][k0])
|
||||
for n0, k0 in self.coords
|
||||
@@ -1454,7 +1454,7 @@ class MoserSolutionInPascal(PascalsTriangleScene):
|
||||
(k, deepcopy(self.coords_to_mobs[n][k]).highlight(term_color))
|
||||
for k in term_range
|
||||
])
|
||||
self.animate(*
|
||||
self.play(*
|
||||
[
|
||||
CounterclockwiseTransform(
|
||||
self.coords_to_n_choose_k[n0][k0],
|
||||
@@ -1479,7 +1479,7 @@ class MoserSolutionInPascal(PascalsTriangleScene):
|
||||
self.coords_to_n_choose_k[n-1][k],
|
||||
]
|
||||
self.add(self.coords_to_mobs[n][k])
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
terms[k],
|
||||
CompoundMobject(*above_terms).highlight(term_color)
|
||||
))
|
||||
@@ -1488,7 +1488,7 @@ class MoserSolutionInPascal(PascalsTriangleScene):
|
||||
terms_sum = tex_mobject(str(moser_function(n)))
|
||||
terms_sum.shift((SPACE_WIDTH-1, terms[0].get_center()[1], 0))
|
||||
terms_sum.highlight(term_color)
|
||||
self.animate(Transform(CompoundMobject(*terms), terms_sum))
|
||||
self.play(Transform(CompoundMobject(*terms), terms_sum))
|
||||
|
||||
class RotatingPolyhedra(Scene):
|
||||
args_list = [
|
||||
@@ -1511,13 +1511,13 @@ class RotatingPolyhedra(Scene):
|
||||
]
|
||||
curr_mob = polyhedra.pop()
|
||||
for mob in polyhedra:
|
||||
self.animate(TransformAnimations(
|
||||
self.play(TransformAnimations(
|
||||
Rotating(curr_mob, **rot_kwargs),
|
||||
Rotating(mob, **rot_kwargs)
|
||||
))
|
||||
for m in polyhedra:
|
||||
m.rotate(rot_kwargs["radians"], rot_kwargs["axis"])
|
||||
self.animate(Rotating(curr_mob, **rot_kwargs))
|
||||
self.play(Rotating(curr_mob, **rot_kwargs))
|
||||
|
||||
class ExplainNChoose2Formula(Scene):
|
||||
args_list = [(7,2,6)]
|
||||
@@ -1545,8 +1545,8 @@ class ExplainNChoose2Formula(Scene):
|
||||
|
||||
self.add(parens, n_mob)
|
||||
up_unit = np.array((0, height, 0))
|
||||
self.animate(ApplyMethod(nums_compound.shift, -(n-1)*up_unit))
|
||||
self.animate(ApplyMethod(nums_compound.shift, (n-a)*up_unit))
|
||||
self.play(ApplyMethod(nums_compound.shift, -(n-1)*up_unit))
|
||||
self.play(ApplyMethod(nums_compound.shift, (n-a)*up_unit))
|
||||
self.remove(nums_compound)
|
||||
nums = nums_compound.split()
|
||||
a_mob = nums.pop(a-1)
|
||||
@@ -1555,23 +1555,23 @@ class ExplainNChoose2Formula(Scene):
|
||||
self.dither()
|
||||
right_shift = b_mob.get_center() - a_mob.get_center()
|
||||
right_shift[1] = 0
|
||||
self.animate(
|
||||
self.play(
|
||||
ApplyMethod(nums_compound.shift, right_shift),
|
||||
FadeIn(n_minus_1)
|
||||
)
|
||||
self.animate(ApplyMethod(nums_compound.shift, (a-b)*up_unit))
|
||||
self.play(ApplyMethod(nums_compound.shift, (a-b)*up_unit))
|
||||
self.remove(nums_compound)
|
||||
nums = nums_compound.split()
|
||||
b_mob = nums.pop(b-2 if a < b else b-1)
|
||||
self.add(b_mob)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(
|
||||
mob,
|
||||
Point(mob.get_center()).highlight("black")
|
||||
)
|
||||
for mob in nums
|
||||
])
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ApplyMethod(mob.shift, (0, 1, 0))
|
||||
for mob in parens, a_mob, b_mob
|
||||
])
|
||||
@@ -1581,7 +1581,7 @@ class ExplainNChoose2Formula(Scene):
|
||||
a_copy = deepcopy(a_mob).center().shift(b_center - (0, 2, 0))
|
||||
b_copy = deepcopy(b_mob).center().shift(a_center - (0, 2, 0))
|
||||
self.add(over_2, deepcopy(a_mob), deepcopy(b_mob))
|
||||
self.animate(
|
||||
self.play(
|
||||
CounterclockwiseTransform(a_mob, a_copy),
|
||||
CounterclockwiseTransform(b_mob, b_copy),
|
||||
FadeIn(parens_copy),
|
||||
@@ -1619,7 +1619,7 @@ class ExplainNChoose4Formula(Scene):
|
||||
up_unit = np.array((0, height, 0))
|
||||
for i in range(4):
|
||||
self.add(form_mobs[i])
|
||||
self.animate(ApplyMethod(
|
||||
self.play(ApplyMethod(
|
||||
nums_compound.shift, (curr_num-quad[i])*up_unit))
|
||||
self.remove(nums_compound)
|
||||
nums = nums_compound.split()
|
||||
@@ -1630,11 +1630,11 @@ class ExplainNChoose4Formula(Scene):
|
||||
if i < 3:
|
||||
right_shift = quad_mobs[i+1].get_center() - chosen.get_center()
|
||||
right_shift[1] = 0
|
||||
self.animate(
|
||||
self.play(
|
||||
ApplyMethod(nums_compound.shift, right_shift)
|
||||
)
|
||||
else:
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(
|
||||
mob,
|
||||
Point(mob.get_center()).highlight("black")
|
||||
@@ -1658,7 +1658,7 @@ class ExplainNChoose4Formula(Scene):
|
||||
for i in range(4)
|
||||
]
|
||||
compound_quad = CompoundMobject(*quad_mobs)
|
||||
self.animate(CounterclockwiseTransform(
|
||||
self.play(CounterclockwiseTransform(
|
||||
compound_quad,
|
||||
CompoundMobject(*new_quad_mobs)
|
||||
))
|
||||
@@ -1688,7 +1688,7 @@ class IntersectionChoppingExamples(Scene):
|
||||
self.add(tex_mobject(exp).shift((0, SPACE_HEIGHT-1, 0)))
|
||||
self.add(*lines)
|
||||
self.dither()
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(line, deepcopy(line).scale(1.2).scale_in_place(1/1.2))
|
||||
for line in lines
|
||||
])
|
||||
|
||||
@@ -12,6 +12,7 @@ from constants import *
|
||||
from region import *
|
||||
from scene import Scene
|
||||
from script_wrapper import command_line_create_scene
|
||||
from inventing_math import underbrace
|
||||
|
||||
import random
|
||||
|
||||
@@ -47,6 +48,10 @@ def fraction_mobject(fraction):
|
||||
n, d = fraction.numerator, fraction.denominator
|
||||
return tex_mobject("\\frac{%d}{%d}"%(n, d))
|
||||
|
||||
def continued_fraction(int_list):
|
||||
if len(int_list) == 1:
|
||||
return int_list[0]
|
||||
return int_list[0] + Fraction(1, continued_fraction(int_list[1:]))
|
||||
|
||||
def zero_to_one_interval():
|
||||
interval = NumberLine(
|
||||
@@ -69,6 +74,31 @@ class OpenInterval(Mobject):
|
||||
self.stretch(0.5+0.5*scale_factor, 1)
|
||||
self.shift(center)
|
||||
|
||||
class Piano(ImageMobject):
|
||||
SHOULD_BUFF_POINTS = False
|
||||
def __init__(self, **kwargs):
|
||||
ImageMobject.__init__(self, "piano_keyboard", invert = False)
|
||||
jump = self.get_width()/24
|
||||
self.scale(0.5).center()
|
||||
self.half_note_jump = self.get_width()/24
|
||||
self.ivory_jump = self.get_width()/14
|
||||
|
||||
def split(self):
|
||||
left = self.get_left()[0]
|
||||
keys = []
|
||||
for count in range(14):
|
||||
key = Mobject(color = "white")
|
||||
x0 = left + count*self.ivory_jump
|
||||
x1 = x0 + self.ivory_jump
|
||||
key.add_points(
|
||||
self.points[
|
||||
(self.points[:,0] > x0)*(self.points[:,0] < x1)
|
||||
]
|
||||
)
|
||||
keys.append(key)
|
||||
return keys
|
||||
|
||||
|
||||
class VibratingString(Animation):
|
||||
def __init__(self,
|
||||
num_periods = 1,
|
||||
@@ -84,7 +114,7 @@ class VibratingString(Animation):
|
||||
self.center = center
|
||||
def func(x, t):
|
||||
return sum([
|
||||
(amplitude/((k+1)**2))*np.sin(2*mult*t)*np.sin(k*mult*x)
|
||||
(amplitude/((k+1)**2.5))*np.sin(2*mult*t)*np.sin(k*mult*x)
|
||||
for k in range(overtones)
|
||||
for mult in [(num_periods+k)*np.pi]
|
||||
])
|
||||
@@ -95,16 +125,18 @@ class VibratingString(Animation):
|
||||
|
||||
def update_mobject(self, alpha):
|
||||
self.mobject.init_points()
|
||||
epsilon = self.mobject.epsilon
|
||||
self.mobject.add_points([
|
||||
[x*self.radius, self.func(x, alpha*self.run_time), 0]
|
||||
for x in np.arange(-1, 1, self.mobject.epsilon/self.radius)
|
||||
[x*self.radius, self.func(x, alpha*self.run_time)+y, 0]
|
||||
for x in np.arange(-1, 1, epsilon/self.radius)
|
||||
for y in epsilon*np.arange(3)
|
||||
])
|
||||
self.mobject.shift(self.center)
|
||||
|
||||
|
||||
class IntervalScene(Scene):
|
||||
def construct(self):
|
||||
self.interval = zero_to_one_interval()
|
||||
self.interval = UnitInterval()
|
||||
self.add(self.interval)
|
||||
|
||||
def show_all_fractions(self,
|
||||
@@ -144,8 +176,8 @@ class IntervalScene(Scene):
|
||||
)
|
||||
|
||||
def add_open_interval(self, num, width, color = None, run_time = 0):
|
||||
width *= 2*self.interval.radius
|
||||
center_point = self.num_to_point(num)
|
||||
width *= self.interval.unit_length_to_spacial_width
|
||||
center_point = self.interval.number_to_point(num)
|
||||
open_interval = OpenInterval(center_point, width)
|
||||
if color:
|
||||
open_interval.highlight(color)
|
||||
@@ -155,7 +187,7 @@ class IntervalScene(Scene):
|
||||
interval_line.highlight("yellow")
|
||||
if run_time > 0:
|
||||
squished_interval = deepcopy(open_interval).stretch_to_fit_width(0)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(squished_interval, open_interval),
|
||||
ShowCreation(interval_line),
|
||||
run_time = run_time
|
||||
@@ -164,11 +196,6 @@ class IntervalScene(Scene):
|
||||
self.add(open_interval, interval_line)
|
||||
return open_interval, interval_line
|
||||
|
||||
def num_to_point(self, num):
|
||||
assert(num <= 1 and num >= 0)
|
||||
radius = self.interval.radius
|
||||
return (num*2*radius - radius)*RIGHT
|
||||
|
||||
|
||||
class TwoChallenges(Scene):
|
||||
def construct(self):
|
||||
@@ -196,10 +223,10 @@ class TwoChallenges(Scene):
|
||||
self.dither()
|
||||
self.add(two, measure)
|
||||
self.dither()
|
||||
self.animate(ShowCreation(arrow_to_int))
|
||||
self.play(ShowCreation(arrow_to_int))
|
||||
self.add(integration)
|
||||
self.dither()
|
||||
self.animate(ShowCreation(arrow_to_prob))
|
||||
self.play(ShowCreation(arrow_to_prob))
|
||||
self.add(probability)
|
||||
self.dither()
|
||||
|
||||
@@ -213,9 +240,9 @@ class MeasureTheoryToHarmony(IntervalScene):
|
||||
self.clear()
|
||||
radius = self.interval.radius
|
||||
line = Line(radius*LEFT, radius*RIGHT).highlight("white")
|
||||
self.animate(DelayByOrder(Transform(all_mobs, line)))
|
||||
self.play(DelayByOrder(Transform(all_mobs, line)))
|
||||
self.clear()
|
||||
self.animate(VibratingString(alpha_func = smooth))
|
||||
self.play(VibratingString(alpha_func = smooth))
|
||||
self.clear()
|
||||
self.add(line)
|
||||
self.dither()
|
||||
@@ -224,21 +251,440 @@ class MeasureTheoryToHarmony(IntervalScene):
|
||||
class ChallengeOne(Scene):
|
||||
def construct(self):
|
||||
title = text_mobject("Challenge #1").to_edge(UP)
|
||||
bottom_vibration = VibratingString(
|
||||
num_periods = 1, run_time = 1.0,
|
||||
start_color = Color("blue")
|
||||
colors = start_color.range_to("white", 6)
|
||||
self.bottom_vibration = VibratingString(
|
||||
num_periods = 1, run_time = 3.0,
|
||||
center = DOWN, color = start_color
|
||||
)
|
||||
top_vibrations = [
|
||||
VibratingString(
|
||||
num_periods = freq, run_time = 3.0,
|
||||
center = 2*UP, color = colors.next()
|
||||
)
|
||||
for freq in [1, 2, 5.0/3, 4.0/3, 2]
|
||||
]
|
||||
freq_220 = text_mobject("220 Hz")
|
||||
freq_r220 = text_mobject("$r\\times$220 Hz")
|
||||
freq_330 = text_mobject("1.5$\\times$220 Hz")
|
||||
freq_sqrt2 = text_mobject("$\\sqrt{2}\\times$220 Hz")
|
||||
freq_220.shift(1.5*DOWN)
|
||||
for freq in freq_r220, freq_330, freq_sqrt2:
|
||||
freq.shift(1.5*UP)
|
||||
r_constraint = tex_mobject("(1<r<2)", size = "\\large")
|
||||
|
||||
self.add(title)
|
||||
self.dither()
|
||||
self.vibrate(1)
|
||||
self.add(freq_220)
|
||||
self.vibrate(1)
|
||||
self.add(r_constraint)
|
||||
self.vibrate(1)
|
||||
self.add(freq_r220)
|
||||
self.vibrate(2, top_vibrations[1])
|
||||
self.remove(freq_r220, r_constraint)
|
||||
self.add(freq_330)
|
||||
self.vibrate(2, top_vibrations[2])
|
||||
self.remove(freq_330)
|
||||
self.add(freq_sqrt2)
|
||||
self.vibrate(1, top_vibrations[3])
|
||||
self.remove(freq_sqrt2)
|
||||
self.continuously_vary_frequency(top_vibrations[0], top_vibrations[4])
|
||||
|
||||
def vibrate(self, num_repeats, *top_vibrations):
|
||||
anims = [self.bottom_vibration] + list(top_vibrations)
|
||||
for count in range(num_repeats):
|
||||
self.play(*anims)
|
||||
self.remove(*[a.mobject for a in anims])
|
||||
|
||||
def continuously_vary_frequency(self, top_vib_1, top_vib_2):
|
||||
number_line = NumberLine(interval_size = 1).add_numbers()
|
||||
|
||||
one, two = 2*number_line.interval_size*RIGHT, 4*number_line.interval_size*RIGHT
|
||||
arrow1 = Arrow(one+UP, one)
|
||||
arrow2 = Arrow(two+UP, two)
|
||||
r1 = tex_mobject("r").next_to(arrow1, UP)
|
||||
r2 = tex_mobject("r").next_to(arrow2, UP)
|
||||
kwargs = {
|
||||
"run_time" : 5.0,
|
||||
"alpha_func" : there_and_back
|
||||
}
|
||||
run_time = 3.0
|
||||
vibrations = [self.bottom_vibration, top_vib_1, top_vib_2]
|
||||
|
||||
self.add(number_line, r1, arrow1)
|
||||
self.play(bottom_vibration, top_vib_1)
|
||||
for vib in vibrations:
|
||||
vib.set_run_time(kwargs["run_time"])
|
||||
self.play(
|
||||
self.bottom_vibration,
|
||||
Transform(arrow1, arrow2, **kwargs),
|
||||
Transform(r1, r2, **kwargs),
|
||||
TransformAnimations(top_vib_1, top_vib_2, **kwargs)
|
||||
)
|
||||
for vib in vibrations:
|
||||
vib.set_run_time(3.0)
|
||||
self.play(bottom_vibration, top_vib_1)
|
||||
|
||||
class QuestionAndAnswer(Scene):
|
||||
def construct(self):
|
||||
Q = text_mobject("Q:").shift(UP).to_edge(LEFT)
|
||||
A = text_mobject("A:").shift(DOWN).to_edge(LEFT)
|
||||
string1 = VibratingString(center = 3*UP, color = "blue")
|
||||
string2 = VibratingString(num_periods = 2, center = 3.5*UP, color = "green")
|
||||
twotwenty = tex_mobject("220").scale(0.25).next_to(string1.mobject, LEFT)
|
||||
r220 = tex_mobject("r\\times220").scale(0.25).next_to(string2.mobject, LEFT)
|
||||
question = text_mobject(
|
||||
"For what values of $r$ will the frequencies 220~Hz and \
|
||||
$r\\times$220~Hz sound nice together?"
|
||||
).next_to(Q)
|
||||
answer = text_mobject([
|
||||
"When $r$ is",
|
||||
"sufficiently close to",
|
||||
"a rational number"
|
||||
], size = "\\small").scale(1.5)
|
||||
answer.next_to(A)
|
||||
correction1 = text_mobject(
|
||||
"with sufficiently low denominator",
|
||||
size = "\\small"
|
||||
).scale(1.5)
|
||||
correction1.highlight("yellow")
|
||||
correction1.next_to(A).shift(2*answer.get_height()*DOWN)
|
||||
answer = answer.split()
|
||||
answer[1].highlight("green")
|
||||
temp_answer_end = deepcopy(answer[-1]).next_to(answer[0], buff = 0.2)
|
||||
|
||||
self.add(Q, A, question, twotwenty, r220)
|
||||
self.play(string1, string2)
|
||||
self.add(answer[0], temp_answer_end)
|
||||
self.play(string1, string2)
|
||||
self.play(ShimmerIn(correction1), string1, string2)
|
||||
self.play(string1, string2, run_time = 3.0)
|
||||
self.play(
|
||||
Transform(Point(answer[1].get_left()), answer[1]),
|
||||
Transform(temp_answer_end, answer[2]),
|
||||
string1, string2
|
||||
)
|
||||
self.play(string1, string2, run_time = 3.0)
|
||||
|
||||
class PlaySimpleRatio(Scene):
|
||||
args_list = [
|
||||
(Fraction(3, 2), "green"),
|
||||
(Fraction(4, 3), "purple"),
|
||||
(Fraction(8, 5), "skyblue"),
|
||||
(Fraction(211, 198), "orange"),
|
||||
(Fraction(1093, 826), "red"),
|
||||
]
|
||||
@staticmethod
|
||||
def args_to_string(fraction, color):
|
||||
return str(fraction).replace("/", "_to_")
|
||||
|
||||
def construct(self, fraction, color):
|
||||
string1 = VibratingString(
|
||||
num_periods = 1, run_time = 5.0,
|
||||
center = DOWN, color = "blue"
|
||||
)
|
||||
top_vibration = VibratingString(
|
||||
num_periods = 2, run_time = 1.0,
|
||||
center = 2*UP, color = "lightgreen"
|
||||
string2 = VibratingString(
|
||||
num_periods = fraction, run_time = 5.0,
|
||||
center = 2*UP, color = color
|
||||
)
|
||||
freq_num1 = text_mobject("220 Hz")
|
||||
freq_num2 = text_mobject("$r\\times$220 Hz")
|
||||
freq_num1.shift(1.5*DOWN)
|
||||
freq_num2.shift(1.5*UP)
|
||||
r_constraint = tex_mobject("1<r<2")
|
||||
# self.add(title, freq_num1, freq_num2, r_constraint)
|
||||
self.animate(top_vibration, bottom_vibration)
|
||||
self.add(fraction_mobject(fraction).shift(0.5*UP))
|
||||
self.play(string1, string2)
|
||||
|
||||
class FlashOnXProximity(Animation):
|
||||
def __init__(self, mobject, x_val, *close_mobjects, **kwargs):
|
||||
self.x_val = x_val
|
||||
self.close_mobjects = close_mobjects
|
||||
Animation.__init__(self, mobject, **kwargs)
|
||||
|
||||
def update_mobject(self, alpha):
|
||||
for mob in self.close_mobjects:
|
||||
if np.min(np.abs(mob.points[:,0] - self.x_val)) < 0.1:
|
||||
self.mobject.highlight()
|
||||
return
|
||||
self.mobject.to_original_color()
|
||||
|
||||
class PatternInFrequencies(Scene):
|
||||
args_list = [
|
||||
(3, 2, "green"),
|
||||
(4, 3, "purple"),
|
||||
(8, 5, "skyblue"),
|
||||
(35, 43, "red"),
|
||||
]
|
||||
@staticmethod
|
||||
def args_to_string(num1, num2, color):
|
||||
return "%d_to_%d"%(num1, num2)
|
||||
|
||||
def construct(self, num1, num2, color):
|
||||
big_line = Line(SPACE_HEIGHT*UP, SPACE_HEIGHT*DOWN)
|
||||
big_line.highlight("white").shift(2*LEFT)
|
||||
line_template = Line(UP, DOWN)
|
||||
line_template.shift(2*UP+2*LEFT)
|
||||
setup_width = 2*SPACE_WIDTH
|
||||
num_top_lines = int(setup_width)
|
||||
num_bot_lines = int(setup_width*num1/num2)
|
||||
top_lines = CompoundMobject(*[
|
||||
deepcopy(line_template).shift(k*(float(num1)/num2)*RIGHT)
|
||||
for k in range(num_top_lines)
|
||||
])
|
||||
line_template.shift(4*DOWN)
|
||||
bottom_lines = CompoundMobject(*[
|
||||
deepcopy(line_template).shift(k*RIGHT)
|
||||
for k in range(num_bot_lines)
|
||||
])
|
||||
bottom_lines.highlight("blue")
|
||||
top_lines.highlight(color)
|
||||
kwargs = {
|
||||
"run_time" : 10,
|
||||
"alpha_func" : None
|
||||
}
|
||||
|
||||
self.add(big_line)
|
||||
self.add(tex_mobject("%d:%d"%(num1, num2)))
|
||||
fracs = (
|
||||
1.0/(num_top_lines-1),
|
||||
1.0/(num_bot_lines-1)
|
||||
)
|
||||
anims = [
|
||||
ApplyMethod(mob.shift, setup_width*LEFT, **kwargs)
|
||||
for mob in top_lines, bottom_lines
|
||||
]
|
||||
anim_mobs = [anim.mobject for anim in anims]
|
||||
self.play(
|
||||
FlashOnXProximity(big_line, -2, *anim_mobs, **kwargs),
|
||||
*anims
|
||||
)
|
||||
|
||||
|
||||
class CompareFractionComplexity(Scene):
|
||||
def construct(self):
|
||||
fractions = []
|
||||
for num, den in [(4, 3), (1093,826)]:
|
||||
top = tex_mobject("%d \\over"%num)
|
||||
bottom = tex_mobject(str(den)).next_to(top, DOWN, buff = 0.3)
|
||||
fractions.append(CompoundMobject(top, bottom))
|
||||
frac0 = fractions[0].shift(3*LEFT).split()
|
||||
frac1 = fractions[1].shift(3*RIGHT).split()
|
||||
arrow1 = Arrow(UP, ORIGIN).next_to(frac0[0], UP)
|
||||
arrow2 = Arrow(UP, ORIGIN).next_to(frac1[0], UP)
|
||||
simple = text_mobject("Simple").next_to(arrow1, UP)
|
||||
simple.highlight("green")
|
||||
complicated = text_mobject("Complicated").next_to(arrow2, UP)
|
||||
complicated.highlight("red")
|
||||
indicates = text_mobject("Indicates complexity").shift(2*DOWN)
|
||||
arrow3 = Arrow(indicates.get_top(), frac0[1])
|
||||
arrow4 = Arrow(indicates.get_top(), frac1[1])
|
||||
|
||||
self.add(*frac0 + frac1)
|
||||
self.dither()
|
||||
self.add(simple, complicated)
|
||||
self.play(*[
|
||||
ShowCreation(arrow)
|
||||
for arrow in arrow1, arrow2
|
||||
])
|
||||
self.dither()
|
||||
self.play(*[
|
||||
DelayByOrder(ApplyMethod(frac[1].highlight, "yellow"))
|
||||
for frac in frac0, frac1
|
||||
])
|
||||
self.play(
|
||||
FadeIn(indicates),
|
||||
ShowCreation(arrow3),
|
||||
ShowCreation(arrow4)
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class IrrationalGang(Scene):
|
||||
def construct(self):
|
||||
randy = Randolph()
|
||||
randy.mouth.highlight(randy.DEFAULT_COLOR)
|
||||
randy.sync_parts()
|
||||
sqrt13 = tex_mobject("\\sqrt{13}").shift(2*LEFT)
|
||||
sqrt13.highlight("green")
|
||||
zeta3 = tex_mobject("\\zeta(3)").shift(2*RIGHT)
|
||||
zeta3.highlight("grey")
|
||||
eyes = CompoundMobject(*randy.eyes)
|
||||
eyes.scale(0.5)
|
||||
sqrt13.add(eyes.next_to(sqrt13, UP, buff = 0).shift(0.25*RIGHT))
|
||||
eyes.scale(0.5)
|
||||
zeta3.add(eyes.next_to(zeta3, UP, buff = 0).shift(0.3*LEFT+0.08*DOWN))
|
||||
speech_bubble = SpeechBubble()
|
||||
speech_bubble.pin_to(randy)
|
||||
speech_bubble.write("We want to play too!")
|
||||
|
||||
self.add(randy, sqrt13, zeta3, speech_bubble, speech_bubble.content)
|
||||
self.play(BlinkPiCreature(randy))
|
||||
|
||||
|
||||
|
||||
class PianoTuning(Scene):
|
||||
def construct(self):
|
||||
piano = self.piano = Piano()
|
||||
jump = piano.half_note_jump
|
||||
semicircle = Circle().filter_out(lambda p : p[1] < 0)
|
||||
semicircle.scale(jump/semicircle.get_width())
|
||||
semicircles = CompoundMobject(*[
|
||||
deepcopy(semicircle).shift(jump*k*RIGHT)
|
||||
for k in range(23)
|
||||
])
|
||||
semicircles.highlight("white")
|
||||
semicircles.next_to(piano, UP, buff = 0)
|
||||
semicircles.shift(0.05*RIGHT)
|
||||
semicircles.sort_points(lambda p : p[0])
|
||||
first_jump = semicircles.split()[0]
|
||||
twelfth_root = tex_mobject("2^{\\left(\\frac{1}{12}\\right)}")
|
||||
twelfth_root.scale(0.75).next_to(first_jump, UP, buff = 1.5)
|
||||
line = Line(twelfth_root, first_jump).highlight("grey")
|
||||
self.keys = piano.split()
|
||||
self.semicircles = semicircles.split()
|
||||
|
||||
self.add(piano)
|
||||
self.dither()
|
||||
self.play(ShowCreation(first_jump))
|
||||
self.play(
|
||||
ShowCreation(line),
|
||||
FadeIn(twelfth_root)
|
||||
)
|
||||
self.dither()
|
||||
self.play(ShowCreation(semicircles, alpha_func = None))
|
||||
self.dither()
|
||||
|
||||
self.show_interval(5, 7)
|
||||
self.show_interval(4, 5)
|
||||
|
||||
def show_interval(self, interval, half_steps):
|
||||
whole_notes_to_base = 5
|
||||
half_notes_to_base = 9
|
||||
|
||||
self.clear()
|
||||
self.add(self.piano)
|
||||
colors = list(Color("blue").range_to("yellow", 7))
|
||||
low = self.keys[whole_notes_to_base]
|
||||
high = self.keys[whole_notes_to_base + interval - 1]
|
||||
u_brace = underbrace(low.get_bottom(), high.get_bottom())
|
||||
u_brace.highlight("yellow")
|
||||
ratio = tex_mobject("2^{\\left(\\frac{%d}{12}\\right)}"%half_steps)
|
||||
ratio.next_to(u_brace, DOWN, buff = 0.2)
|
||||
semicircles = self.semicircles[half_notes_to_base:half_notes_to_base+half_steps]
|
||||
product = tex_mobject(
|
||||
["\\left(2^{\\left(\\frac{1}{12}\\right)}\\right)"]*half_steps,
|
||||
size = "\\small"
|
||||
).next_to(self.piano, UP, buff = 1.0)
|
||||
approximate_form = tex_mobject("\\approx"+str(2**(float(half_steps)/12)))
|
||||
approximate_form.scale(0.75)
|
||||
approximate_form.next_to(ratio)
|
||||
|
||||
self.play(ApplyMethod(low.highlight, colors[0]))
|
||||
self.play(
|
||||
ApplyMethod(high.highlight, colors[interval]),
|
||||
Transform(Point(u_brace.get_left()), u_brace),
|
||||
)
|
||||
terms = product.split()
|
||||
for term, semicircle in zip(terms, semicircles):
|
||||
self.add(term, semicircle)
|
||||
self.dither(0.25)
|
||||
self.dither()
|
||||
product.sort_points(lambda p : p[1])
|
||||
self.play(DelayByOrder(Transform(product, ratio)))
|
||||
self.dither()
|
||||
self.play(ShimmerIn(approximate_form))
|
||||
self.dither()
|
||||
|
||||
class PowersOfTwelfthRoot(Scene):
|
||||
def construct(self):
|
||||
max_height = SPACE_HEIGHT-0.5
|
||||
min_height = -max_height
|
||||
num_terms = 11
|
||||
mob_list = []
|
||||
fraction_map = {
|
||||
1 : Fraction(16, 15),
|
||||
2 : Fraction(9, 8),
|
||||
3 : Fraction(6, 5),
|
||||
4 : Fraction(5, 4),
|
||||
5 : Fraction(4, 3),
|
||||
7 : Fraction(3, 2),
|
||||
8 : Fraction(8, 5),
|
||||
9 : Fraction(5, 3),
|
||||
10 : Fraction(16, 9),
|
||||
}
|
||||
approx = tex_mobject("\\approx").scale(0.5)
|
||||
curr_height = max_height*UP
|
||||
spacing = UP*(max_height-min_height)/(len(fraction_map)-1.0)
|
||||
for i in range(1, num_terms+1):
|
||||
if i not in fraction_map:
|
||||
continue
|
||||
term = tex_mobject("2^{\\left(\\frac{%d}{12}\\right)}"%i)
|
||||
term.shift(curr_height)
|
||||
curr_height -= spacing
|
||||
term.shift(4*LEFT)
|
||||
value = 2**(i/12.0)
|
||||
approx_form = tex_mobject(str(value)[:10])
|
||||
approx_copy = deepcopy(approx).next_to(term)
|
||||
approx_form.scale(0.5).next_to(approx_copy)
|
||||
words = text_mobject("is close to")
|
||||
words.scale(approx_form.get_height()/words.get_height())
|
||||
words.next_to(approx_form)
|
||||
frac = fraction_map[i]
|
||||
frac_mob = tex_mobject("%d/%d"%(frac.numerator, frac.denominator))
|
||||
frac_mob.scale(0.5).next_to(words)
|
||||
percent_error = abs(100*((value - frac) / frac))
|
||||
error_string = text_mobject([
|
||||
"with", str(percent_error)[:4] + "\\%", "error"
|
||||
])
|
||||
error_string = error_string.split()
|
||||
error_string[1].highlight()
|
||||
error_string = CompoundMobject(*error_string)
|
||||
error_string.scale(approx_form.get_height()/error_string.get_height())
|
||||
error_string.next_to(frac_mob)
|
||||
|
||||
mob_list.append(CompoundMobject(*[
|
||||
term, approx_copy, approx_form, words, frac_mob, error_string
|
||||
]))
|
||||
self.play(ShimmerIn(CompoundMobject(*mob_list), run_time = 3.0))
|
||||
|
||||
|
||||
class AllValuesBetween1And2(Scene):
|
||||
def construct(self):
|
||||
irrational = 1.2020569031595942
|
||||
cont_frac = [1, 4, 1, 18, 1, 1, 1, 4, 1, 9, 9, 2, 1, 1, 1, 2]
|
||||
number_line = NumberLine(interval_size = 1).add_numbers()
|
||||
one, two = 2*RIGHT, 4*RIGHT
|
||||
top_arrow = Arrow(one+UP, one)
|
||||
bot_arrow = Arrow(2*irrational*RIGHT+DOWN, 2*irrational*RIGHT)
|
||||
r = tex_mobject("r").next_to(top_arrow, UP)
|
||||
irr_mob = tex_mobject(str(irrational)).next_to(bot_arrow, DOWN)
|
||||
|
||||
approximations = [
|
||||
continued_fraction(cont_frac[:k])
|
||||
for k in range(1, len(cont_frac))
|
||||
]
|
||||
approx_mobs = [fraction_mobject(a) for a in approximations]
|
||||
|
||||
self.add(number_line)
|
||||
kwargs = {
|
||||
"run_time" : 3.0,
|
||||
"alpha_func" : there_and_back
|
||||
}
|
||||
self.play(*[
|
||||
ApplyMethod(mob.shift, 2*RIGHT, **kwargs)
|
||||
for mob in r, top_arrow
|
||||
])
|
||||
self.remove(r, top_arrow)
|
||||
self.play(
|
||||
ShimmerIn(irr_mob),
|
||||
ShowCreation(bot_arrow)
|
||||
)
|
||||
frac_mob = Point(top_arrow.get_top())
|
||||
for approx in approximations:
|
||||
point = 2*float(approx)*RIGHT
|
||||
new_arrow = Arrow(point+UP, point)
|
||||
mob = fraction_mobject(approx).next_to(new_arrow, UP)
|
||||
self.play(
|
||||
Transform(top_arrow, new_arrow),
|
||||
Transform(frac_mob, mob),
|
||||
run_time = 0.2
|
||||
)
|
||||
self.dither(0.5)
|
||||
|
||||
|
||||
|
||||
@@ -252,7 +698,11 @@ class SampleIntervalScene(IntervalScene):
|
||||
class ShowAllFractions(IntervalScene):
|
||||
def construct(self):
|
||||
IntervalScene.construct(self)
|
||||
self.show_all_fractions(remove_as_you_go = False, pause_time = 0.3)
|
||||
self.show_all_fractions(
|
||||
num_fractions = 100,
|
||||
remove_as_you_go = False,
|
||||
pause_time = 0.3
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -84,8 +84,8 @@ class HappyTauDayWords(Scene):
|
||||
pi.highlight("red")
|
||||
self.add(words, tau, pi)
|
||||
self.dither()
|
||||
self.animate(BlinkPiCreature(tau))
|
||||
self.animate(BlinkPiCreature(pi))
|
||||
self.play(BlinkPiCreature(tau))
|
||||
self.play(BlinkPiCreature(pi))
|
||||
|
||||
class TauPoem(Scene):
|
||||
args_list = map(lambda x : (x,), range(len(POEM_LINES)))
|
||||
@@ -160,17 +160,17 @@ class TauPoem(Scene):
|
||||
if self.line_num == 19:
|
||||
shift_val = SPACE_HEIGHT*DOWN
|
||||
self.new_digit.shift(shift_val)
|
||||
self.animate(ApplyMethod(
|
||||
self.play(ApplyMethod(
|
||||
self.first_digits.shift, shift_val, run_time = 2.0
|
||||
))
|
||||
self.dither(2)
|
||||
self.animate_over_time_range(0, 2,
|
||||
self.play_over_time_range(0, 2,
|
||||
Transform(
|
||||
deepcopy(self.first_word), self.number_word,
|
||||
alpha_func = squish_alpha_func(smooth)
|
||||
)
|
||||
)
|
||||
self.animate_over_time_range(2, 4,
|
||||
self.play_over_time_range(2, 4,
|
||||
Transform(
|
||||
self.number_word, self.new_digit,
|
||||
alpha_func = squish_alpha_func(smooth)
|
||||
@@ -181,7 +181,7 @@ class TauPoem(Scene):
|
||||
two, pi = tex_mobject(["2", "\\pi"]).scale(2).split()
|
||||
self.add(two, pi)
|
||||
two_copy = deepcopy(two).rotate(np.pi/10).highlight("yellow")
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
two, two_copy,
|
||||
alpha_func = squish_alpha_func(
|
||||
lambda t : wiggle(t),
|
||||
@@ -203,12 +203,12 @@ class TauPoem(Scene):
|
||||
)
|
||||
self.add(two_pi)
|
||||
self.dither()
|
||||
self.animate(CounterclockwiseTransform(
|
||||
self.play(CounterclockwiseTransform(
|
||||
two_pi, sphere,
|
||||
alpha_func = lambda t : 2*smooth(t/2)
|
||||
))
|
||||
self.remove(two_pi)
|
||||
self.animate(CounterclockwiseTransform(
|
||||
self.play(CounterclockwiseTransform(
|
||||
sphere, tau,
|
||||
alpha_func = lambda t : 2*(smooth(t/2+0.5)-0.5)
|
||||
))
|
||||
@@ -227,11 +227,11 @@ class TauPoem(Scene):
|
||||
for eye in blinked.eyes:
|
||||
eye.highlight("black")
|
||||
self.add(*set(tau.parts).difference(tau.white_parts))
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*eyes)
|
||||
for eyes in zip(blinked.eyes, tau.eyes)
|
||||
])
|
||||
self.animate(ShowCreation(tau.mouth))
|
||||
self.play(ShowCreation(tau.mouth))
|
||||
self.dither(2)
|
||||
|
||||
def line3(self):
|
||||
@@ -239,17 +239,17 @@ class TauPoem(Scene):
|
||||
pi = PiCreature()
|
||||
self.add(*tau.parts)
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(tau.leg, pi.left_leg),
|
||||
ShowCreation(pi.right_leg),
|
||||
run_time = 1.0,
|
||||
)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*parts)
|
||||
for parts in zip(tau.white_parts, pi.white_parts)
|
||||
])
|
||||
self.remove(*tau.parts + pi.parts)
|
||||
self.animate(BlinkPiCreature(pi))
|
||||
self.play(BlinkPiCreature(pi))
|
||||
|
||||
def pi_speaking(self, text):
|
||||
pi = PiCreature()
|
||||
@@ -263,7 +263,7 @@ class TauPoem(Scene):
|
||||
pi, bubble = self.pi_speaking("Conventions matter \\\\ not!")
|
||||
self.add(pi)
|
||||
self.dither()
|
||||
self.animate(Transform(
|
||||
self.play(Transform(
|
||||
Point(bubble.tip).highlight("black"),
|
||||
bubble
|
||||
))
|
||||
@@ -280,11 +280,11 @@ class TauPoem(Scene):
|
||||
formulae = tex_mobject(FORMULAE, size = "\\small")
|
||||
formulae.scale(1.25)
|
||||
formulae.to_corner([1, -1, 0])
|
||||
self.animate(FadeIn(formulae))
|
||||
self.play(FadeIn(formulae))
|
||||
|
||||
def line6(self):
|
||||
bubble = ThoughtBubble()
|
||||
self.animate(ApplyFunction(
|
||||
self.play(ApplyFunction(
|
||||
lambda p : 2 * p / np.linalg.norm(p),
|
||||
bubble,
|
||||
alpha_func = wiggle,
|
||||
@@ -302,10 +302,10 @@ class TauPoem(Scene):
|
||||
self.dither()
|
||||
self.remove(bubble)
|
||||
bubble_copy = deepcopy(bubble)
|
||||
self.animate(CounterclockwiseTransform(bubble_copy, heart))
|
||||
self.play(CounterclockwiseTransform(bubble_copy, heart))
|
||||
self.dither()
|
||||
self.remove(bubble_copy)
|
||||
self.animate(CounterclockwiseTransform(heart, bubble))
|
||||
self.play(CounterclockwiseTransform(heart, bubble))
|
||||
self.dither()
|
||||
|
||||
|
||||
@@ -316,7 +316,7 @@ class TauPoem(Scene):
|
||||
|
||||
self.add(two, *pi.parts)
|
||||
self.dither()
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(pi.left_leg, tau.leg),
|
||||
Transform(
|
||||
pi.right_leg,
|
||||
@@ -343,10 +343,10 @@ class TauPoem(Scene):
|
||||
|
||||
self.add(tau)
|
||||
self.dither()
|
||||
self.animate(Transform(point, pi))
|
||||
self.play(Transform(point, pi))
|
||||
self.remove(point)
|
||||
self.add(pi)
|
||||
self.animate(WaveArm(tau),Transform(pi, new_pi))
|
||||
self.play(WaveArm(tau),Transform(pi, new_pi))
|
||||
|
||||
def line10(self):
|
||||
formulae = tex_mobject(FORMULAE, "\\small")
|
||||
@@ -363,7 +363,7 @@ class TauPoem(Scene):
|
||||
mob.to_edge(LEFT).shift(RIGHT*(SPACE_WIDTH-1))
|
||||
else:
|
||||
mob.shift(2*SPACE_WIDTH*RIGHT)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*mobs, run_time = 2.0)
|
||||
for mobs in zip(formulae, f_copy)
|
||||
])
|
||||
@@ -402,7 +402,7 @@ class TauPoem(Scene):
|
||||
tau.shift(tau_line.get_center() + 0.5*UP)
|
||||
|
||||
self.add(axes, grid)
|
||||
self.animate(
|
||||
self.play(
|
||||
TransformAnimations(
|
||||
ShowCreation(sine),
|
||||
ShowCreation(deepcopy(sine).shift(2*np.pi*interval_size*RIGHT)),
|
||||
@@ -411,7 +411,7 @@ class TauPoem(Scene):
|
||||
),
|
||||
ShowCreation(circle)
|
||||
)
|
||||
self.animate(
|
||||
self.play(
|
||||
CounterclockwiseTransform(sine_period, tau_line),
|
||||
CounterclockwiseTransform(circle, deepcopy(tau_line)),
|
||||
FadeOut(axes),
|
||||
@@ -435,9 +435,9 @@ class TauPoem(Scene):
|
||||
|
||||
self.add(*formula)
|
||||
self.dither()
|
||||
self.animate(CounterclockwiseTransform(two_pi, tau))
|
||||
self.play(CounterclockwiseTransform(two_pi, tau))
|
||||
self.remove(two_pi)
|
||||
self.animate(BlinkPiCreature(tau))
|
||||
self.play(BlinkPiCreature(tau))
|
||||
self.dither()
|
||||
|
||||
def line14(self):
|
||||
@@ -445,7 +445,7 @@ class TauPoem(Scene):
|
||||
"Wait! Area \\\\ of circles"
|
||||
)
|
||||
self.add(pi)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(Point(bubble.tip).highlight("black"), bubble)
|
||||
)
|
||||
|
||||
@@ -461,7 +461,7 @@ class TauPoem(Scene):
|
||||
|
||||
self.add(pi, bubble, *formula)
|
||||
self.dither(2)
|
||||
self.animate(ApplyMethod(half.highlight, "yellow"))
|
||||
self.play(ApplyMethod(half.highlight, "yellow"))
|
||||
|
||||
def line16(self):
|
||||
self.add(tex_mobject(
|
||||
@@ -498,9 +498,9 @@ class TauPoem(Scene):
|
||||
for line in lines:
|
||||
line.highlight("red")
|
||||
|
||||
self.animate(ApplyFunction(trianglify, circle, run_time = 2.0))
|
||||
self.play(ApplyFunction(trianglify, circle, run_time = 2.0))
|
||||
self.add(tau_r, r)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
ShowCreation(line, run_time = 1.0)
|
||||
for line in lines
|
||||
])
|
||||
@@ -521,7 +521,7 @@ class TauPoem(Scene):
|
||||
|
||||
self.add(*pi.parts + tau.parts)
|
||||
self.dither(0.8)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*eyes, run_time = 0.2, alpha_func = rush_into)
|
||||
for eyes in [
|
||||
(tau.left_eye, blinked_tau.left_eye),
|
||||
@@ -529,7 +529,7 @@ class TauPoem(Scene):
|
||||
]
|
||||
])
|
||||
self.remove(tau.left_eye, tau.right_eye)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*eyes, run_time = 0.2, alpha_func = rush_from)
|
||||
for eyes in [
|
||||
(blinked_tau.left_eye, mad_tau.left_eye),
|
||||
@@ -538,7 +538,7 @@ class TauPoem(Scene):
|
||||
])
|
||||
self.remove(blinked_tau.left_eye, blinked_tau.right_eye)
|
||||
self.add(mad_tau.left_eye, mad_tau.right_eye)
|
||||
self.animate(
|
||||
self.play(
|
||||
Transform(tau.arm, mad_tau.arm),
|
||||
Transform(tau.mouth, mad_tau.mouth),
|
||||
run_time = 0.5
|
||||
@@ -546,7 +546,7 @@ class TauPoem(Scene):
|
||||
self.remove(*tau.parts + blinked_tau.parts)
|
||||
self.add(*mad_tau.parts)
|
||||
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*eyes, run_time = 0.2, alpha_func = rush_into)
|
||||
for eyes in [
|
||||
(pi.left_eye, blinked_pi.left_eye),
|
||||
@@ -554,7 +554,7 @@ class TauPoem(Scene):
|
||||
]
|
||||
])
|
||||
self.remove(pi.left_eye, pi.right_eye)
|
||||
self.animate(*[
|
||||
self.play(*[
|
||||
Transform(*eyes, run_time = 0.2, alpha_func = rush_from)
|
||||
for eyes in [
|
||||
(blinked_pi.left_eye, sad_pi.left_eye),
|
||||
@@ -564,7 +564,7 @@ class TauPoem(Scene):
|
||||
Transform(pi.mouth, sad_pi.mouth, run_time = 0.2)
|
||||
])
|
||||
self.remove(*blinked_pi.parts + pi.parts + sad_pi.parts)
|
||||
self.animate(
|
||||
self.play(
|
||||
WalkPiCreature(sad_pi, DOWN+4*LEFT),
|
||||
run_time = 1.0
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user