mirror of
https://github.com/3b1b/manim.git
synced 2025-07-30 13:34:19 +08:00
Refactored tex_utils, and made TexMobject proper objects
This commit is contained in:
@ -57,7 +57,7 @@ LEFT_SIDE = SPACE_WIDTH*LEFT
|
||||
RIGHT_SIDE = SPACE_WIDTH*RIGHT
|
||||
|
||||
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
FILE_DIR = os.path.join(THIS_DIR, "files")
|
||||
FILE_DIR = os.path.join(THIS_DIR, os.pardir, "animation_files")
|
||||
IMAGE_DIR = os.path.join(FILE_DIR, "images")
|
||||
GIF_DIR = os.path.join(FILE_DIR, "gifs")
|
||||
MOVIE_DIR = os.path.join(FILE_DIR, "movies")
|
||||
|
3
mobject/__init__.py
Normal file
3
mobject/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from mobject import *
|
||||
from image_mobject import *
|
||||
from tex_mobject import *
|
@ -5,7 +5,6 @@ from PIL import Image
|
||||
from random import random
|
||||
|
||||
from helpers import *
|
||||
from tex_utils import tex_to_image
|
||||
from mobject import Mobject
|
||||
|
||||
class ImageMobject(Mobject):
|
161
mobject/tex_mobject.py
Normal file
161
mobject/tex_mobject.py
Normal file
@ -0,0 +1,161 @@
|
||||
from mobject import Mobject
|
||||
from image_mobject import ImageMobject
|
||||
from helpers import *
|
||||
|
||||
#TODO, Cleanup and refactor this file.
|
||||
|
||||
class TexMobject(Mobject):
|
||||
DEFAULT_CONFIG = {
|
||||
"template_tex_file" : TEMPLATE_TEX_FILE,
|
||||
"color" : WHITE,
|
||||
"point_thickness" : 1,
|
||||
"should_center" : False,
|
||||
}
|
||||
def __init__(self, expression, **kwargs):
|
||||
if "size" not in kwargs:
|
||||
#Todo, make this more sophisticated.
|
||||
if len("".join(expression)) < MAX_LEN_FOR_HUGE_TEX_FONT:
|
||||
size = "\\Huge"
|
||||
else:
|
||||
size = "\\large"
|
||||
digest_locals(self)
|
||||
Mobject.__init__(self, **kwargs)
|
||||
|
||||
def generate_points(self):
|
||||
image_files = tex_to_image_files(
|
||||
self.expression,
|
||||
self.size,
|
||||
self.template_tex_file
|
||||
)
|
||||
for image_file in image_files:
|
||||
self.add(ImageMobject(image_file))
|
||||
if self.should_center:
|
||||
self.center()
|
||||
self.highlight(self.color)
|
||||
|
||||
|
||||
|
||||
class TextMobject(TexMobject):
|
||||
DEFAULT_CONFIG = {
|
||||
"template_tex_file" : TEMPLATE_TEXT_FILE,
|
||||
"size" : "\\Large", #TODO, auto-adjust?
|
||||
}
|
||||
|
||||
|
||||
class Underbrace(TexMobject):
|
||||
DEFAULT_CONFIG = {
|
||||
"buff" : 0.2,
|
||||
}
|
||||
def __init__(self, left, right, **kwargs):
|
||||
expression = "\\underbrace{%s}"%(14*"\\quad")
|
||||
TexMobject.__init__(self, expression, **kwargs)
|
||||
result.stretch_to_fit_width(right[0]-left[0])
|
||||
result.shift(left - result.points[0] + buff*DOWN)
|
||||
|
||||
|
||||
|
||||
def tex_hash(expression, size):
|
||||
return str(hash(expression + size))
|
||||
|
||||
def tex_to_image_files(expression, size, template_tex_file):
|
||||
"""
|
||||
Returns list of images for correpsonding with a list of expressions
|
||||
"""
|
||||
image_dir = os.path.join(TEX_IMAGE_DIR, tex_hash(expression, size))
|
||||
if os.path.exists(image_dir):
|
||||
return get_sorted_image_list(image_dir)
|
||||
tex_file = generate_tex_file(expression, size, template_tex_file)
|
||||
dvi_file = tex_to_dvi(tex_file)
|
||||
return dvi_to_png(dvi_file)
|
||||
|
||||
|
||||
def generate_tex_file(expression, size, template_tex_file):
|
||||
if isinstance(expression, list):
|
||||
expression = tex_expression_list_as_string(expression)
|
||||
result = os.path.join(TEX_DIR, tex_hash(expression, size))+".tex"
|
||||
if not os.path.exists(result):
|
||||
print "Writing %s at size %s to %s"%(
|
||||
"".join(expression), size, result
|
||||
)
|
||||
with open(template_tex_file, "r") as infile:
|
||||
body = infile.read()
|
||||
body = body.replace(SIZE_TO_REPLACE, size)
|
||||
body = body.replace(TEX_TEXT_TO_REPLACE, expression)
|
||||
with open(result, "w") as outfile:
|
||||
outfile.write(body)
|
||||
return result
|
||||
|
||||
def tex_to_dvi(tex_file):
|
||||
result = tex_file.replace(".tex", ".dvi")
|
||||
if not os.path.exists(filestem + ".dvi"):
|
||||
commands = [
|
||||
"latex",
|
||||
"-interaction=batchmode",
|
||||
"-output-directory=" + TEX_DIR,
|
||||
tex_file,
|
||||
"> /dev/null"
|
||||
]
|
||||
#TODO, Error check
|
||||
os.system(" ".join(commands))
|
||||
return result
|
||||
|
||||
def tex_expression_list_as_string(expression):
|
||||
return "\n".join([
|
||||
"\onslide<%d>{"%count + exp + "}"
|
||||
for count, exp in zip(it.count(1), expression)
|
||||
])
|
||||
|
||||
def dvi_to_png(dvi_file, regen_if_exists = False):
|
||||
"""
|
||||
Converts a dvi, which potentially has multiple slides, into a
|
||||
directory full of enumerated pngs corresponding with these slides.
|
||||
Returns a list of PIL Image objects for these images sorted as they
|
||||
where in the dvi
|
||||
"""
|
||||
directory, filename = os.path.split(dvi_file)
|
||||
name = filename.replace(".dvi", "")
|
||||
images_dir = os.path.join(TEX_IMAGE_DIR, name)
|
||||
if not os.path.exists(images_dir):
|
||||
os.mkdir(images_dir)
|
||||
if os.listdir(images_dir) == [] or regen_if_exists:
|
||||
commands = [
|
||||
"convert",
|
||||
"-density",
|
||||
str(PDF_DENSITY),
|
||||
path,
|
||||
"-size",
|
||||
str(DEFAULT_WIDTH) + "x" + str(DEFAULT_HEIGHT),
|
||||
os.path.join(images_dir, name + ".png")
|
||||
]
|
||||
os.system(" ".join(commands))
|
||||
return get_sorted_image_list(images_dir)
|
||||
|
||||
|
||||
def get_sorted_image_list(images_dir):
|
||||
return sorted([
|
||||
os.path.join(images_dir, name)
|
||||
for name in os.listdir(images_dir)
|
||||
if name.endswith(".png")
|
||||
], cmp_enumerated_files)
|
||||
|
||||
def cmp_enumerated_files(name1, name2):
|
||||
num1, num2 = [
|
||||
int(name.split(".")[0].split("-")[-1])
|
||||
for name in (name1, name2)
|
||||
]
|
||||
return num1 - num2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -195,7 +195,7 @@ class DrawComplexAngleAndMagnitude(Scene):
|
||||
def draw_number(self, tex_representation, number):
|
||||
point = self.plane.number_to_point(number)
|
||||
dot = Dot(point)
|
||||
label = tex_mobject(tex_representation)
|
||||
label = TexMobject(tex_representation)
|
||||
max_width = 0.8*self.plane.unit_to_spatial_width
|
||||
if label.get_width() > max_width:
|
||||
label.scale_to_fit_width(max_width)
|
||||
@ -235,17 +235,17 @@ class DrawComplexAngleAndMagnitude(Scene):
|
||||
# tex_parts = tex_representation.split("+")
|
||||
# elif "-" in tex_representation:
|
||||
# tex_parts = tex_representation.split("-")
|
||||
# x_label, y_label = map(tex_mobject, tex_parts)
|
||||
# x_label, y_label = map(TexMobject, tex_parts)
|
||||
# for label in x_label, y_label:
|
||||
# label.scale_to_fit_height(0.5)
|
||||
# x_label.next_to(x_line, point[1]*DOWN/abs(point[1]))
|
||||
# y_label.next_to(y_line, point[0]*RIGHT/abs(point[0]))
|
||||
norm = np.linalg.norm(point)
|
||||
brace = underbrace(ORIGIN, ORIGIN+norm*RIGHT)
|
||||
brace = Underbrace(ORIGIN, ORIGIN+norm*RIGHT)
|
||||
if point[1] > 0:
|
||||
brace.rotate(np.pi, RIGHT)
|
||||
brace.rotate(np.log(number).imag)
|
||||
norm_label = tex_mobject("%.1f"%abs(number))
|
||||
norm_label = TexMobject("%.1f"%abs(number))
|
||||
norm_label.scale(0.5)
|
||||
axis = OUT if point[1] > 0 else IN
|
||||
norm_label.next_to(brace, rotate_vector(point, np.pi/2, axis))
|
||||
|
@ -81,7 +81,7 @@ COUNT_TO_TIP_POS = {
|
||||
}
|
||||
|
||||
def finger_tip_power_of_2(finger_no):
|
||||
return tex_mobject(str(2**finger_no)).shift(COUNT_TO_TIP_POS[finger_no])
|
||||
return TexMobject(str(2**finger_no)).shift(COUNT_TO_TIP_POS[finger_no])
|
||||
|
||||
class Hand(ImageMobject):
|
||||
STARTING_BOTTOM_RIGHT = [4.61111111e+00, -3.98888889e+00, 9.80454690e-16]
|
||||
@ -114,7 +114,7 @@ class Hand(ImageMobject):
|
||||
# )
|
||||
|
||||
def get_algorithm():
|
||||
return text_mobject(ALGORITHM_TEXT)
|
||||
return TextMobject(ALGORITHM_TEXT)
|
||||
|
||||
def get_finger_colors():
|
||||
return list(Color("yellow").range_to("red", 5))
|
||||
@ -186,7 +186,7 @@ class ShowCounting(OverHand):
|
||||
]
|
||||
|
||||
def get_counting_mob(self, count):
|
||||
mob = tex_mobject(str(count))
|
||||
mob = TexMobject(str(count))
|
||||
mob.scale(2)
|
||||
mob.shift(LEFT)
|
||||
mob.to_edge(UP, buff = 0.1)
|
||||
@ -199,7 +199,7 @@ class ShowFrameNum(OverHand):
|
||||
for frame, count in zip(self.frames, it.count()):
|
||||
print count, "of", len(self.frames)
|
||||
mob = CompoundMobject(*[
|
||||
tex_mobject(char).shift(0.3*x*RIGHT)
|
||||
TexMobject(char).shift(0.3*x*RIGHT)
|
||||
for char, x, in zip(str(count), it.count())
|
||||
])
|
||||
self.frames[count] = disp.paint_mobject(
|
||||
@ -213,7 +213,7 @@ class CountTo1023(Scene):
|
||||
lh_map = get_hand_map("left")
|
||||
def get_num(count):
|
||||
return CompoundMobject(*[
|
||||
tex_mobject(char).shift(0.35*x*RIGHT)
|
||||
TexMobject(char).shift(0.35*x*RIGHT)
|
||||
for char, x, in zip(str(count), it.count())
|
||||
]).center().to_edge(UP)
|
||||
self.frames = [
|
||||
@ -225,7 +225,7 @@ class CountTo1023(Scene):
|
||||
|
||||
class Introduction(Scene):
|
||||
def construct(self):
|
||||
words = text_mobject("""
|
||||
words = TextMobject("""
|
||||
First, let's see how to count
|
||||
to 31 on just one hand...
|
||||
""")
|
||||
@ -242,10 +242,10 @@ class Introduction(Scene):
|
||||
class ShowReadingRule(Scene):
|
||||
def construct(self):
|
||||
sample_counts = [6, 17, 27, 31]
|
||||
question = text_mobject("""
|
||||
question = TextMobject("""
|
||||
How do you recognize what number a given configuration represents?
|
||||
""", size = "\\Huge").scale(0.75).to_corner(UP+LEFT)
|
||||
answer = text_mobject([
|
||||
answer = TextMobject([
|
||||
"Think of each finger as representing a power of 2, ",
|
||||
"then add up the numbers represented by the standing fingers."
|
||||
], size = "\\Huge").scale(0.75).to_corner(UP+LEFT).split()
|
||||
@ -278,7 +278,7 @@ class ShowReadingRule(Scene):
|
||||
count_mobs[1].shift(0.2*DOWN + 0.2*LEFT)
|
||||
if num in [6, 17]:
|
||||
hand.shift(0.8*LEFT)
|
||||
sum_mobs = tex_mobject(
|
||||
sum_mobs = TexMobject(
|
||||
" + ".join([str(2**c) for c in counts]).split(" ") + ["=%d"%num]
|
||||
).to_corner(UP+RIGHT).split()
|
||||
self.add(hand, *count_mobs)
|
||||
@ -298,7 +298,7 @@ class ShowIncrementRule(Scene):
|
||||
def to_left(words):
|
||||
return "\\begin{flushleft}" + words + "\\end{flushleft}"
|
||||
phrases = [
|
||||
text_mobject(to_left(words), size = "\\Huge").scale(0.75).to_corner(UP+LEFT)
|
||||
TextMobject(to_left(words), size = "\\Huge").scale(0.75).to_corner(UP+LEFT)
|
||||
for words in [
|
||||
"But while you're counting, you don't need to think about powers of 2.",
|
||||
"Can you see the pattern for incrementing?",
|
||||
@ -337,7 +337,7 @@ class ShowIncrementRule(Scene):
|
||||
self.frames += [self.frames[-1]]*int(1.0/self.frame_duration)
|
||||
|
||||
def get_arrow_set(self, num):
|
||||
arrow = tex_mobject("\\downarrow", size = "\\Huge")
|
||||
arrow = TexMobject("\\downarrow", size = "\\Huge")
|
||||
arrow.highlight("green")
|
||||
arrow.shift(-arrow.get_bottom())
|
||||
if num == 12:
|
||||
@ -368,17 +368,17 @@ class ShowIncrementRule(Scene):
|
||||
|
||||
class MindFindsShortcuts(Scene):
|
||||
def construct(self):
|
||||
words1 = text_mobject("""
|
||||
words1 = TextMobject("""
|
||||
Before long, your mind starts to recognize certain
|
||||
patterns without needing to perform the addition.
|
||||
""", size = "\\Huge").scale(0.75).to_corner(LEFT+UP)
|
||||
words2 = text_mobject("""
|
||||
words2 = TextMobject("""
|
||||
Which makes it faster to recognize other patterns...
|
||||
""", size = "\\Huge").scale(0.75).to_corner(LEFT+UP)
|
||||
|
||||
hand = Hand(7).scale(0.5).center().shift(DOWN+2*LEFT)
|
||||
sum421 = tex_mobject("4+2+1").shift(DOWN+2*RIGHT)
|
||||
seven = tex_mobject("7").shift(DOWN+6*RIGHT)
|
||||
sum421 = TexMobject("4+2+1").shift(DOWN+2*RIGHT)
|
||||
seven = TexMobject("7").shift(DOWN+6*RIGHT)
|
||||
compound = CompoundMobject(
|
||||
Arrow(hand, sum421),
|
||||
sum421,
|
||||
@ -393,7 +393,7 @@ class MindFindsShortcuts(Scene):
|
||||
self.dither()
|
||||
self.play(
|
||||
Transform(compound, Arrow(hand, seven).highlight("yellow")),
|
||||
ShimmerIn(text_mobject("Directly recognize").shift(1.5*DOWN+2*RIGHT))
|
||||
ShimmerIn(TextMobject("Directly recognize").shift(1.5*DOWN+2*RIGHT))
|
||||
)
|
||||
self.dither()
|
||||
|
||||
@ -406,10 +406,10 @@ class MindFindsShortcuts(Scene):
|
||||
hands[16].shift(LEFT)
|
||||
hands[7].shift(3*RIGHT)
|
||||
for num in 7, 16:
|
||||
hands[num].add(tex_mobject(str(num)).shift(hands[num].get_top()+0.5*UP))
|
||||
plus = tex_mobject("+").shift(DOWN + RIGHT)
|
||||
equals = tex_mobject("=").shift(DOWN + 2.5*LEFT)
|
||||
equals23 = tex_mobject("=23").shift(DOWN + 5.5*RIGHT)
|
||||
hands[num].add(TexMobject(str(num)).shift(hands[num].get_top()+0.5*UP))
|
||||
plus = TexMobject("+").shift(DOWN + RIGHT)
|
||||
equals = TexMobject("=").shift(DOWN + 2.5*LEFT)
|
||||
equals23 = TexMobject("=23").shift(DOWN + 5.5*RIGHT)
|
||||
|
||||
self.add(words2, hands[23])
|
||||
self.dither()
|
||||
@ -434,7 +434,7 @@ class MindFindsShortcuts(Scene):
|
||||
class CountingExampleSentence(ShowCounting):
|
||||
def construct(self):
|
||||
words = "As an example, this is me counting the number of words in this sentence on just one hand!"
|
||||
self.words = text_mobject(words.split(), size = "\\Huge").scale(0.7).to_corner(UP+LEFT, buff = 0.25).split()
|
||||
self.words = TextMobject(words.split(), size = "\\Huge").scale(0.7).to_corner(UP+LEFT, buff = 0.25).split()
|
||||
ShowCounting.construct(self)
|
||||
|
||||
def get_counting_mob(self, num):
|
||||
@ -443,11 +443,11 @@ class CountingExampleSentence(ShowCounting):
|
||||
class FinishCountingExampleSentence(Scene):
|
||||
def construct(self):
|
||||
words = "As an example, this is me counting the number of words in this sentence on just one hand!"
|
||||
words = text_mobject(words, size = "\\Huge").scale(0.7).to_corner(UP+LEFT, buff = 0.25)
|
||||
words = TextMobject(words, size = "\\Huge").scale(0.7).to_corner(UP+LEFT, buff = 0.25)
|
||||
hand = Hand(18)
|
||||
sixteen = tex_mobject("16").shift([0, 2.25, 0])
|
||||
two = tex_mobject("2").shift([3, 3.65, 0])
|
||||
eightteen = tex_mobject("18").shift([1.5, 2.5, 0])
|
||||
sixteen = TexMobject("16").shift([0, 2.25, 0])
|
||||
two = TexMobject("2").shift([3, 3.65, 0])
|
||||
eightteen = TexMobject("18").shift([1.5, 2.5, 0])
|
||||
eightteen.sort_points()
|
||||
comp = CompoundMobject(sixteen, two)
|
||||
self.add(hand, comp, words)
|
||||
@ -457,18 +457,18 @@ class FinishCountingExampleSentence(Scene):
|
||||
|
||||
class Question(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("Left to ponder: Why does this rule for incrementing work?"))
|
||||
self.add(TextMobject("Left to ponder: Why does this rule for incrementing work?"))
|
||||
|
||||
|
||||
class TwoHandStatement(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject(
|
||||
self.add(TextMobject(
|
||||
"With 10 fingers, you can count up to $2^{10} - 1 = 1023$..."
|
||||
))
|
||||
|
||||
class WithToes(Scene):
|
||||
def construct(self):
|
||||
words = text_mobject([
|
||||
words = TextMobject([
|
||||
"If you were dexterous enough to use your toes as well,",
|
||||
"you could count to 1,048,575"
|
||||
]).split()
|
||||
|
@ -23,19 +23,19 @@ DUAL_CYCLE = [3, 4, 5, 6, 1, 0, 2, 3]
|
||||
|
||||
class EulersFormulaWords(Scene):
|
||||
def construct(self):
|
||||
self.add(tex_mobject("V-E+F=2"))
|
||||
self.add(TexMobject("V-E+F=2"))
|
||||
|
||||
class TheTheoremWords(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("The Theorem:"))
|
||||
self.add(TextMobject("The Theorem:"))
|
||||
|
||||
class ProofAtLastWords(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("The Proof At Last..."))
|
||||
self.add(TextMobject("The Proof At Last..."))
|
||||
|
||||
class DualSpanningTreeWords(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("Spanning trees have duals too!"))
|
||||
self.add(TextMobject("Spanning trees have duals too!"))
|
||||
|
||||
class PreferOtherProofDialogue(Scene):
|
||||
def construct(self):
|
||||
@ -63,7 +63,7 @@ class IllustrateDuality(GraphScene):
|
||||
GraphScene.construct(self)
|
||||
self.generate_dual_graph()
|
||||
|
||||
self.add(text_mobject("Duality").to_edge(UP))
|
||||
self.add(TextMobject("Duality").to_edge(UP))
|
||||
self.remove(*self.vertices)
|
||||
def special_alpha(t):
|
||||
if t > 0.5:
|
||||
@ -107,11 +107,11 @@ class IntroduceGraph(GraphScene):
|
||||
for pair in [(4, 5), (0, 5), (1, 5), (7, 1), (8, 3)]
|
||||
]
|
||||
|
||||
connected, planar, graph = text_mobject([
|
||||
connected, planar, graph = TextMobject([
|
||||
"Connected ", "Planar ", "Graph"
|
||||
]).to_edge(UP).split()
|
||||
not_okay = text_mobject("Not Okay").highlight("red")
|
||||
planar_explanation = text_mobject("""
|
||||
not_okay = TextMobject("Not Okay").highlight("red")
|
||||
planar_explanation = TextMobject("""
|
||||
(``Planar'' just means we can draw it without
|
||||
intersecting lines)
|
||||
""", size = "\\small")
|
||||
@ -162,7 +162,7 @@ class OldIntroduceGraphs(GraphScene):
|
||||
self.clear()
|
||||
self.add(*self.edges)
|
||||
self.replace_vertices_with(Face().scale(0.4))
|
||||
friends = text_mobject("Friends").scale(EDGE_ANNOTATION_SCALE_VAL)
|
||||
friends = TextMobject("Friends").scale(EDGE_ANNOTATION_SCALE_VAL)
|
||||
self.annotate_edges(friends.shift((0, friends.get_height()/2, 0)))
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(vertex, Dot(point))
|
||||
@ -178,7 +178,7 @@ class OldIntroduceGraphs(GraphScene):
|
||||
|
||||
class PlanarGraphDefinition(Scene):
|
||||
def construct(self):
|
||||
Not, quote, planar, end_quote = text_mobject([
|
||||
Not, quote, planar, end_quote = TextMobject([
|
||||
"Not \\\\", "``", "Planar", "''",
|
||||
# "no matter how \\\\ hard you try"
|
||||
]).split()
|
||||
@ -233,9 +233,9 @@ class TerminologyFromPolyhedra(GraphScene):
|
||||
])
|
||||
cube.rotate(-np.pi/3, [0, 0, 1])
|
||||
cube.rotate(-np.pi/3, [0, 1, 0])
|
||||
dots_to_vertices = text_mobject("Dots $\\to$ Vertices").to_corner()
|
||||
lines_to_edges = text_mobject("Lines $\\to$ Edges").to_corner()
|
||||
regions_to_faces = text_mobject("Regions $\\to$ Faces").to_corner()
|
||||
dots_to_vertices = TextMobject("Dots $\\to$ Vertices").to_corner()
|
||||
lines_to_edges = TextMobject("Lines $\\to$ Edges").to_corner()
|
||||
regions_to_faces = TextMobject("Regions $\\to$ Faces").to_corner()
|
||||
|
||||
self.clear()
|
||||
# self.play(TransformAnimations(
|
||||
@ -274,7 +274,7 @@ class ThreePiecesOfTerminology(GraphScene):
|
||||
def construct(self):
|
||||
GraphScene.construct(self)
|
||||
terms = cycles, spanning_trees, dual_graphs = [
|
||||
text_mobject(phrase).shift(y*UP).to_edge()
|
||||
TextMobject(phrase).shift(y*UP).to_edge()
|
||||
for phrase, y in [
|
||||
("Cycles", 3),
|
||||
("Spanning Trees", 1),
|
||||
@ -355,8 +355,8 @@ class PathExamples(GraphScene):
|
||||
[(0, 1), (7, 8), (5, 6),],
|
||||
[(5, 0), (0, 2), (0, 1)],
|
||||
]
|
||||
valid_path = text_mobject("Valid \\\\ Path").highlight("green")
|
||||
not_a_path = text_mobject("Not a \\\\ Path").highlight("red")
|
||||
valid_path = TextMobject("Valid \\\\ Path").highlight("green")
|
||||
not_a_path = TextMobject("Not a \\\\ Path").highlight("red")
|
||||
for mob in valid_path, not_a_path:
|
||||
mob.to_edge(UP)
|
||||
kwargs = {"run_time" : 1.0}
|
||||
@ -413,7 +413,7 @@ class IntroduceRandolph(GraphScene):
|
||||
def construct(self):
|
||||
GraphScene.construct(self)
|
||||
randy = Randolph().move_to((-3, 0, 0))
|
||||
name = text_mobject("Randolph")
|
||||
name = TextMobject("Randolph")
|
||||
self.play(Transform(
|
||||
randy,
|
||||
deepcopy(randy).scale(RANDOLPH_SCALE_VAL).move_to(self.points[0]),
|
||||
@ -428,13 +428,13 @@ class DefineSpanningTree(GraphScene):
|
||||
GraphScene.construct(self)
|
||||
randy = Randolph()
|
||||
randy.scale(RANDOLPH_SCALE_VAL).move_to(self.points[0])
|
||||
dollar_signs = text_mobject("\\$\\$")
|
||||
dollar_signs = TextMobject("\\$\\$")
|
||||
dollar_signs.scale(EDGE_ANNOTATION_SCALE_VAL)
|
||||
dollar_signs = CompoundMobject(*[
|
||||
deepcopy(dollar_signs).shift(edge.get_center())
|
||||
for edge in self.edges
|
||||
])
|
||||
unneeded = text_mobject("unneeded!")
|
||||
unneeded = TextMobject("unneeded!")
|
||||
unneeded.scale(EDGE_ANNOTATION_SCALE_VAL)
|
||||
self.generate_spanning_tree()
|
||||
def green_dot_at_index(index):
|
||||
@ -489,8 +489,8 @@ class NamingTree(GraphScene):
|
||||
branches = self.spanning_tree.split()
|
||||
branches_copy = deepcopy(branches)
|
||||
treeified_branches = self.treeified_spanning_tree.split()
|
||||
tree = text_mobject("``Tree''").to_edge(UP)
|
||||
spanning_tree = text_mobject("``Spanning Tree''").to_edge(UP)
|
||||
tree = TextMobject("``Tree''").to_edge(UP)
|
||||
spanning_tree = TextMobject("``Spanning Tree''").to_edge(UP)
|
||||
|
||||
self.add(*branches)
|
||||
self.play(
|
||||
@ -521,7 +521,7 @@ class DualGraph(GraphScene):
|
||||
def construct(self):
|
||||
GraphScene.construct(self)
|
||||
self.generate_dual_graph()
|
||||
self.add(text_mobject("Dual Graph").to_edge(UP).shift(2*LEFT))
|
||||
self.add(TextMobject("Dual Graph").to_edge(UP).shift(2*LEFT))
|
||||
self.play(*[
|
||||
ShowCreation(mob)
|
||||
for mob in self.dual_edges + self.dual_vertices
|
||||
@ -544,7 +544,7 @@ class FacebookGraph(GraphScene):
|
||||
logo.shift(0.2*LEFT + 0.1*UP)
|
||||
account.add(logo).center()
|
||||
account.shift(0.2*LEFT + 0.1*UP)
|
||||
friends = tex_mobject(
|
||||
friends = TexMobject(
|
||||
"\\leftarrow \\text{friends} \\rightarrow"
|
||||
).scale(0.5*EDGE_ANNOTATION_SCALE_VAL)
|
||||
|
||||
@ -591,13 +591,13 @@ class FacebookGraphAsAbstractSet(Scene):
|
||||
"\\text{%s}&\\leftrightarrow\\text{%s}"%(names[i],names[j])
|
||||
for i, j in friend_pairs
|
||||
] + ["\\vdots"])
|
||||
names_mob = text_mobject(names_string).shift(3*LEFT)
|
||||
friends_mob = tex_mobject(
|
||||
names_mob = TextMobject(names_string).shift(3*LEFT)
|
||||
friends_mob = TexMobject(
|
||||
friends_string, size = "\\Large"
|
||||
).shift(3*RIGHT)
|
||||
accounts = text_mobject("\\textbf{Accounts}")
|
||||
accounts = TextMobject("\\textbf{Accounts}")
|
||||
accounts.shift(3*LEFT).to_edge(UP)
|
||||
friendships = text_mobject("\\textbf{Friendships}")
|
||||
friendships = TextMobject("\\textbf{Friendships}")
|
||||
friendships.shift(3*RIGHT).to_edge(UP)
|
||||
lines = CompoundMobject(
|
||||
Line(UP*SPACE_HEIGHT, DOWN*SPACE_HEIGHT),
|
||||
@ -622,7 +622,7 @@ class ExamplesOfGraphs(GraphScene):
|
||||
)
|
||||
GraphScene.construct(self)
|
||||
self.generate_regions()
|
||||
objects, notions = CompoundMobject(*text_mobject(
|
||||
objects, notions = CompoundMobject(*TextMobject(
|
||||
["Objects \\quad\\quad ", "Thing that connects objects"]
|
||||
)).to_corner().shift(0.5*RIGHT).split()
|
||||
horizontal_line = Line(
|
||||
@ -649,8 +649,8 @@ class ExamplesOfGraphs(GraphScene):
|
||||
self.clear()
|
||||
self.add(objects, notions, horizontal_line, vertical_line)
|
||||
for (obj, notion), height in zip(objects_and_notions, it.count(2, -1)):
|
||||
obj_mob = text_mobject(obj, size = "\\small").to_edge(LEFT)
|
||||
not_mob = text_mobject(notion, size = "\\small").to_edge(LEFT)
|
||||
obj_mob = TextMobject(obj, size = "\\small").to_edge(LEFT)
|
||||
not_mob = TextMobject(notion, size = "\\small").to_edge(LEFT)
|
||||
not_mob.shift((vert_line_x_val + SPACE_WIDTH)*RIGHT)
|
||||
obj_mob.shift(height*UP)
|
||||
not_mob.shift(height*UP)
|
||||
@ -666,7 +666,7 @@ class ExamplesOfGraphs(GraphScene):
|
||||
self.dither()
|
||||
|
||||
def handle_english_words(self, words1, words2):
|
||||
words = map(text_mobject, ["graph", "grape", "gape", "gripe"])
|
||||
words = map(TextMobject, ["graph", "grape", "gape", "gripe"])
|
||||
words[0].shift(RIGHT)
|
||||
words[1].shift(3*RIGHT)
|
||||
words[2].shift(3*RIGHT + 2*UP)
|
||||
@ -701,9 +701,9 @@ class ExamplesOfGraphs(GraphScene):
|
||||
def handle_dual_graph(self, words1, words2):
|
||||
words1.highlight("yellow")
|
||||
words2.highlight("yellow")
|
||||
connected = text_mobject("Connected")
|
||||
connected = TextMobject("Connected")
|
||||
connected.highlight("lightgreen")
|
||||
not_connected = text_mobject("Not Connected")
|
||||
not_connected = TextMobject("Not Connected")
|
||||
not_connected.highlight("red")
|
||||
for mob in connected, not_connected:
|
||||
mob.shift(self.points[3] + UP)
|
||||
@ -818,7 +818,7 @@ class EdgesAreTheSame(GraphScene):
|
||||
])
|
||||
self.dither()
|
||||
self.add(
|
||||
text_mobject("""
|
||||
TextMobject("""
|
||||
(Or at least I would argue they should \\\\
|
||||
be thought of as the same thing.)
|
||||
""", size = "\\small").to_edge(UP)
|
||||
@ -839,11 +839,11 @@ class ListOfCorrespondances(Scene):
|
||||
for corr in correspondances:
|
||||
corr[0] += " original graph"
|
||||
corr[1] += " dual graph"
|
||||
arrow = tex_mobject("\\leftrightarrow", size = "\\large")
|
||||
arrow = TexMobject("\\leftrightarrow", size = "\\large")
|
||||
lines = []
|
||||
for corr, height in zip(correspondances, it.count(3, -1)):
|
||||
left = text_mobject(corr[0], size = "\\small")
|
||||
right = text_mobject(corr[1], size = "\\small")
|
||||
left = TextMobject(corr[0], size = "\\small")
|
||||
right = TextMobject(corr[1], size = "\\small")
|
||||
this_arrow = deepcopy(arrow)
|
||||
for mob in left, right, this_arrow:
|
||||
mob.shift(height*UP)
|
||||
@ -917,7 +917,7 @@ class IntroduceMortimer(GraphScene):
|
||||
self.generate_regions()
|
||||
randy = Randolph().shift(LEFT)
|
||||
morty = Mortimer().shift(RIGHT)
|
||||
name = text_mobject("Mortimer")
|
||||
name = TextMobject("Mortimer")
|
||||
name.shift(morty.get_center() + 1.2*UP)
|
||||
randy_path = (0, 1, 3)
|
||||
morty_path = (-2, -3, -4)
|
||||
@ -1031,7 +1031,7 @@ class MortimerCannotTraverseCycle(GraphScene):
|
||||
morty = Mortimer().scale(RANDOLPH_SCALE_VAL)
|
||||
morty.move_to(self.dual_points[dual_cycle[0]])
|
||||
time_per_edge = 0.5
|
||||
text = text_mobject("""
|
||||
text = TextMobject("""
|
||||
One of these lines must be included
|
||||
in the spanning tree if those two inner
|
||||
vertices are to be reached.
|
||||
@ -1073,14 +1073,14 @@ class MortimerCannotTraverseCycle(GraphScene):
|
||||
|
||||
class TwoPropertiesOfSpanningTree(Scene):
|
||||
def construct(self):
|
||||
spanning, tree = text_mobject(
|
||||
spanning, tree = TextMobject(
|
||||
["Spanning ", "Tree"],
|
||||
size = "\\Huge"
|
||||
).split()
|
||||
spanning_explanation = text_mobject("""
|
||||
spanning_explanation = TextMobject("""
|
||||
Touches every vertex
|
||||
""").shift(spanning.get_center() + 2*DOWN)
|
||||
tree_explanation = text_mobject("""
|
||||
tree_explanation = TextMobject("""
|
||||
No Cycles
|
||||
""").shift(tree.get_center() + 2*UP)
|
||||
|
||||
@ -1111,7 +1111,7 @@ class DualSpanningTree(GraphScene):
|
||||
morty.scale(RANDOLPH_SCALE_VAL)
|
||||
morty.move_to(self.dual_points[0])
|
||||
dual_edges = [1, 3, 4, 7, 11, 9, 13]
|
||||
words = text_mobject("""
|
||||
words = TextMobject("""
|
||||
The red edges form a spanning tree of the dual graph!
|
||||
""").to_edge(UP)
|
||||
|
||||
@ -1125,7 +1125,7 @@ class DualSpanningTree(GraphScene):
|
||||
class TreeCountFormula(Scene):
|
||||
def construct(self):
|
||||
time_per_branch = 0.5
|
||||
text = text_mobject("""
|
||||
text = TextMobject("""
|
||||
In any tree:
|
||||
$$E + 1 = V$$
|
||||
""")
|
||||
@ -1157,7 +1157,7 @@ class TreeCountFormula(Scene):
|
||||
|
||||
class FinalSum(Scene):
|
||||
def construct(self):
|
||||
lines = tex_mobject([
|
||||
lines = TexMobject([
|
||||
"(\\text{Number of Randolph's Edges}) + 1 &= V \\\\ \n",
|
||||
"(\\text{Number of Mortimer's Edges}) + 1 &= F \\\\ \n",
|
||||
" \\Downarrow \\\\", "E","+","2","&=","V","+","F",
|
||||
@ -1167,10 +1167,10 @@ class FinalSum(Scene):
|
||||
self.dither()
|
||||
self.dither()
|
||||
|
||||
symbols = V, minus, E, plus, F, equals, two = tex_mobject(
|
||||
symbols = V, minus, E, plus, F, equals, two = TexMobject(
|
||||
"V - E + F = 2".split(" ")
|
||||
)
|
||||
plus = tex_mobject("+")
|
||||
plus = TexMobject("+")
|
||||
anims = []
|
||||
for mob, index in zip(symbols, [-3, -2, -7, -6, -1, -4, -5]):
|
||||
copy = plus if index == -2 else deepcopy(mob)
|
||||
|
@ -47,7 +47,7 @@ class LogoGeneration(Scene):
|
||||
lambda point: np.linalg.norm(point) < \
|
||||
self.INNER_RADIUS_RATIO*self.LOGO_RADIUS
|
||||
)
|
||||
name = text_mobject("3Blue1Brown").center()
|
||||
name = TextMobject("3Blue1Brown").center()
|
||||
name.highlight("grey")
|
||||
name.shift(2*DOWN)
|
||||
|
||||
|
@ -76,13 +76,13 @@ NUM_INTERVAL_TICKS = 16
|
||||
|
||||
|
||||
def divergent_sum():
|
||||
return tex_mobject(DIVERGENT_SUM_TEXT, size = "\\large").scale(2)
|
||||
return TexMobject(DIVERGENT_SUM_TEXT, size = "\\large").scale(2)
|
||||
|
||||
def convergent_sum():
|
||||
return tex_mobject(CONVERGENT_SUM_TEXT, size = "\\large").scale(2)
|
||||
return TexMobject(CONVERGENT_SUM_TEXT, size = "\\large").scale(2)
|
||||
|
||||
def underbrace(left, right):
|
||||
result = tex_mobject("\\underbrace{%s}"%(14*"\\quad"))
|
||||
def Underbrace(left, right):
|
||||
result = TexMobject("\\Underbrace{%s}"%(14*"\\quad"))
|
||||
result.stretch_to_fit_width(right[0]-left[0])
|
||||
result.shift(left - result.points[0])
|
||||
return result
|
||||
@ -94,8 +94,8 @@ def zero_to_one_interval():
|
||||
)
|
||||
interval.elongate_tick_at(-INTERVAL_RADIUS, 4)
|
||||
interval.elongate_tick_at(INTERVAL_RADIUS, 4)
|
||||
zero = tex_mobject("0").shift(INTERVAL_RADIUS*LEFT+DOWN)
|
||||
one = tex_mobject("1").shift(INTERVAL_RADIUS*RIGHT+DOWN)
|
||||
zero = TexMobject("0").shift(INTERVAL_RADIUS*LEFT+DOWN)
|
||||
one = TexMobject("1").shift(INTERVAL_RADIUS*RIGHT+DOWN)
|
||||
return CompoundMobject(interval, zero, one)
|
||||
|
||||
def draw_you(with_bubble = False):
|
||||
@ -132,7 +132,7 @@ class FlipThroughNumbers(Animation):
|
||||
self.start_center = start_center
|
||||
self.end_center = end_center
|
||||
self.current_number = function(start)
|
||||
mobject = tex_mobject(str(self.current_number)).shift(start_center)
|
||||
mobject = TexMobject(str(self.current_number)).shift(start_center)
|
||||
Animation.__init__(self, mobject, **kwargs)
|
||||
|
||||
def update_mobject(self, alpha):
|
||||
@ -141,7 +141,7 @@ class FlipThroughNumbers(Animation):
|
||||
)
|
||||
if new_number != self.current_number:
|
||||
self.current_number = new_number
|
||||
self.mobject = tex_mobject(str(new_number)).shift(self.start_center)
|
||||
self.mobject = TexMobject(str(new_number)).shift(self.start_center)
|
||||
if not all(self.start_center == self.end_center):
|
||||
self.mobject.center().shift(
|
||||
(1-alpha)*self.start_center + alpha*self.end_center
|
||||
@ -154,7 +154,7 @@ class IntroduceDivergentSum(Scene):
|
||||
def construct(self):
|
||||
equation = divergent_sum().split()
|
||||
sum_value = None
|
||||
brace = underbrace(
|
||||
brace = Underbrace(
|
||||
equation[0].get_boundary_point(DOWN+LEFT),
|
||||
equation[1].get_boundary_point(DOWN+RIGHT)
|
||||
).shift(0.2*DOWN)
|
||||
@ -170,7 +170,7 @@ class IntroduceDivergentSum(Scene):
|
||||
brace.to_edge(LEFT, buff = SPACE_WIDTH+min_x_coord)
|
||||
if sum_value:
|
||||
self.remove(sum_value)
|
||||
sum_value = tex_mobject(str(2**(x+1) - 1))
|
||||
sum_value = TexMobject(str(2**(x+1) - 1))
|
||||
sum_value.shift(brace.get_center() + 0.5*DOWN)
|
||||
self.add(brace, sum_value)
|
||||
self.dither(0.75)
|
||||
@ -203,9 +203,9 @@ class ClearlyNonsense(Scene):
|
||||
def construct(self):
|
||||
number_line = NumberLine().add_numbers()
|
||||
div_sum = divergent_sum()
|
||||
this_way = text_mobject("Sum goes this way...")
|
||||
this_way = TextMobject("Sum goes this way...")
|
||||
this_way.to_edge(LEFT).shift(RIGHT*(SPACE_WIDTH+1) + DOWN)
|
||||
how_here = text_mobject("How does it end up here?")
|
||||
how_here = TextMobject("How does it end up here?")
|
||||
how_here.shift(1.5*UP+LEFT)
|
||||
neg_1_arrow = Arrow(
|
||||
(-1, 0.3, 0),
|
||||
@ -237,7 +237,7 @@ class OutlineOfVideo(Scene):
|
||||
def construct(self):
|
||||
conv_sum = convergent_sum().scale(0.5)
|
||||
div_sum = divergent_sum().scale(0.5)
|
||||
overbrace = underbrace(
|
||||
overbrace = Underbrace(
|
||||
conv_sum.get_left(),
|
||||
conv_sum.get_right()
|
||||
).rotate(np.pi, RIGHT).shift(0.75*UP*conv_sum.get_height())
|
||||
@ -247,14 +247,14 @@ class OutlineOfVideo(Scene):
|
||||
dots.get_bottom(),
|
||||
direction = UP+LEFT
|
||||
)
|
||||
u_brace = underbrace(div_sum.get_left(), div_sum.get_right())
|
||||
u_brace = Underbrace(div_sum.get_left(), div_sum.get_right())
|
||||
u_brace.shift(1.5*div_sum.get_bottom())
|
||||
for mob in conv_sum, overbrace, arrow, dots:
|
||||
mob.shift(2*UP)
|
||||
for mob in div_sum, u_brace:
|
||||
mob.shift(DOWN)
|
||||
texts = [
|
||||
text_mobject(words).highlight("yellow")
|
||||
TextMobject(words).highlight("yellow")
|
||||
for words in [
|
||||
"1. Discover this",
|
||||
"2. Clarify what this means",
|
||||
@ -288,7 +288,7 @@ class OutlineOfVideo(Scene):
|
||||
|
||||
# # class ReasonsForMakingVideo(Scene):
|
||||
# # def construct(self):
|
||||
# # text = text_mobject([
|
||||
# # text = TextMobject([
|
||||
# # """
|
||||
# # \\begin{itemize}
|
||||
# # \\item Understand what ``$
|
||||
@ -320,9 +320,9 @@ class OutlineOfVideo(Scene):
|
||||
|
||||
# class DiscoverAndDefine(Scene):
|
||||
# def construct(self):
|
||||
# sum_mob = tex_mobject("\\sum_{n = 1}^\\infty a_n")
|
||||
# discover = text_mobject("What does it feel like to discover these?")
|
||||
# define = text_mobject([
|
||||
# sum_mob = TexMobject("\\sum_{n = 1}^\\infty a_n")
|
||||
# discover = TextMobject("What does it feel like to discover these?")
|
||||
# define = TextMobject([
|
||||
# "What does it feel like to",
|
||||
# "\\emph{define} ",
|
||||
# "them?"
|
||||
@ -341,7 +341,7 @@ class OutlineOfVideo(Scene):
|
||||
class YouAsMathematician(Scene):
|
||||
def construct(self):
|
||||
you, bubble = draw_you(with_bubble = True)
|
||||
explanation = text_mobject(
|
||||
explanation = TextMobject(
|
||||
"You as a (questionably accurate portrayal of a) mathematician.",
|
||||
size = "\\small"
|
||||
).shift([2, you.get_center()[1], 0])
|
||||
@ -473,7 +473,7 @@ class DanceDotOnInterval(Scene):
|
||||
for x in LEFT, RIGHT
|
||||
]
|
||||
color_range = Color("green").range_to("yellow", num_written_terms)
|
||||
conv_sum = tex_mobject(sum_terms, size = "\\large").split()
|
||||
conv_sum = TexMobject(sum_terms, size = "\\large").split()
|
||||
|
||||
self.add(interval)
|
||||
self.play(*[
|
||||
@ -510,7 +510,7 @@ class DanceDotOnInterval(Scene):
|
||||
self.dither()
|
||||
|
||||
def write_partial_sums(self):
|
||||
partial_sums = tex_mobject(PARTIAL_CONVERGENT_SUMS_TEXT, size = "\\small")
|
||||
partial_sums = TexMobject(PARTIAL_CONVERGENT_SUMS_TEXT, size = "\\small")
|
||||
partial_sums.scale(1.5).to_edge(UP)
|
||||
partial_sum_parts = partial_sums.split()
|
||||
partial_sum_parts[0].highlight("yellow")
|
||||
@ -525,7 +525,7 @@ class DanceDotOnInterval(Scene):
|
||||
|
||||
class OrganizePartialSums(Scene):
|
||||
def construct(self):
|
||||
partial_sums = tex_mobject(PARTIAL_CONVERGENT_SUMS_TEXT, size = "\\small")
|
||||
partial_sums = TexMobject(PARTIAL_CONVERGENT_SUMS_TEXT, size = "\\small")
|
||||
partial_sums.scale(1.5).to_edge(UP)
|
||||
partial_sum_parts = partial_sums.split()
|
||||
for x in [0] + range(2, len(partial_sum_parts), 4):
|
||||
@ -549,11 +549,11 @@ class OrganizePartialSums(Scene):
|
||||
for mob in partial_sum_parts
|
||||
if mob not in pure_sums
|
||||
])
|
||||
down_arrow = tex_mobject("\\downarrow")
|
||||
down_arrow = TexMobject("\\downarrow")
|
||||
down_arrow.to_edge(LEFT).shift(2*RIGHT+2*DOWN)
|
||||
dots = tex_mobject("\\vdots")
|
||||
dots = TexMobject("\\vdots")
|
||||
dots.shift(down_arrow.get_center()+down_arrow.get_height()*UP)
|
||||
infinite_sum = tex_mobject("".join(CONVERGENT_SUM_TEXT[:-1]), size = "\\samll")
|
||||
infinite_sum = TexMobject("".join(CONVERGENT_SUM_TEXT[:-1]), size = "\\samll")
|
||||
infinite_sum.scale(1.5/1.25)
|
||||
infinite_sum.to_corner(DOWN+LEFT).shift(2*RIGHT)
|
||||
|
||||
@ -589,7 +589,7 @@ class SeeNumbersApproachOne(Scene):
|
||||
|
||||
class OneAndInfiniteSumAreTheSameThing(Scene):
|
||||
def construct(self):
|
||||
one, equals, inf_sum = tex_mobject([
|
||||
one, equals, inf_sum = TexMobject([
|
||||
"1", "=", "\\sum_{n=1}^\\infty \\frac{1}{2^n}"
|
||||
]).split()
|
||||
point = Point(equals.get_center()).highlight("black")
|
||||
@ -609,12 +609,12 @@ class OneAndInfiniteSumAreTheSameThing(Scene):
|
||||
class HowDoYouDefineInfiniteSums(Scene):
|
||||
def construct(self):
|
||||
you = draw_you().center().rewire_part_attributes()
|
||||
text = text_mobject(
|
||||
text = TextMobject(
|
||||
["How", " do", " you,\\\\", "\\emph{define}"],
|
||||
size = "\\Huge"
|
||||
).shift(UP).split()
|
||||
text[-1].shift(3*DOWN).highlight("skyblue")
|
||||
sum_mob = tex_mobject("\\sum_{n=0}^\\infty{a_n}")
|
||||
sum_mob = TexMobject("\\sum_{n=0}^\\infty{a_n}")
|
||||
text[-1].shift(LEFT)
|
||||
sum_mob.shift(text[-1].get_center()+2*RIGHT)
|
||||
|
||||
@ -633,18 +633,18 @@ class HowDoYouDefineInfiniteSums(Scene):
|
||||
|
||||
class LessAboutNewThoughts(Scene):
|
||||
def construct(self):
|
||||
words = generating, new, thoughts, to, definitions = text_mobject([
|
||||
words = generating, new, thoughts, to, definitions = TextMobject([
|
||||
"Generating", " new", " thoughts", "$\\rightarrow$",
|
||||
"useful definitions"
|
||||
], size = "\\large").split()
|
||||
gen_cross = tex_mobject("\\hline").highlight("red")
|
||||
gen_cross = TexMobject("\\hline").highlight("red")
|
||||
new_cross = deepcopy(gen_cross)
|
||||
for cross, mob in [(gen_cross, generating), (new_cross, new)]:
|
||||
cross.replace(mob)
|
||||
cross.stretch_to_fit_height(0.03)
|
||||
disecting = text_mobject("Disecting").highlight("green")
|
||||
disecting = TextMobject("Disecting").highlight("green")
|
||||
disecting.shift(generating.get_center() + 0.6*UP)
|
||||
old = text_mobject("old").highlight("green")
|
||||
old = TextMobject("old").highlight("green")
|
||||
old.shift(new.get_center()+0.6*UP)
|
||||
|
||||
kwargs = {"run_time" : 0.25}
|
||||
@ -660,7 +660,7 @@ class LessAboutNewThoughts(Scene):
|
||||
|
||||
class ListOfPartialSums(Scene):
|
||||
def construct(self):
|
||||
all_terms = np.array(tex_mobject(
|
||||
all_terms = np.array(TexMobject(
|
||||
ALT_PARTIAL_SUM_TEXT,
|
||||
size = "\\large"
|
||||
).split())
|
||||
@ -739,11 +739,11 @@ class CircleZoomInOnOne(Scene):
|
||||
for n in range(10)
|
||||
])
|
||||
circle = Circle().shift(2*RIGHT)
|
||||
text = text_mobject(
|
||||
text = TextMobject(
|
||||
"All but finitely many dots fall inside even the tiniest circle."
|
||||
)
|
||||
numbers = map(
|
||||
lambda s : tex_mobject("\\frac{1}{%s}"%s),
|
||||
lambda s : TexMobject("\\frac{1}{%s}"%s),
|
||||
["100", "1,000,000", "g_{g_{64}}"]
|
||||
)
|
||||
for num in numbers + [text]:
|
||||
@ -784,7 +784,7 @@ class ZoomInOnOne(Scene):
|
||||
nl_with_nums = deepcopy(number_line).add_numbers()
|
||||
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)
|
||||
TexMobject(str(n)).scale(0.5).shift(0.4*DOWN+2*(-1+n)*RIGHT)
|
||||
for n in 0, 1, 2
|
||||
]
|
||||
self.play(
|
||||
@ -801,7 +801,7 @@ class ZoomInOnOne(Scene):
|
||||
|
||||
def zoom_with_numbers(self, numbers, next_numbers):
|
||||
all_numbers = map(
|
||||
lambda (n, u): tex_mobject(str(n)).scale(0.5).shift(0.4*DOWN+2*u*RIGHT),
|
||||
lambda (n, u): TexMobject(str(n)).scale(0.5).shift(0.4*DOWN+2*u*RIGHT),
|
||||
zip(numbers+next_numbers, it.cycle([-1, 1]))
|
||||
)
|
||||
|
||||
@ -844,7 +844,7 @@ class DefineInfiniteSum(Scene):
|
||||
|
||||
def put_expression_in_corner(self):
|
||||
buff = 0.24
|
||||
define, infinite_sum = tex_mobject([
|
||||
define, infinite_sum = TexMobject([
|
||||
"\\text{\\emph{Define} }",
|
||||
"\\sum_{n = 0}^\\infty a_n = X"
|
||||
]).split()
|
||||
@ -879,10 +879,10 @@ class DefineInfiniteSum(Scene):
|
||||
]
|
||||
for n in range(num_terms)
|
||||
])
|
||||
terms = tex_mobject(term_strings, size = "\\large").split()
|
||||
terms = TexMobject(term_strings, size = "\\large").split()
|
||||
number_line = NumberLine()
|
||||
ex_point = 2*RIGHT
|
||||
ex = tex_mobject("X").shift(ex_point + LEFT + UP)
|
||||
ex = TexMobject("X").shift(ex_point + LEFT + UP)
|
||||
arrow = Arrow(ex_point, tail = ex.points[-1]).nudge()
|
||||
|
||||
for term, count in zip(terms, it.count()):
|
||||
@ -928,7 +928,7 @@ class DefineInfiniteSum(Scene):
|
||||
|
||||
class YouJustInventedSomeMath(Scene):
|
||||
def construct(self):
|
||||
text = text_mobject([
|
||||
text = TextMobject([
|
||||
"You ", "just ", "invented\\\\", "some ", "math"
|
||||
]).split()
|
||||
for mob in text[:3]:
|
||||
@ -959,7 +959,7 @@ class SeekMoreGeneralTruths(Scene):
|
||||
"\\frac{(-1)^n}{(2n)!}",
|
||||
"\\frac{2\sqrt{2}}{99^2}\\frac{(4n)!}{(n!)^4} \\cdot \\frac{26390n + 1103}{396^{4k}}",
|
||||
]
|
||||
sums = tex_mobject([
|
||||
sums = TexMobject([
|
||||
"&\\sum_{n = 0}^\\infty" + summand + "= ? \\\\"
|
||||
for summand in summands
|
||||
], size = "")
|
||||
@ -984,7 +984,7 @@ class ChopIntervalInProportions(Scene):
|
||||
num_terms = 2
|
||||
left_terms, right_terms = [
|
||||
[
|
||||
tex_mobject("\\frac{%d}{%d}"%(k, (10**(count+1))))
|
||||
TexMobject("\\frac{%d}{%d}"%(k, (10**(count+1))))
|
||||
for count in range(num_terms)
|
||||
]
|
||||
for k in 9, 1
|
||||
@ -992,19 +992,19 @@ class ChopIntervalInProportions(Scene):
|
||||
if mode == "p":
|
||||
num_terms = 4
|
||||
prop = 0.7
|
||||
left_terms = map(tex_mobject, ["(1-p)", ["p","(1-p)"]]+[
|
||||
left_terms = map(TexMobject, ["(1-p)", ["p","(1-p)"]]+[
|
||||
["p^%d"%(count), "(1-p)"]
|
||||
for count in range(2, num_terms)
|
||||
])
|
||||
right_terms = map(tex_mobject, ["p"] + [
|
||||
right_terms = map(TexMobject, ["p"] + [
|
||||
["p", "^%d"%(count+1)]
|
||||
for count in range(1, num_terms)
|
||||
])
|
||||
interval = zero_to_one_interval()
|
||||
left = INTERVAL_RADIUS*LEFT
|
||||
right = INTERVAL_RADIUS*RIGHT
|
||||
left_paren = tex_mobject("(")
|
||||
right_paren = tex_mobject(")").shift(right + 1.1*UP)
|
||||
left_paren = TexMobject("(")
|
||||
right_paren = TexMobject(")").shift(right + 1.1*UP)
|
||||
curr = left.astype("float")
|
||||
brace_to_replace = None
|
||||
term_to_replace = None
|
||||
@ -1015,7 +1015,7 @@ class ChopIntervalInProportions(Scene):
|
||||
last = deepcopy(curr)
|
||||
curr += 2*RIGHT*INTERVAL_RADIUS*(1-prop)*(prop**count)
|
||||
braces = [
|
||||
underbrace(a, b).rotate(np.pi, RIGHT)
|
||||
Underbrace(a, b).rotate(np.pi, RIGHT)
|
||||
for a, b in [(last, curr), (curr, right)]
|
||||
]
|
||||
for term, brace, count2 in zip([lt, rt], braces, it.count()):
|
||||
@ -1098,7 +1098,7 @@ class ChopIntervalInProportions(Scene):
|
||||
brace_to_replace = braces[1]
|
||||
term_to_replace = rt
|
||||
if mode == "9":
|
||||
split_100 = tex_mobject("\\frac{9}{1000}+\\frac{1}{1000}")
|
||||
split_100 = TexMobject("\\frac{9}{1000}+\\frac{1}{1000}")
|
||||
split_100.scale(0.5)
|
||||
split_100.shift(right_terms[-1].get_center())
|
||||
split_100.to_edge(RIGHT)
|
||||
@ -1166,7 +1166,7 @@ class PointNineRepeating(RearrangeEquation):
|
||||
4 : 4,
|
||||
6 : 5,
|
||||
}
|
||||
for term in tex_mobject(start_terms).split():
|
||||
for term in TexMobject(start_terms).split():
|
||||
self.add(term)
|
||||
self.dither(0.5)
|
||||
self.clear()
|
||||
@ -1182,11 +1182,11 @@ class PointNineRepeating(RearrangeEquation):
|
||||
class PlugNumbersIntoRightside(Scene):
|
||||
def construct(self):
|
||||
scale_factor = 1.5
|
||||
lhs, rhs = tex_mobject(
|
||||
lhs, rhs = TexMobject(
|
||||
["1 + p + p^2 + p^3 + \\cdots = ", "\\frac{1}{1-p}"],
|
||||
size = "\\large"
|
||||
).scale(scale_factor).split()
|
||||
rhs = tex_mobject(
|
||||
rhs = TexMobject(
|
||||
["1 \\over 1 - ", "p"],
|
||||
size = "\\large"
|
||||
).replace(rhs).split()
|
||||
@ -1195,7 +1195,7 @@ class PlugNumbersIntoRightside(Scene):
|
||||
"0.2", "27", "i"
|
||||
]
|
||||
nums = [
|
||||
tex_mobject(num_string, size="\\large")
|
||||
TexMobject(num_string, size="\\large")
|
||||
for num_string in num_strings
|
||||
]
|
||||
for num, num_string in zip(nums, num_strings):
|
||||
@ -1205,10 +1205,10 @@ class PlugNumbersIntoRightside(Scene):
|
||||
num.highlight("green")
|
||||
if num_string == "(-1)":
|
||||
num.shift(0.3*RIGHT)
|
||||
right_words = text_mobject(
|
||||
right_words = TextMobject(
|
||||
"This side makes sense for almost any value of $p$,"
|
||||
).shift(2*UP)
|
||||
left_words = text_mobject(
|
||||
left_words = TextMobject(
|
||||
"even if it seems like this side will not."
|
||||
).shift(2*DOWN)
|
||||
right_words.add(Arrow(
|
||||
@ -1318,11 +1318,11 @@ class ListPartialDivergentSums(Scene):
|
||||
"\\\\"
|
||||
for n in range(num_lines)
|
||||
]
|
||||
terms = tex_mobject(
|
||||
terms = TexMobject(
|
||||
list(it.chain.from_iterable(zip(rhss, lhss))) + ["\\vdots&", ""],
|
||||
size = "\\large"
|
||||
).shift(RIGHT).split()
|
||||
words = text_mobject("These numbers don't \\\\ approach anything")
|
||||
words = TextMobject("These numbers don't \\\\ approach anything")
|
||||
words.to_edge(LEFT)
|
||||
arrow = Arrow(3*DOWN+2*LEFT, direction = DOWN, length = 6)
|
||||
|
||||
@ -1339,8 +1339,8 @@ class ListPartialDivergentSums(Scene):
|
||||
class NotARobot(Scene):
|
||||
def construct(self):
|
||||
you = draw_you().center()
|
||||
top_words = text_mobject("You are a mathematician,")
|
||||
low_words = text_mobject("not a robot.")
|
||||
top_words = TextMobject("You are a mathematician,")
|
||||
low_words = TextMobject("not a robot.")
|
||||
top_words.shift(1.5*UP)
|
||||
low_words.shift(1.5*DOWN)
|
||||
|
||||
@ -1361,22 +1361,22 @@ class SumPowersOfTwoAnimation(Scene):
|
||||
bottom_brace_left = left + 0.3*DOWN
|
||||
circle = Circle().scale(dot_width[0]/2).shift(left+dot_width/2)
|
||||
curr_dots = deepcopy(dot).shift(left+1.5*dot_width+dot_buff)
|
||||
topbrace = underbrace(top_brace_left, right).rotate(np.pi, RIGHT)
|
||||
bottombrace = underbrace(bottom_brace_left, right)
|
||||
topbrace = Underbrace(top_brace_left, right).rotate(np.pi, RIGHT)
|
||||
bottombrace = Underbrace(bottom_brace_left, right)
|
||||
colors = Color("yellow").range_to("purple", iterations)
|
||||
curr_dots.highlight(colors.next())
|
||||
equation = tex_mobject(
|
||||
equation = TexMobject(
|
||||
"1+2+4+\\cdots+2^n=2^{n+1} - 1",
|
||||
size = "\\Huge"
|
||||
).shift(3*UP)
|
||||
full_top_sum = tex_mobject(["1", "+2", "+4", "+8", "+16"]).split()
|
||||
full_top_sum = TexMobject(["1", "+2", "+4", "+8", "+16"]).split()
|
||||
|
||||
self.add(equation)
|
||||
self.dither()
|
||||
self.add(circle, curr_dots, topbrace, bottombrace)
|
||||
for n in range(1,iterations):
|
||||
bottom_num = tex_mobject(str(2**n))
|
||||
new_bottom_num = tex_mobject(str(2**(n+1)))
|
||||
bottom_num = TexMobject(str(2**n))
|
||||
new_bottom_num = TexMobject(str(2**(n+1)))
|
||||
bottom_num.shift(bottombrace.get_center()+0.5*DOWN)
|
||||
|
||||
top_sum = CompoundMobject(*full_top_sum[:n]).center()
|
||||
@ -1396,8 +1396,8 @@ class SumPowersOfTwoAnimation(Scene):
|
||||
alt_bottom_num = deepcopy(bottom_num).shift(shift_val)
|
||||
alt_topbrace = deepcopy(alt_bottombrace).rotate(np.pi, RIGHT)
|
||||
top_sum_end.shift(alt_topbrace.get_center()+0.5*UP)
|
||||
new_topbrace = underbrace(top_brace_left, right).rotate(np.pi, RIGHT)
|
||||
new_bottombrace = underbrace(bottom_brace_left, right)
|
||||
new_topbrace = Underbrace(top_brace_left, right).rotate(np.pi, RIGHT)
|
||||
new_bottombrace = Underbrace(bottom_brace_left, right)
|
||||
new_bottom_num.shift(new_bottombrace.get_center()+0.5*DOWN)
|
||||
new_top_sum.shift(new_topbrace.get_center()+0.5*UP)
|
||||
for exp, brace in [
|
||||
@ -1446,7 +1446,7 @@ class PretendTheyDoApproachNegativeOne(RearrangeEquation):
|
||||
num_lines = 6
|
||||
da = "\\downarrow"
|
||||
columns = [
|
||||
tex_mobject("\\\\".join([
|
||||
TexMobject("\\\\".join([
|
||||
n_func(n)
|
||||
for n in range(num_lines)
|
||||
]+last_bits), size = "\\Large").to_corner(UP+LEFT)
|
||||
@ -1477,15 +1477,15 @@ class DistanceBetweenRationalNumbers(Scene):
|
||||
def construct(self):
|
||||
locii = [2*LEFT, 2*RIGHT]
|
||||
nums = [
|
||||
tex_mobject(s).shift(1.3*d)
|
||||
TexMobject(s).shift(1.3*d)
|
||||
for s, d in zip(["\\frac{1}{2}", "3"], locii)
|
||||
]
|
||||
arrows = [
|
||||
Arrow(direction, tail = ORIGIN)
|
||||
for direction in locii
|
||||
]
|
||||
dist = tex_mobject("\\frac{5}{2}").scale(0.5).shift(0.5*UP)
|
||||
text = text_mobject("How we define distance between rational numbers")
|
||||
dist = TexMobject("\\frac{5}{2}").scale(0.5).shift(0.5*UP)
|
||||
text = TextMobject("How we define distance between rational numbers")
|
||||
text.to_edge(UP)
|
||||
self.add(text, *nums)
|
||||
self.play(*[ShowCreation(arrow) for arrow in arrows])
|
||||
@ -1497,7 +1497,7 @@ class NotTheOnlyWayToOrganize(Scene):
|
||||
self.play(ShowCreation(NumberLine().add_numbers()))
|
||||
self.dither()
|
||||
words = "Is there any other reasonable way to organize numbers?"
|
||||
self.play(FadeIn(text_mobject(words).shift(2*UP)))
|
||||
self.play(FadeIn(TextMobject(words).shift(2*UP)))
|
||||
self.dither()
|
||||
|
||||
class DistanceIsAFunction(Scene):
|
||||
@ -1517,7 +1517,7 @@ class DistanceIsAFunction(Scene):
|
||||
dist_text = "random\\_dist"
|
||||
elif mode == "2adic":
|
||||
dist_text = "2\\_adic\\_dist"
|
||||
dist, r_paren, arg0, comma, arg1, l_paren, equals, result = text_mobject([
|
||||
dist, r_paren, arg0, comma, arg1, l_paren, equals, result = TextMobject([
|
||||
dist_text, "(", "000", ",", "000", ")", "=", "000"
|
||||
]).split()
|
||||
point_origin = comma.get_center()+0.2*UP
|
||||
@ -1551,9 +1551,9 @@ class DistanceIsAFunction(Scene):
|
||||
self.dither()
|
||||
example_mobs = [
|
||||
(
|
||||
tex_mobject(tup[0]).shift(arg0.get_center()),
|
||||
tex_mobject(tup[1]).shift(arg1.get_center()),
|
||||
tex_mobject(tup[2]).shift(result.get_center())
|
||||
TexMobject(tup[0]).shift(arg0.get_center()),
|
||||
TexMobject(tup[1]).shift(arg1.get_center()),
|
||||
TexMobject(tup[2]).shift(result.get_center())
|
||||
)
|
||||
for tup in examples
|
||||
]
|
||||
@ -1578,13 +1578,13 @@ class DistanceIsAFunction(Scene):
|
||||
class ShiftInvarianceNumberLine(Scene):
|
||||
def construct(self):
|
||||
number_line = NumberLine().add_numbers()
|
||||
topbrace = underbrace(ORIGIN, 2*RIGHT).rotate(np.pi, RIGHT)
|
||||
dist0 = text_mobject(["dist(", "$0$", ",", "$2$",")"])
|
||||
dist1 = text_mobject(["dist(", "$2$", ",", "$4$",")"])
|
||||
topbrace = Underbrace(ORIGIN, 2*RIGHT).rotate(np.pi, RIGHT)
|
||||
dist0 = TextMobject(["dist(", "$0$", ",", "$2$",")"])
|
||||
dist1 = TextMobject(["dist(", "$2$", ",", "$4$",")"])
|
||||
for dist in dist0, dist1:
|
||||
dist.shift(topbrace.get_center()+0.3*UP)
|
||||
dist1.shift(2*RIGHT)
|
||||
footnote = text_mobject("""
|
||||
footnote = TextMobject("""
|
||||
\\begin{flushleft}
|
||||
*yeah yeah, I know I'm still drawing them on a line,
|
||||
but until a few minutes from now I have no other way
|
||||
@ -1606,19 +1606,19 @@ class ShiftInvarianceNumberLine(Scene):
|
||||
|
||||
class NameShiftInvarianceProperty(Scene):
|
||||
def construct(self):
|
||||
prop = text_mobject([
|
||||
prop = TextMobject([
|
||||
"dist($A$, $B$) = dist(",
|
||||
"$A+x$, $B+x$",
|
||||
") \\quad for all $x$"
|
||||
])
|
||||
mid_part = prop.split()[1]
|
||||
u_brace = underbrace(
|
||||
u_brace = Underbrace(
|
||||
mid_part.get_boundary_point(DOWN+LEFT),
|
||||
mid_part.get_boundary_point(DOWN+RIGHT)
|
||||
).shift(0.3*DOWN)
|
||||
label = text_mobject("Shifted values")
|
||||
label = TextMobject("Shifted values")
|
||||
label.shift(u_brace.get_center()+0.5*DOWN)
|
||||
name = text_mobject("``Shift Invariance''")
|
||||
name = TextMobject("``Shift Invariance''")
|
||||
name.highlight("green").to_edge(UP)
|
||||
for mob in u_brace, label:
|
||||
mob.highlight("yellow")
|
||||
@ -1634,7 +1634,7 @@ class TriangleInequality(Scene):
|
||||
def construct(self):
|
||||
symbols = ["A", "B", "C"]
|
||||
locations = [2*(DOWN+LEFT), UP, 4*RIGHT]
|
||||
ab, plus, bc, greater_than, ac = text_mobject([
|
||||
ab, plus, bc, greater_than, ac = TextMobject([
|
||||
"dist($A$, $B$)",
|
||||
"$+$",
|
||||
"dist($B$, $C$)",
|
||||
@ -1656,7 +1656,7 @@ class TriangleInequality(Scene):
|
||||
for dist, line in zip(all_dists, all_lines)
|
||||
]
|
||||
for symbol, loc in zip(symbols, locations):
|
||||
self.add(tex_mobject(symbol).shift(loc))
|
||||
self.add(TexMobject(symbol).shift(loc))
|
||||
self.play(ShowCreation(ac_line), FadeIn(ac_copy))
|
||||
self.dither()
|
||||
self.play(*[
|
||||
@ -1679,12 +1679,12 @@ class TriangleInequality(Scene):
|
||||
class StruggleToFindFrameOfMind(Scene):
|
||||
def construct(self):
|
||||
you, bubble = draw_you(with_bubble = True)
|
||||
questions = text_mobject("???", size = "\\Huge").scale(1.5)
|
||||
questions = TextMobject("???", size = "\\Huge").scale(1.5)
|
||||
contents = [
|
||||
tex_mobject("2, 4, 8, 16, 32, \\dots \\rightarrow 0"),
|
||||
text_mobject("dist(0, 2) $<$ dist(0, 64)"),
|
||||
TexMobject("2, 4, 8, 16, 32, \\dots \\rightarrow 0"),
|
||||
TextMobject("dist(0, 2) $<$ dist(0, 64)"),
|
||||
NumberLine().sort_points(lambda p : -p[1]).add(
|
||||
text_mobject("Not on a line?").shift(UP)
|
||||
TextMobject("Not on a line?").shift(UP)
|
||||
),
|
||||
]
|
||||
kwargs = {"run_time" : 0.5}
|
||||
@ -1759,11 +1759,11 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
|
||||
def draw_numbers(self, zero_local, zero_one_width):
|
||||
num_numbers = 5
|
||||
zero = tex_mobject("0").shift(zero_local)
|
||||
zero = TexMobject("0").shift(zero_local)
|
||||
self.add(zero)
|
||||
nums = []
|
||||
for n in range(num_numbers):
|
||||
num = tex_mobject(str(2**n))
|
||||
num = TexMobject(str(2**n))
|
||||
num.scale(1.0/(n+1))
|
||||
num.shift(
|
||||
zero_local+\
|
||||
@ -1820,7 +1820,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
for mob, count in zip(new_power_mobs, it.count(1)):
|
||||
self.center_in_closest_rect(mob, small_rects)
|
||||
new_power_mobs[-1].shift(DOWN)
|
||||
dots = tex_mobject("\\vdots")
|
||||
dots = TexMobject("\\vdots")
|
||||
dots.scale(0.5).shift(new_zero.get_center()+0.5*DOWN)
|
||||
self.play(
|
||||
Transform(zero, new_zero),
|
||||
@ -1859,7 +1859,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
ApplyMethod(mob.shift, shift_val)
|
||||
for mob in zero_copy, power_mob_copy
|
||||
])
|
||||
num_mobs[n] = tex_mobject(str(n))
|
||||
num_mobs[n] = TexMobject(str(n))
|
||||
num_mobs[n].scale(1.0/(power_of_divisor(n, 2)+1))
|
||||
width_ratio = max_width / num_mobs[n].get_width()
|
||||
if width_ratio < 1:
|
||||
@ -1882,7 +1882,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
mobject.shift(diffs[np.argmin(map(np.linalg.norm, diffs))])
|
||||
|
||||
def add_negative_one(self, num_mobs):
|
||||
neg_one = tex_mobject("-1").scale(0.5)
|
||||
neg_one = TexMobject("-1").scale(0.5)
|
||||
shift_val = num_mobs[15].get_center()-neg_one.get_center()
|
||||
neg_one.shift(UP)
|
||||
self.play(ApplyMethod(neg_one.shift, shift_val))
|
||||
@ -1897,7 +1897,7 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
dist_string = "1"
|
||||
else:
|
||||
dist_string = "$\\frac{1}{%d}$"%(2**count)
|
||||
text = text_mobject(
|
||||
text = TextMobject(
|
||||
"Any of these pairs are considered to be a distance " +\
|
||||
dist_string +\
|
||||
" away from each other"
|
||||
@ -1934,10 +1934,10 @@ class RoomsAndSubroomsWithNumbers(Scene):
|
||||
|
||||
class DeduceWhereNegativeOneFalls(Scene):
|
||||
def construct(self):
|
||||
part0, arg0, part1, part2, arg1, part3 = text_mobject([
|
||||
part0, arg0, part1, part2, arg1, part3 = TextMobject([
|
||||
"dist(-1, ", "0000", ") = ", "dist(0, ", "0000", ")"
|
||||
]).scale(1.5).split()
|
||||
u_brace = underbrace(
|
||||
u_brace = Underbrace(
|
||||
part2.get_boundary_point(DOWN+LEFT),
|
||||
part3.get_boundary_point(DOWN+RIGHT)
|
||||
).shift(0.3+DOWN)
|
||||
@ -1947,7 +1947,7 @@ class DeduceWhereNegativeOneFalls(Scene):
|
||||
texts = [
|
||||
CompoundMobject(parts[0], parts[1].highlight(color))
|
||||
for count, color in zip(it.count(), colors)
|
||||
for parts in [text_mobject([
|
||||
for parts in [TextMobject([
|
||||
"Represented (heuristically) \\\\ by being in the same \\\\",
|
||||
(count*"sub-")+"room"
|
||||
]).split()]
|
||||
@ -1961,7 +1961,7 @@ class DeduceWhereNegativeOneFalls(Scene):
|
||||
for n in range(1, 15):
|
||||
rest_time = 0.3 + 1.0/(n+1)
|
||||
new_args = [
|
||||
text_mobject("$%d$"%k).scale(1.5)
|
||||
TextMobject("$%d$"%k).scale(1.5)
|
||||
for k in 2**n-1, 2**n
|
||||
]
|
||||
for new_arg, old_arg in zip(new_args, last_args):
|
||||
@ -1986,7 +1986,7 @@ class DeduceWhereNegativeOneFalls(Scene):
|
||||
class OtherRationalNumbers(Scene):
|
||||
def construct(self):
|
||||
import random
|
||||
self.add(text_mobject("Where do other \\\\ rational numbers fall?"))
|
||||
self.add(TextMobject("Where do other \\\\ rational numbers fall?"))
|
||||
pairs = [
|
||||
(1, 2),
|
||||
(1, 3),
|
||||
@ -2002,17 +2002,17 @@ class OtherRationalNumbers(Scene):
|
||||
3*DOWN,
|
||||
]
|
||||
for pair, locus in zip(pairs, locii):
|
||||
fraction = tex_mobject("\\frac{%d}{%d}"%pair).shift(locus)
|
||||
fraction = TexMobject("\\frac{%d}{%d}"%pair).shift(locus)
|
||||
self.play(ShimmerIn(fraction))
|
||||
self.dither()
|
||||
|
||||
class PAdicMetric(Scene):
|
||||
def construct(self):
|
||||
p_str, text = text_mobject(["$p$", "-adic metric"]).shift(2*UP).split()
|
||||
primes = [tex_mobject(str(p)) for p in [2, 3, 5, 7, 11, 13, 17, 19, 23]]
|
||||
p_str, text = TextMobject(["$p$", "-adic metric"]).shift(2*UP).split()
|
||||
primes = [TexMobject(str(p)) for p in [2, 3, 5, 7, 11, 13, 17, 19, 23]]
|
||||
p_str.highlight("yellow")
|
||||
colors = Color("green").range_to("skyblue", len(primes))
|
||||
new_numbers = text_mobject("Completely new types of numbers!")
|
||||
new_numbers = TextMobject("Completely new types of numbers!")
|
||||
new_numbers.highlight("skyblue").shift(2.3*DOWN)
|
||||
arrow = Arrow(2*DOWN, tail = 1.7*UP)
|
||||
|
||||
@ -2048,19 +2048,19 @@ class PAdicMetric(Scene):
|
||||
|
||||
class FuzzyDiscoveryToNewMath(Scene):
|
||||
def construct(self):
|
||||
fuzzy = text_mobject("Fuzzy Discovery")
|
||||
fuzzy = TextMobject("Fuzzy Discovery")
|
||||
fuzzy.to_edge(UP).shift(SPACE_WIDTH*LEFT/2)
|
||||
new_math = text_mobject("New Math")
|
||||
new_math = TextMobject("New Math")
|
||||
new_math.to_edge(UP).shift(SPACE_WIDTH*RIGHT/2)
|
||||
lines = CompoundMobject(
|
||||
Line(DOWN*SPACE_HEIGHT, UP*SPACE_HEIGHT),
|
||||
Line(3*UP+LEFT*SPACE_WIDTH, 3*UP+RIGHT*SPACE_WIDTH)
|
||||
)
|
||||
fuzzy_discoveries = [
|
||||
tex_mobject("a^2 + b^2 = c^2"),
|
||||
tex_mobject("".join(CONVERGENT_SUM_TEXT)),
|
||||
tex_mobject("".join(DIVERGENT_SUM_TEXT)),
|
||||
tex_mobject("e^{\pi i} = -1"),
|
||||
TexMobject("a^2 + b^2 = c^2"),
|
||||
TexMobject("".join(CONVERGENT_SUM_TEXT)),
|
||||
TexMobject("".join(DIVERGENT_SUM_TEXT)),
|
||||
TexMobject("e^{\pi i} = -1"),
|
||||
]
|
||||
triangle_lines = [
|
||||
Line(ORIGIN, LEFT),
|
||||
@ -2069,21 +2069,21 @@ class FuzzyDiscoveryToNewMath(Scene):
|
||||
]
|
||||
for line, char in zip(triangle_lines, ["a", "c", "b"]):
|
||||
line.highlight("blue")
|
||||
char_mob = tex_mobject(char).scale(0.25)
|
||||
char_mob = TexMobject(char).scale(0.25)
|
||||
line.add(char_mob.shift(line.get_center()))
|
||||
triangle = CompoundMobject(*triangle_lines)
|
||||
triangle.center().shift(1.5*fuzzy_discoveries[0].get_right())
|
||||
how_length = text_mobject("But how is length defined?").scale(0.5)
|
||||
how_length = TextMobject("But how is length defined?").scale(0.5)
|
||||
how_length.shift(0.75*DOWN)
|
||||
fuzzy_discoveries[0].add(triangle, how_length)
|
||||
new_maths = [
|
||||
text_mobject("""
|
||||
TextMobject("""
|
||||
Define distance between points $(x_0, y_0)$ and
|
||||
$(x_1, y_1)$ as $\\sqrt{(x_1-x_0)^2 + (y_1-y_0)^2}$
|
||||
"""),
|
||||
text_mobject("Define ``approach'' and infinite sums"),
|
||||
text_mobject("Discover $2$-adic numbers"),
|
||||
text_mobject(
|
||||
TextMobject("Define ``approach'' and infinite sums"),
|
||||
TextMobject("Discover $2$-adic numbers"),
|
||||
TextMobject(
|
||||
"Realize exponentiation is doing something much \
|
||||
different from repeated multiplication"
|
||||
)
|
||||
@ -2112,13 +2112,13 @@ class FuzzyDiscoveryToNewMath(Scene):
|
||||
|
||||
class DiscoveryAndInvention(Scene):
|
||||
def construct(self):
|
||||
invention, vs, discovery = text_mobject([
|
||||
invention, vs, discovery = TextMobject([
|
||||
"Invention ", "vs. ", "Discovery"
|
||||
]).split()
|
||||
nrd = text_mobject(
|
||||
nrd = TextMobject(
|
||||
"Non-rigorous truths"
|
||||
).shift(2*UP)
|
||||
rt = text_mobject(
|
||||
rt = TextMobject(
|
||||
"Rigorous terms"
|
||||
).shift(2*DOWN)
|
||||
|
||||
|
@ -37,7 +37,7 @@ class SimpleText(Scene):
|
||||
return initials(filter(lambda c : c in string.letters + " ", text))
|
||||
|
||||
def construct(self, text):
|
||||
self.add(text_mobject(text))
|
||||
self.add(TextMobject(text))
|
||||
|
||||
|
||||
class SimpleTex(Scene):
|
||||
@ -56,12 +56,12 @@ class SimpleTex(Scene):
|
||||
return words
|
||||
|
||||
def construct(self, expression, words):
|
||||
self.add(tex_mobject(expression))
|
||||
self.add(TexMobject(expression))
|
||||
|
||||
|
||||
class OneMinusOnePoem(Scene):
|
||||
def construct(self):
|
||||
verse1 = text_mobject("""
|
||||
verse1 = TextMobject("""
|
||||
\\begin{flushleft}
|
||||
When one takes one from one \\\\
|
||||
plus one from one plus one \\\\
|
||||
@ -75,7 +75,7 @@ class OneMinusOnePoem(Scene):
|
||||
until the infinite. \\\\
|
||||
\\end{flushleft}
|
||||
""").scale(0.5).to_corner(UP+LEFT)
|
||||
verse2 = text_mobject("""
|
||||
verse2 = TextMobject("""
|
||||
\\begin{flushleft}
|
||||
Lest you should think that such \\\\
|
||||
less well-known sums are much \\\\
|
||||
@ -89,7 +89,7 @@ class OneMinusOnePoem(Scene):
|
||||
the universe gives ``half''. \\\\
|
||||
\\end{flushleft}
|
||||
""").scale(0.5).to_corner(DOWN+LEFT)
|
||||
equation = tex_mobject(
|
||||
equation = TexMobject(
|
||||
"1-1+1-1+\\cdots = \\frac{1}{2}"
|
||||
)
|
||||
self.add(verse1, verse2, equation)
|
||||
@ -111,7 +111,7 @@ class PowersOfTwoSmall(Scene):
|
||||
|
||||
class FinalSlide(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("""
|
||||
self.add(TextMobject("""
|
||||
\\begin{flushleft}
|
||||
Needless to say, what I said here only scratches the
|
||||
surface of the tip of the iceberg of the p-adic metric.
|
||||
|
@ -17,7 +17,7 @@ def matrix_to_string(matrix):
|
||||
return "--".join(["-".join(map(str, row)) for row in matrix])
|
||||
|
||||
def matrix_mobject(matrix):
|
||||
return text_mobject(
|
||||
return TextMobject(
|
||||
"""
|
||||
\\left(
|
||||
\\begin{array}{%s}
|
||||
@ -100,7 +100,7 @@ class ExamplesOfNonlinearOneDimensionalTransforms(NumberLineScene):
|
||||
return (np.sin(x) + 1.2*x, y, z)
|
||||
def shift_zero((x, y, z)):
|
||||
return (2*x+4, y, z)
|
||||
self.nonlinear = text_mobject("Not a Linear Transform")
|
||||
self.nonlinear = TextMobject("Not a Linear Transform")
|
||||
self.nonlinear.highlight(LIGHT_RED).to_edge(UP, buff = 1.5)
|
||||
pairs = [
|
||||
(sinx_plux_x, "numbers don't remain evenly spaced"),
|
||||
@ -118,7 +118,7 @@ class ExamplesOfNonlinearOneDimensionalTransforms(NumberLineScene):
|
||||
"density" : 5*DEFAULT_POINT_DENSITY_1D,
|
||||
}
|
||||
NumberLineScene.construct(self, **config)
|
||||
words = text_mobject(explanation).highlight(LIGHT_RED)
|
||||
words = TextMobject(explanation).highlight(LIGHT_RED)
|
||||
words.next_to(self.nonlinear, DOWN, buff = 0.5)
|
||||
self.add(words)
|
||||
|
||||
@ -300,7 +300,7 @@ class ExamplesOfNonlinearTwoDimensionalTransformations(Scene):
|
||||
return (x+np.sin(y), y+np.cos(x), z)
|
||||
def shift_zero((x, y, z)):
|
||||
return (2*x + 3*y + 4, -1*x+y+2, z)
|
||||
self.nonlinear = text_mobject("Nonlinear Transform")
|
||||
self.nonlinear = TextMobject("Nonlinear Transform")
|
||||
self.nonlinear.highlight(LIGHT_RED)
|
||||
self.nonlinear.to_edge(UP, buff = 1.5)
|
||||
pairs = [
|
||||
@ -322,7 +322,7 @@ class ExamplesOfNonlinearTwoDimensionalTransformations(Scene):
|
||||
}
|
||||
number_plane = NumberPlane(**config)
|
||||
numbers = number_plane.get_coordinate_labels()
|
||||
words = text_mobject(explanation)
|
||||
words = TextMobject(explanation)
|
||||
words.highlight(LIGHT_RED)
|
||||
words.next_to(self.nonlinear, DOWN, buff = 0.5)
|
||||
|
||||
@ -356,7 +356,7 @@ class ExamplesOfNonlinearTwoDimensionalTransformations(Scene):
|
||||
|
||||
region = region_from_polygon_vertices(*vertices)
|
||||
image = disp.paint_region(region, color = WHITE)
|
||||
self.blackness = text_mobject("")
|
||||
self.blackness = TextMobject("")
|
||||
ImageMobject.generate_points_from_image_array(self.blackness, image)
|
||||
self.blackness.highlight(BLACK)
|
||||
rectangle = Rectangle(width = 7, height=1.7)
|
||||
@ -375,7 +375,7 @@ class TrickyExamplesOfNonlinearTwoDimensionalTransformations(Scene):
|
||||
"point_thickness" : 2*DEFAULT_POINT_THICKNESS
|
||||
}
|
||||
number_plane = NumberPlane(**config)
|
||||
phrase1, phrase2 = text_mobject([
|
||||
phrase1, phrase2 = TextMobject([
|
||||
"These might look like they keep lines straight...",
|
||||
"but diagonal lines get curved"
|
||||
]).to_edge(UP, buff = 1.5).split()
|
||||
@ -427,7 +427,7 @@ class TrickyExamplesOfNonlinearTwoDimensionalTransformations(Scene):
|
||||
|
||||
region = region_from_polygon_vertices(*vertices)
|
||||
image = disp.paint_region(region, color = WHITE)
|
||||
self.blackness = text_mobject("")
|
||||
self.blackness = TextMobject("")
|
||||
ImageMobject.generate_points_from_image_array(self.blackness, image)
|
||||
self.blackness.highlight(BLACK)
|
||||
rectangle = Rectangle(width = 9, height=1.5)
|
||||
|
@ -61,7 +61,7 @@ def count_sections(*radians):
|
||||
|
||||
last_num = None
|
||||
for reg, count in zip(regions, it.count(1)):
|
||||
number = tex_mobject(str(count)).shift((RADIUS, 3, 0))
|
||||
number = TexMobject(str(count)).shift((RADIUS, 3, 0))
|
||||
sc.highlight_region(reg)
|
||||
rt = 1.0 / (x**0.8)
|
||||
sc.add(number)
|
||||
@ -89,7 +89,7 @@ def summarize_pattern(*radians):
|
||||
new_lines = CompoundMobject(*[
|
||||
Line(points[x], points[y]) for y in xrange(x)
|
||||
])
|
||||
num = tex_mobject(str(moser_function(x + 1))).center()
|
||||
num = TexMobject(str(moser_function(x + 1))).center()
|
||||
sc.animate(
|
||||
Transform(last_num, num) if last_num else ShowCreation(num),
|
||||
FadeIn(new_lines),
|
||||
@ -127,7 +127,7 @@ def connect_points(*radians):
|
||||
def interesting_problems():
|
||||
sc = Scene()
|
||||
locales = [(6, 2, 0), (6, -2, 0), (-5, -2, 0)]
|
||||
fermat = CompoundMobject(*tex_mobjects(["x^n","+","y^n","=","z^n"]))
|
||||
fermat = CompoundMobject(*TexMobjects(["x^n","+","y^n","=","z^n"]))
|
||||
fermat.scale(0.5).shift((-2.5, 0.7, 0))
|
||||
face = SimpleFace()
|
||||
tb = ThoughtBubble().shift((-1.5, 1, 0))
|
||||
@ -274,13 +274,13 @@ if __name__ == '__main__':
|
||||
# summarize_pattern(*different_radians).write_to_movie("moser/PatternWithDifferentPoints")
|
||||
|
||||
#Images
|
||||
# tex_mobject(r"""
|
||||
# \underbrace{1, 2, 4, 8, 16, 31, \dots}_\text{What?}
|
||||
# TexMobject(r"""
|
||||
# \Underbrace{1, 2, 4, 8, 16, 31, \dots}_\text{What?}
|
||||
# """).save_image("moser/NumberList31")
|
||||
# tex_mobject("""
|
||||
# TexMobject("""
|
||||
# 1, 2, 4, 8, 16, 32, 63, \dots
|
||||
# """).save_image("moser/NumberList63")
|
||||
# tex_mobject("""
|
||||
# TexMobject("""
|
||||
# 1, 2, 4, 8, 15, \dots
|
||||
# """).save_image("moser/NumberList15")
|
||||
|
||||
|
@ -51,7 +51,7 @@ class CircleScene(Scene):
|
||||
]
|
||||
self.dots = [Dot(point) for point in self.points]
|
||||
self.lines = [Line(p1, p2) for p1, p2 in it.combinations(self.points, 2)]
|
||||
self.n_equals = tex_mobject(
|
||||
self.n_equals = TexMobject(
|
||||
"n=%d"%len(radians),
|
||||
).shift((-SPACE_WIDTH+1, SPACE_HEIGHT-1.5, 0))
|
||||
self.add(self.circle, self.n_equals, *self.dots + self.lines)
|
||||
@ -149,7 +149,7 @@ class MoserPattern(CircleScene):
|
||||
def __init__(self, radians, *args, **kwargs):
|
||||
CircleScene.__init__(self, radians, *args, **kwargs)
|
||||
self.remove(*self.dots + self.lines + [self.n_equals])
|
||||
n_equals, num = tex_mobject(["n=", "10"]).split()
|
||||
n_equals, num = TexMobject(["n=", "10"]).split()
|
||||
for mob in n_equals, num:
|
||||
mob.shift((-SPACE_WIDTH + 1.5, SPACE_HEIGHT - 1.5, 0))
|
||||
self.add(n_equals)
|
||||
@ -157,8 +157,8 @@ class MoserPattern(CircleScene):
|
||||
self.add(*self.dots[:n])
|
||||
self.add(*[Line(p[0], p[1]) for p in it.combinations(self.points[:n], 2)])
|
||||
tex_stuffs = [
|
||||
tex_mobject(str(moser_function(n))),
|
||||
tex_mobject(str(n)).shift(num.get_center())
|
||||
TexMobject(str(moser_function(n))),
|
||||
TexMobject(str(n)).shift(num.get_center())
|
||||
]
|
||||
self.add(*tex_stuffs)
|
||||
self.dither(0.5)
|
||||
@ -176,14 +176,14 @@ class HardProblemsSimplerQuestions(Scene):
|
||||
fermat = dict([
|
||||
(
|
||||
sym,
|
||||
CompoundMobject(*tex_mobjects(
|
||||
CompoundMobject(*TexMobjects(
|
||||
["x","^"+sym,"+","y","^"+sym,"=","z","^"+sym]
|
||||
))
|
||||
)
|
||||
for sym in ["n", "2", "3"]
|
||||
])
|
||||
# not_that_hard = text_mobject("(maybe not that hard...)").scale(0.5)
|
||||
fermat2, fermat2_jargon = tex_mobject([
|
||||
# not_that_hard = TextMobject("(maybe not that hard...)").scale(0.5)
|
||||
fermat2, fermat2_jargon = TexMobject([
|
||||
r"&x^2 + y^2 = z^2 \\",
|
||||
r"""
|
||||
&(3, 4, 5) \\
|
||||
@ -194,7 +194,7 @@ class HardProblemsSimplerQuestions(Scene):
|
||||
&\quad \vdots
|
||||
"""
|
||||
]).split()
|
||||
fermat3, fermat3_jargon = tex_mobject([
|
||||
fermat3, fermat3_jargon = TexMobject([
|
||||
r"&x^3 + y^3 = z^3\\",
|
||||
r"""
|
||||
&y^3 = (z - x)(z - \omega x)(z - \omega^2 x) \\
|
||||
@ -237,7 +237,7 @@ class HardProblemsSimplerQuestions(Scene):
|
||||
circle_grid = CompoundMobject(
|
||||
Circle(),
|
||||
Grid(radius = 2),
|
||||
tex_mobject(r"\mathds{R}^2").shift((2, -2, 0))
|
||||
TexMobject(r"\mathds{R}^2").shift((2, -2, 0))
|
||||
)
|
||||
start_line = Line((-1, 0, 0), (-1, 2, 0))
|
||||
end_line = Line((-1, 0, 0), (-1, -2, 0))
|
||||
@ -246,7 +246,7 @@ class HardProblemsSimplerQuestions(Scene):
|
||||
|
||||
other_grid = CompoundMobject(
|
||||
Grid(radius = 2),
|
||||
tex_mobject(r"\mathds{C}").shift((2, -2, 0))
|
||||
TexMobject(r"\mathds{C}").shift((2, -2, 0))
|
||||
)
|
||||
omega = np.array((0.5, 0.5*np.sqrt(3), 0))
|
||||
dots = CompoundMobject(*[
|
||||
@ -283,9 +283,9 @@ class CountLines(CircleScene):
|
||||
#TODO, Count things explicitly?
|
||||
text_center = (self.radius + 1, self.radius -1, 0)
|
||||
scale_factor = 0.4
|
||||
text = tex_mobject(r"\text{How Many Lines?}", size = r"\large")
|
||||
text = TexMobject(r"\text{How Many Lines?}", size = r"\large")
|
||||
n = len(radians)
|
||||
formula, answer = tex_mobject([
|
||||
formula, answer = TexMobject([
|
||||
r"{%d \choose 2} = \frac{%d(%d - 1)}{2} = "%(n, n, n),
|
||||
str(choose(n, 2))
|
||||
])
|
||||
@ -330,9 +330,9 @@ class CountIntersectionPoints(CircleScene):
|
||||
text_center = (self.radius + 0.5, self.radius -0.5, 0)
|
||||
size = r"\large"
|
||||
scale_factor = 0.4
|
||||
text = tex_mobject(r"\text{How Many Intersection Points?}", size = size)
|
||||
text = TexMobject(r"\text{How Many Intersection Points?}", size = size)
|
||||
n = len(radians)
|
||||
formula, answer = tex_mobject([
|
||||
formula, answer = TexMobject([
|
||||
r"{%d \choose 4} = \frac{%d(%d - 1)(%d - 2)(%d-3)}{1\cdot 2\cdot 3 \cdot 4}="%(n, n, n, n, n),
|
||||
str(choose(n, 4))
|
||||
]).split()
|
||||
@ -369,7 +369,7 @@ class NonGeneralPosition(CircleScene):
|
||||
]
|
||||
)
|
||||
center_region
|
||||
text = tex_mobject(r"\text{This region disappears}", size = r"\large")
|
||||
text = TexMobject(r"\text{This region disappears}", size = r"\large")
|
||||
text.center().scale(0.5).shift((-self.radius, self.radius-0.3, 0))
|
||||
arrow = Arrow(
|
||||
point = (-0.35, -0.1, 0),
|
||||
@ -417,7 +417,7 @@ class GeneralPositionRule(Scene):
|
||||
for radians, words, pairs in tuples:
|
||||
cs = CircleScene(radians)
|
||||
self.add(*cs.mobjects)
|
||||
words_mob = text_mobject(words).scale(2).shift((5, 3, 0))
|
||||
words_mob = TextMobject(words).scale(2).shift((5, 3, 0))
|
||||
if not first_time:
|
||||
self.add(words_mob)
|
||||
if words == "Okay":
|
||||
@ -492,8 +492,8 @@ class IllustrateNChooseK(Scene):
|
||||
Scene.__init__(self, *args, **kwargs)
|
||||
nrange = range(1, n+1)
|
||||
tuples = list(it.combinations(nrange, k))
|
||||
nrange_mobs = tex_mobject([str(n) + r'\;' for n in nrange]).split()
|
||||
tuple_mobs = tex_mobjects(
|
||||
nrange_mobs = TexMobject([str(n) + r'\;' for n in nrange]).split()
|
||||
tuple_mobs = TexMobjects(
|
||||
[
|
||||
(r'\\&' if c%(20//k) == 0 else r'\;\;') + str(p)
|
||||
for p, c in zip(tuples, it.count())
|
||||
@ -515,12 +515,12 @@ class IllustrateNChooseK(Scene):
|
||||
"""%(n, k, n, n, n, n)
|
||||
else:
|
||||
str1 = r"{%d \choose %d} ="%(n, k)
|
||||
form1, count, form2 = tex_mobject([
|
||||
form1, count, form2 = TexMobject([
|
||||
str1,
|
||||
"%d"%choose(n, k),
|
||||
r" \text{ total %s}"%tuple_term
|
||||
])
|
||||
pronunciation = text_mobject(
|
||||
pronunciation = TextMobject(
|
||||
"(pronounced ``%d choose %d\'\')"%(n, k)
|
||||
)
|
||||
for mob in nrange_mobs:
|
||||
@ -539,7 +539,7 @@ class IllustrateNChooseK(Scene):
|
||||
run_time = 6.0
|
||||
frame_time = run_time / len(tuples)
|
||||
for tup, count in zip(tuples, it.count()):
|
||||
count_mob = tex_mobject(str(count+1))
|
||||
count_mob = TexMobject(str(count+1))
|
||||
count_mob.center().shift(count_center)
|
||||
self.add(count_mob)
|
||||
tuple_copy = CompoundMobject(*[nrange_mobs[index-1] for index in tup])
|
||||
@ -582,8 +582,8 @@ class IntersectionPointCorrespondances(CircleScene):
|
||||
self.dots[p]
|
||||
for p in indices
|
||||
]
|
||||
line_statement = tex_mobject(r"\text{Pair of Lines}")
|
||||
dots_statement = tex_mobject(r"&\text{Quadruplet of} \\ &\text{outer dots}")
|
||||
line_statement = TexMobject(r"\text{Pair of Lines}")
|
||||
dots_statement = TexMobject(r"&\text{Quadruplet of} \\ &\text{outer dots}")
|
||||
for mob in line_statement, dots_statement:
|
||||
mob.center()
|
||||
mob.scale(0.7)
|
||||
@ -685,7 +685,7 @@ class GraphsAndEulersFormulaJoke(Scene):
|
||||
graph.filter_out(lambda (x, y, z) : abs(y) > SPACE_HEIGHT)
|
||||
self.add(axes)
|
||||
self.play(ShowCreation(graph), run_time = 1.0)
|
||||
eulers = tex_mobject("e^{\pi i} = -1").shift((0, 3, 0))
|
||||
eulers = TexMobject("e^{\pi i} = -1").shift((0, 3, 0))
|
||||
self.play(CounterclockwiseTransform(
|
||||
deepcopy(graph), eulers
|
||||
))
|
||||
@ -705,8 +705,8 @@ class DefiningGraph(GraphScene):
|
||||
def __init__(self, *args, **kwargs):
|
||||
GraphScene.__init__(self, *args, **kwargs)
|
||||
word_center = (0, 3, 0)
|
||||
vertices_word = text_mobject("``Vertices\"").shift(word_center)
|
||||
edges_word = text_mobject("``Edges\"").shift(word_center)
|
||||
vertices_word = TextMobject("``Vertices\"").shift(word_center)
|
||||
edges_word = TextMobject("``Edges\"").shift(word_center)
|
||||
dots, lines = self.vertices, self.edges
|
||||
self.remove(*dots + lines)
|
||||
all_dots = CompoundMobject(*dots)
|
||||
@ -782,7 +782,7 @@ class EulersFormula(GraphScene):
|
||||
terms = "V - E + F =2".split(" ")
|
||||
form = dict([
|
||||
(key, mob)
|
||||
for key, mob in zip(terms, tex_mobjects(terms))
|
||||
for key, mob in zip(terms, TexMobjects(terms))
|
||||
])
|
||||
for mob in form.values():
|
||||
mob.shift((0, SPACE_HEIGHT-0.7, 0))
|
||||
@ -831,7 +831,7 @@ class CannotDirectlyApplyEulerToMoser(CircleScene):
|
||||
def __init__(self, radians, *args, **kwargs):
|
||||
CircleScene.__init__(self, radians, *args, **kwargs)
|
||||
self.remove(self.n_equals)
|
||||
n_equals, intersection_count = tex_mobject([
|
||||
n_equals, intersection_count = TexMobject([
|
||||
r"&n = %d\\"%len(radians),
|
||||
r"&{%d \choose 4} = %d"%(len(radians), choose(len(radians), 4))
|
||||
]).split()
|
||||
@ -854,7 +854,7 @@ class CannotDirectlyApplyEulerToMoser(CircleScene):
|
||||
self.play(ShowCreation(yellow_lines))
|
||||
self.dither()
|
||||
self.remove(yellow_lines)
|
||||
cannot_intersect = text_mobject(r"""
|
||||
cannot_intersect = TextMobject(r"""
|
||||
Euler's formula does not apply to \\
|
||||
graphs whose edges intersect!
|
||||
"""
|
||||
@ -877,8 +877,8 @@ class ShowMoserGraphLines(CircleScene):
|
||||
radians = list(set(map(lambda x : x%(2*np.pi), radians)))
|
||||
radians.sort()
|
||||
CircleScene.__init__(self, radians, *args, **kwargs)
|
||||
n, plus_n_choose_4 = tex_mobject(["n", "+{n \\choose 4}"]).split()
|
||||
n_choose_2, plus_2_n_choose_4, plus_n = tex_mobject([
|
||||
n, plus_n_choose_4 = TexMobject(["n", "+{n \\choose 4}"]).split()
|
||||
n_choose_2, plus_2_n_choose_4, plus_n = TexMobject([
|
||||
r"{n \choose 2}",r"&+2{n \choose 4}\\",r"&+n"
|
||||
]).split()
|
||||
for mob in n, plus_n_choose_4, n_choose_2, plus_2_n_choose_4, plus_n:
|
||||
@ -1028,19 +1028,19 @@ class ApplyEulerToMoser(CircleScene):
|
||||
equals, two, two1, n, n1, nc2, nc4, nc41]
|
||||
|
||||
V[1], minus[1], E[1], plus[1], F[1], equals[1], two[1] = \
|
||||
tex_mobject(["V", "-", "E", "+", "F", "=", "2"]).split()
|
||||
TexMobject(["V", "-", "E", "+", "F", "=", "2"]).split()
|
||||
F[2], equals[2], E[2], minus[2], V[2], plus[2], two[2] = \
|
||||
tex_mobject(["F", "=", "E", "-", "V", "+", "2"]).split()
|
||||
TexMobject(["F", "=", "E", "-", "V", "+", "2"]).split()
|
||||
F[3], equals[3], E[3], minus[3], n[3], minus1[3], nc4[3], plus[3], two[3] = \
|
||||
tex_mobject(["F", "=", "E", "-", "n", "-", r"{n \choose 4}", "+", "2"]).split()
|
||||
TexMobject(["F", "=", "E", "-", "n", "-", r"{n \choose 4}", "+", "2"]).split()
|
||||
F[4], equals[4], nc2[4], plus1[4], two1[4], nc41[4], plus2[4], n1[4], minus[4], n[4], minus1[4], nc4[4], plus[4], two[4] = \
|
||||
tex_mobject(["F", "=", r"{n \choose 2}", "+", "2", r"{n \choose 4}", "+", "n","-", "n", "-", r"{n \choose 4}", "+", "2"]).split()
|
||||
TexMobject(["F", "=", r"{n \choose 2}", "+", "2", r"{n \choose 4}", "+", "n","-", "n", "-", r"{n \choose 4}", "+", "2"]).split()
|
||||
F[5], equals[5], nc2[5], plus1[5], two1[5], nc41[5], minus1[5], nc4[5], plus[5], two[5] = \
|
||||
tex_mobject(["F", "=", r"{n \choose 2}", "+", "2", r"{n \choose 4}", "-", r"{n \choose 4}", "+", "2"]).split()
|
||||
TexMobject(["F", "=", r"{n \choose 2}", "+", "2", r"{n \choose 4}", "-", r"{n \choose 4}", "+", "2"]).split()
|
||||
F[6], equals[6], nc2[6], plus1[6], nc4[6], plus[6], two[6] = \
|
||||
tex_mobject(["F", "=", r"{n \choose 2}", "+", r"{n \choose 4}", "+", "2"]).split()
|
||||
TexMobject(["F", "=", r"{n \choose 2}", "+", r"{n \choose 4}", "+", "2"]).split()
|
||||
F[7], equals[7], two[7], plus[7], nc2[7], plus1[7], nc4[7] = \
|
||||
tex_mobject(["F", "=", "2", "+", r"{n \choose 2}", "+", r"{n \choose 4}"]).split()
|
||||
TexMobject(["F", "=", "2", "+", r"{n \choose 2}", "+", r"{n \choose 4}"]).split()
|
||||
shift_val = (0, 3, 0)
|
||||
for d in dicts:
|
||||
if not d:
|
||||
@ -1181,7 +1181,7 @@ class ApplyEulerToMoser(CircleScene):
|
||||
self.highlight_region(self.exterior, "black")
|
||||
self.remove(two[6])
|
||||
two = two[7]
|
||||
one = tex_mobject("1").shift(two.get_center())
|
||||
one = TexMobject("1").shift(two.get_center())
|
||||
two.highlight("red")
|
||||
self.add(two)
|
||||
self.play(CounterclockwiseTransform(two, one))
|
||||
@ -1198,7 +1198,7 @@ class FormulaRelatesToPowersOfTwo(Scene):
|
||||
]
|
||||
for n in [1, 2, 3, 4, 5, 10]
|
||||
]
|
||||
everything = tex_mobjects(sum(strings, []), size = r"\large")
|
||||
everything = TexMobjects(sum(strings, []), size = r"\large")
|
||||
scale_factor = 1
|
||||
for mob in everything:
|
||||
mob.scale(scale_factor)
|
||||
@ -1216,7 +1216,7 @@ class FormulaRelatesToPowersOfTwo(Scene):
|
||||
for s, result in zip(sums, results)
|
||||
])
|
||||
powers_of_two = [
|
||||
tex_mobject("2^{%d}"%(i-1)
|
||||
TexMobject("2^{%d}"%(i-1)
|
||||
).scale(scale_factor
|
||||
).shift(result.get_center()
|
||||
).highlight()
|
||||
@ -1260,7 +1260,7 @@ class PascalRuleExample(PascalsTriangleScene):
|
||||
k = randint(1, n-1)
|
||||
self.coords_to_mobs[n][k].highlight("green")
|
||||
self.dither()
|
||||
plus = tex_mobject("+").scale(0.5)
|
||||
plus = TexMobject("+").scale(0.5)
|
||||
nums_above = [self.coords_to_mobs[n-1][k-1], self.coords_to_mobs[n-1][k]]
|
||||
plus.center().shift(sum(map(Mobject.get_center, nums_above)) / 2)
|
||||
self.add(plus)
|
||||
@ -1298,7 +1298,7 @@ class PascalsTriangleNChooseKExample(PascalsTriangleScene):
|
||||
PascalsTriangleScene.__init__(self, nrows, *args, **kwargs)
|
||||
dither_time = 0.5
|
||||
triangle_terms = [self.coords_to_mobs[a][b] for a, b in self.coords]
|
||||
formula_terms = left, n_mob, k_mob, right = tex_mobject([
|
||||
formula_terms = left, n_mob, k_mob, right = TexMobject([
|
||||
r"\left(", str(n), r"\atop %d"%k, r"\right)"
|
||||
])
|
||||
formula_center = (SPACE_WIDTH - 1, SPACE_HEIGHT - 1, 0)
|
||||
@ -1317,7 +1317,7 @@ class PascalsTriangleNChooseKExample(PascalsTriangleScene):
|
||||
self.remove(n_mob, k_mob)
|
||||
for a in range(n+1):
|
||||
row = [self.coords_to_mobs[a][b] for b in range(a+1)]
|
||||
a_mob = tex_mobject(str(a))
|
||||
a_mob = TexMobject(str(a))
|
||||
a_mob.shift(n_mob.get_center())
|
||||
a_mob.highlight("green")
|
||||
self.add(a_mob)
|
||||
@ -1330,7 +1330,7 @@ class PascalsTriangleNChooseKExample(PascalsTriangleScene):
|
||||
self.remove(a_mob)
|
||||
self.dither()
|
||||
for b in range(k+1):
|
||||
b_mob = tex_mobject(str(b))
|
||||
b_mob = TexMobject(str(b))
|
||||
b_mob.shift(k_mob.get_center())
|
||||
b_mob.highlight("yellow")
|
||||
self.add(b_mob)
|
||||
@ -1353,7 +1353,7 @@ class PascalsTriangleSumRows(PascalsTriangleScene):
|
||||
powers_of_two = []
|
||||
equalses = []
|
||||
powers_of_two_symbols = []
|
||||
plus = tex_mobject("+")
|
||||
plus = TexMobject("+")
|
||||
desired_plus_width = self.coords_to_mobs[0][0].get_width()
|
||||
if plus.get_width() > desired_plus_width:
|
||||
plus.scale(desired_plus_width / plus.get_width())
|
||||
@ -1364,12 +1364,12 @@ class PascalsTriangleSumRows(PascalsTriangleScene):
|
||||
new_plus.center().shift(self.coords_to_mobs[n][k].get_center())
|
||||
new_plus.shift((-self.cell_width / 2.0, 0, 0))
|
||||
pluses.append(new_plus)
|
||||
equals = tex_mobject("=")
|
||||
equals = TexMobject("=")
|
||||
equals.scale(min(1, 0.7 * self.cell_height / equals.get_width()))
|
||||
for n in range(self.nrows):
|
||||
new_equals = deepcopy(equals)
|
||||
pof2 = tex_mobjects(str(2**n))
|
||||
symbol = tex_mobject("2^{%d}"%n)
|
||||
pof2 = TexMobjects(str(2**n))
|
||||
symbol = TexMobject("2^{%d}"%n)
|
||||
desired_center = np.array((
|
||||
self.diagram_width / 2.0,
|
||||
self.coords_to_mobs[n][0].get_center()[1],
|
||||
@ -1423,7 +1423,7 @@ class MoserSolutionInPascal(PascalsTriangleScene):
|
||||
term_color = "green"
|
||||
self.generate_n_choose_k_mobs()
|
||||
self.remove(*[self.coords_to_mobs[n0][k0] for n0, k0 in self.coords])
|
||||
terms = one, plus0, n_choose_2, plus1, n_choose_4 = tex_mobject([
|
||||
terms = one, plus0, n_choose_2, plus1, n_choose_4 = TexMobject([
|
||||
"1", "+", r"{%d \choose 2}"%n, "+", r"{%d \choose 4}"%n
|
||||
]).split()
|
||||
target_terms = []
|
||||
@ -1485,7 +1485,7 @@ class MoserSolutionInPascal(PascalsTriangleScene):
|
||||
))
|
||||
self.remove(*above_terms)
|
||||
self.dither()
|
||||
terms_sum = tex_mobject(str(moser_function(n)))
|
||||
terms_sum = TexMobject(str(moser_function(n)))
|
||||
terms_sum.shift((SPACE_WIDTH-1, terms[0].get_center()[1], 0))
|
||||
terms_sum.highlight(term_color)
|
||||
self.play(Transform(CompoundMobject(*terms), terms_sum))
|
||||
@ -1527,17 +1527,17 @@ class ExplainNChoose2Formula(Scene):
|
||||
|
||||
def __init__(self, n, a, b, *args, **kwargs):
|
||||
Scene.__init__(self, *args, **kwargs)
|
||||
r_paren, a_mob, comma, b_mob, l_paren = tex_mobjects(
|
||||
r_paren, a_mob, comma, b_mob, l_paren = TexMobjects(
|
||||
("( %d , %d )"%(a, b)).split(" ")
|
||||
)
|
||||
parens = CompoundMobject(r_paren, comma, l_paren)
|
||||
nums = [tex_mobject(str(k)) for k in range(1, n+1)]
|
||||
nums = [TexMobject(str(k)) for k in range(1, n+1)]
|
||||
height = 1.5*nums[0].get_height()
|
||||
for x in range(n):
|
||||
nums[x].shift((0, x*height, 0))
|
||||
nums_compound = CompoundMobject(*nums)
|
||||
nums_compound.shift(a_mob.get_center() - nums[0].get_center())
|
||||
n_mob, n_minus_1, over_2 = tex_mobject([
|
||||
n_mob, n_minus_1, over_2 = TexMobject([
|
||||
str(n), "(%d-1)"%n, r"\over{2}"
|
||||
]).split()
|
||||
for part in n_mob, n_minus_1, over_2:
|
||||
@ -1585,7 +1585,7 @@ class ExplainNChoose2Formula(Scene):
|
||||
CounterclockwiseTransform(a_mob, a_copy),
|
||||
CounterclockwiseTransform(b_mob, b_copy),
|
||||
FadeIn(parens_copy),
|
||||
FadeIn(text_mobject("is considered the same as"))
|
||||
FadeIn(TextMobject("is considered the same as"))
|
||||
)
|
||||
|
||||
class ExplainNChoose4Formula(Scene):
|
||||
@ -1598,17 +1598,17 @@ class ExplainNChoose4Formula(Scene):
|
||||
Scene.__init__(self, *args, **kwargs)
|
||||
# quad = list(it.combinations(range(1,n+1), 4))[randint(0, choose(n, 4)-1)]
|
||||
quad = (4, 2, 5, 1)
|
||||
tuple_mobs = tex_mobjects(
|
||||
tuple_mobs = TexMobjects(
|
||||
("( %d , %d , %d , %d )"%quad).split(" ")
|
||||
)
|
||||
quad_mobs = tuple_mobs[1::2]
|
||||
parens = CompoundMobject(*tuple_mobs[0::2])
|
||||
form_mobs = tex_mobject([
|
||||
form_mobs = TexMobject([
|
||||
str(n), "(%d-1)"%n, "(%d-2)"%n,"(%d-3)"%n,
|
||||
r"\over {4 \cdot 3 \cdot 2 \cdot 1}"
|
||||
]).split()
|
||||
form_mobs = CompoundMobject(*form_mobs).scale(0.7).shift((4, 3, 0)).split()
|
||||
nums = [tex_mobject(str(k)) for k in range(1, n+1)]
|
||||
nums = [TexMobject(str(k)) for k in range(1, n+1)]
|
||||
height = 1.5*nums[0].get_height()
|
||||
for x in range(n):
|
||||
nums[x].shift((0, x*height, 0))
|
||||
@ -1643,7 +1643,7 @@ class ExplainNChoose4Formula(Scene):
|
||||
])
|
||||
curr_num = quad[i]
|
||||
self.remove(*self.mobjects)
|
||||
num_perms_explain = text_mobject(
|
||||
num_perms_explain = TextMobject(
|
||||
r"There are $(4 \cdot 3 \cdot 2 \cdot 1)$ total permutations"
|
||||
).shift((0, -2, 0))
|
||||
self.add(parens, num_perms_explain, *form_mobs)
|
||||
@ -1685,7 +1685,7 @@ class IntersectionChoppingExamples(Scene):
|
||||
for pairs, exp in [(pairs1, "3 + 2(2) = 7"),
|
||||
(pairs2, "4 + 2(3) = 10")]:
|
||||
lines = [Line(*pair).scale(2) for pair in pairs]
|
||||
self.add(tex_mobject(exp).shift((0, SPACE_HEIGHT-1, 0)))
|
||||
self.add(TexMobject(exp).shift((0, SPACE_HEIGHT-1, 0)))
|
||||
self.add(*lines)
|
||||
self.dither()
|
||||
self.play(*[
|
||||
|
@ -12,7 +12,7 @@ from constants import *
|
||||
from region import *
|
||||
from scene import Scene, NumberLineScene
|
||||
from script_wrapper import command_line_create_scene
|
||||
from inventing_math import underbrace
|
||||
from inventing_math import Underbrace
|
||||
|
||||
import random
|
||||
|
||||
@ -46,7 +46,7 @@ def rationals():
|
||||
|
||||
def fraction_mobject(fraction):
|
||||
n, d = fraction.numerator, fraction.denominator
|
||||
return tex_mobject("\\frac{%d}{%d}"%(n, d))
|
||||
return TexMobject("\\frac{%d}{%d}"%(n, d))
|
||||
|
||||
def continued_fraction(int_list):
|
||||
if len(int_list) == 1:
|
||||
@ -60,13 +60,13 @@ def zero_to_one_interval():
|
||||
)
|
||||
interval.elongate_tick_at(-INTERVAL_RADIUS, TICK_STRETCH_FACTOR)
|
||||
interval.elongate_tick_at(INTERVAL_RADIUS, TICK_STRETCH_FACTOR)
|
||||
interval.add(tex_mobject("0").shift(INTERVAL_RADIUS*LEFT+DOWN))
|
||||
interval.add(tex_mobject("1").shift(INTERVAL_RADIUS*RIGHT+DOWN))
|
||||
interval.add(TexMobject("0").shift(INTERVAL_RADIUS*LEFT+DOWN))
|
||||
interval.add(TexMobject("1").shift(INTERVAL_RADIUS*RIGHT+DOWN))
|
||||
return interval
|
||||
|
||||
class LeftParen(Mobject):
|
||||
def generate_points(self):
|
||||
self.add(tex_mobject("("))
|
||||
self.add(TexMobject("("))
|
||||
self.center()
|
||||
|
||||
def get_center(self):
|
||||
@ -74,7 +74,7 @@ class LeftParen(Mobject):
|
||||
|
||||
class RightParen(Mobject):
|
||||
def generate_points(self):
|
||||
self.add(tex_mobject(")"))
|
||||
self.add(TexMobject(")"))
|
||||
self.center()
|
||||
|
||||
def get_center(self):
|
||||
@ -258,17 +258,17 @@ class IntervalScene(NumberLineScene):
|
||||
|
||||
class TwoChallenges(Scene):
|
||||
def construct(self):
|
||||
two_challenges = text_mobject("Two Challenges", size = "\\Huge").to_edge(UP)
|
||||
one, two = map(text_mobject, ["1.", "2."])
|
||||
two_challenges = TextMobject("Two Challenges", size = "\\Huge").to_edge(UP)
|
||||
one, two = map(TextMobject, ["1.", "2."])
|
||||
one.shift(UP).to_edge(LEFT)
|
||||
two.shift(DOWN).to_edge(LEFT)
|
||||
notes = ImageMobject("musical_notes").scale(0.3)
|
||||
notes.next_to(one)
|
||||
notes.highlight("blue")
|
||||
measure = text_mobject("Measure Theory").next_to(two)
|
||||
probability = text_mobject("Probability")
|
||||
measure = TextMobject("Measure Theory").next_to(two)
|
||||
probability = TextMobject("Probability")
|
||||
probability.next_to(measure).shift(DOWN+RIGHT)
|
||||
integration = tex_mobject("\\int")
|
||||
integration = TexMobject("\\int")
|
||||
integration.next_to(measure).shift(UP+RIGHT)
|
||||
arrow_to_prob = Arrow(measure, probability)
|
||||
arrow_to_int = Arrow(measure, integration)
|
||||
@ -309,7 +309,7 @@ class MeasureTheoryToHarmony(IntervalScene):
|
||||
|
||||
class ChallengeOne(Scene):
|
||||
def construct(self):
|
||||
title = text_mobject("Challenge #1").to_edge(UP)
|
||||
title = TextMobject("Challenge #1").to_edge(UP)
|
||||
start_color = Color("blue")
|
||||
colors = start_color.range_to("white", 6)
|
||||
self.bottom_vibration = VibratingString(
|
||||
@ -323,14 +323,14 @@ class ChallengeOne(Scene):
|
||||
)
|
||||
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 = TextMobject("220 Hz")
|
||||
freq_r220 = TextMobject("$r\\times$220 Hz")
|
||||
freq_330 = TextMobject("1.5$\\times$220 Hz")
|
||||
freq_sqrt2 = TextMobject("$\\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")
|
||||
r_constraint = TexMobject("(1<r<2)", size = "\\large")
|
||||
|
||||
self.add(title)
|
||||
self.dither()
|
||||
@ -362,8 +362,8 @@ class ChallengeOne(Scene):
|
||||
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)
|
||||
r1 = TexMobject("r").next_to(arrow1, UP)
|
||||
r2 = TexMobject("r").next_to(arrow2, UP)
|
||||
kwargs = {
|
||||
"run_time" : 5.0,
|
||||
"alpha_func" : there_and_back
|
||||
@ -395,10 +395,10 @@ class JustByAnalyzingTheNumber(Scene):
|
||||
1.2020569031595942,
|
||||
]
|
||||
last = None
|
||||
r_equals = tex_mobject("r=").shift(2*LEFT)
|
||||
r_equals = TexMobject("r=").shift(2*LEFT)
|
||||
self.add(r_equals)
|
||||
for num in nums:
|
||||
mob = tex_mobject(str(num)).next_to(r_equals)
|
||||
mob = TexMobject(str(num)).next_to(r_equals)
|
||||
mob.highlight()
|
||||
mob.sort_points()
|
||||
if last:
|
||||
@ -412,23 +412,23 @@ class JustByAnalyzingTheNumber(Scene):
|
||||
|
||||
class QuestionAndAnswer(Scene):
|
||||
def construct(self):
|
||||
Q = text_mobject("Q:").shift(UP).to_edge(LEFT)
|
||||
A = text_mobject("A:").shift(DOWN).to_edge(LEFT)
|
||||
Q = TextMobject("Q:").shift(UP).to_edge(LEFT)
|
||||
A = TextMobject("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(
|
||||
twotwenty = TexMobject("220").scale(0.25).next_to(string1.mobject, LEFT)
|
||||
r220 = TexMobject("r\\times220").scale(0.25).next_to(string2.mobject, LEFT)
|
||||
question = TextMobject(
|
||||
"For what values of $r$ will the frequencies 220~Hz and \
|
||||
$r\\times$220~Hz sound nice together?"
|
||||
).next_to(Q)
|
||||
answer = text_mobject([
|
||||
answer = TextMobject([
|
||||
"When $r$ is",
|
||||
"sufficiently close to",
|
||||
"a rational number"
|
||||
], size = "\\small").scale(1.5)
|
||||
answer.next_to(A)
|
||||
correction1 = text_mobject(
|
||||
correction1 = TextMobject(
|
||||
"with sufficiently low denominator",
|
||||
size = "\\small"
|
||||
).scale(1.5)
|
||||
@ -476,7 +476,7 @@ class PlaySimpleRatio(Scene):
|
||||
if isinstance(fraction, Fraction):
|
||||
mob = fraction_mobject(fraction).shift(0.5*UP)
|
||||
else:
|
||||
mob = tex_mobject("\\frac{e^\\pi - \\pi}{15} \\approx \\frac{4}{3}")
|
||||
mob = TexMobject("\\frac{e^\\pi - \\pi}{15} \\approx \\frac{4}{3}")
|
||||
mob.shift(0.5*UP)
|
||||
self.add(mob)
|
||||
self.play(string1, string2)
|
||||
@ -496,7 +496,7 @@ class DecomposeMusicalNote(Scene):
|
||||
"run_time" : 4.0,
|
||||
"alpha_func" : None
|
||||
}
|
||||
words = text_mobject("Imagine 220 per second...")
|
||||
words = TextMobject("Imagine 220 per second...")
|
||||
words.shift(2*UP)
|
||||
|
||||
self.add(line)
|
||||
@ -528,7 +528,7 @@ class DecomposeTwoFrequencies(Scene):
|
||||
|
||||
class MostRationalsSoundBad(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("Most rational numbers sound bad!"))
|
||||
self.add(TextMobject("Most rational numbers sound bad!"))
|
||||
|
||||
class FlashOnXProximity(Animation):
|
||||
def __init__(self, mobject, x_val, *close_mobjects, **kwargs):
|
||||
@ -579,7 +579,7 @@ class PatternInFrequencies(Scene):
|
||||
}
|
||||
|
||||
self.add(big_line)
|
||||
self.add(tex_mobject("%d:%d"%(num1, num2)))
|
||||
self.add(TexMobject("%d:%d"%(num1, num2)))
|
||||
fracs = (
|
||||
1.0/(num_top_lines-1),
|
||||
1.0/(num_bot_lines-1)
|
||||
@ -599,18 +599,18 @@ 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)
|
||||
top = TexMobject("%d \\over"%num)
|
||||
bottom = TexMobject(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 = TextMobject("Simple").next_to(arrow1, UP)
|
||||
simple.highlight("green")
|
||||
complicated = text_mobject("Complicated").next_to(arrow2, UP)
|
||||
complicated = TextMobject("Complicated").next_to(arrow2, UP)
|
||||
complicated.highlight("red")
|
||||
indicates = text_mobject("Indicates complexity").shift(2*DOWN)
|
||||
indicates = TextMobject("Indicates complexity").shift(2*DOWN)
|
||||
arrow3 = Arrow(indicates.get_top(), frac0[1])
|
||||
arrow4 = Arrow(indicates.get_top(), frac1[1])
|
||||
|
||||
@ -638,9 +638,9 @@ class IrrationalGang(Scene):
|
||||
randy = Randolph()
|
||||
randy.mouth.highlight(randy.DEFAULT_COLOR)
|
||||
randy.sync_parts()
|
||||
sqrt13 = tex_mobject("\\sqrt{13}").shift(2*LEFT)
|
||||
sqrt13 = TexMobject("\\sqrt{13}").shift(2*LEFT)
|
||||
sqrt13.highlight("green")
|
||||
zeta3 = tex_mobject("\\zeta(3)").shift(2*RIGHT)
|
||||
zeta3 = TexMobject("\\zeta(3)").shift(2*RIGHT)
|
||||
zeta3.highlight("grey")
|
||||
eyes = CompoundMobject(*randy.eyes)
|
||||
eyes.scale(0.5)
|
||||
@ -691,7 +691,7 @@ class PianoTuning(Scene):
|
||||
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 = TexMobject("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()
|
||||
@ -720,23 +720,23 @@ class PianoTuning(Scene):
|
||||
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 = Underbrace(low.get_bottom(), high.get_bottom())
|
||||
u_brace.highlight("yellow")
|
||||
ratio = tex_mobject("2^{\\left(\\frac{%d}{12}\\right)}"%half_steps)
|
||||
ratio = TexMobject("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(
|
||||
product = TexMobject(
|
||||
["\\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 = TexMobject("\\approx"+str(2**(float(half_steps)/12)))
|
||||
approximate_form.scale(0.75)
|
||||
approximate_form.next_to(ratio)
|
||||
if interval == 5:
|
||||
num_den = (3, 2)
|
||||
elif interval == 4:
|
||||
num_den = (4, 3)
|
||||
should_be = text_mobject("Should be $\\frac{%d}{%d}$"%num_den)
|
||||
should_be = TextMobject("Should be $\\frac{%d}{%d}$"%num_den)
|
||||
should_be.next_to(u_brace, DOWN)
|
||||
|
||||
self.play(ApplyMethod(low.highlight, colors[0]))
|
||||
@ -776,28 +776,28 @@ class PowersOfTwelfthRoot(Scene):
|
||||
9 : Fraction(5, 3),
|
||||
10 : Fraction(16, 9),
|
||||
}
|
||||
approx = tex_mobject("\\approx").scale(0.5)
|
||||
approx = TexMobject("\\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 = TexMobject("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_form = TexMobject(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 = TextMobject("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 = TexMobject("%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([
|
||||
error_string = TextMobject([
|
||||
"with", str(percent_error)[:4] + "\\%", "error"
|
||||
])
|
||||
error_string = error_string.split()
|
||||
@ -813,7 +813,7 @@ class PowersOfTwelfthRoot(Scene):
|
||||
|
||||
class InterestingQuestion(Scene):
|
||||
def construct(self):
|
||||
words = text_mobject("Interesting Question:", size = "\\Huge")
|
||||
words = TextMobject("Interesting Question:", size = "\\Huge")
|
||||
words.scale(2.0)
|
||||
self.add(words)
|
||||
|
||||
@ -824,7 +824,7 @@ class SupposeThereIsASavant(Scene):
|
||||
"who finds pleasure in all pairs of " + \
|
||||
"notes whose frequencies have a rational ratio"
|
||||
words = words.split(" ")
|
||||
word_mobs = text_mobject(words).split()
|
||||
word_mobs = TextMobject(words).split()
|
||||
word_mobs[4].highlight()
|
||||
word_mobs[5].highlight()
|
||||
for word, word_mob in zip(words, word_mobs):
|
||||
@ -842,8 +842,8 @@ class AllValuesBetween1And2(NumberLineScene):
|
||||
)
|
||||
top_arrow = Arrow(one+UP, one)
|
||||
bot_arrow = Arrow(irr+2*DOWN, irr)
|
||||
r = tex_mobject("r").next_to(top_arrow, UP)
|
||||
irr_mob = tex_mobject(str(irrational)+"\\dots").next_to(bot_arrow, DOWN)
|
||||
r = TexMobject("r").next_to(top_arrow, UP)
|
||||
irr_mob = TexMobject(str(irrational)+"\\dots").next_to(bot_arrow, DOWN)
|
||||
|
||||
approximations = [
|
||||
continued_fraction(cont_frac[:k])
|
||||
@ -893,7 +893,7 @@ class AllValuesBetween1And2(NumberLineScene):
|
||||
|
||||
class ChallengeTwo(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("Challenge #2"))
|
||||
self.add(TextMobject("Challenge #2"))
|
||||
|
||||
class CoveringSetsWithOpenIntervals(IntervalScene):
|
||||
def construct(self):
|
||||
@ -903,7 +903,7 @@ class CoveringSetsWithOpenIntervals(IntervalScene):
|
||||
for num in set([0.2, 0.25, 0.45, 0.6, 0.65])
|
||||
])
|
||||
theorems = [
|
||||
text_mobject(words).shift(UP)
|
||||
TextMobject(words).shift(UP)
|
||||
for words in [
|
||||
"Heine-Borel Theorem",
|
||||
"Lebesgue's Number Lemma",
|
||||
@ -931,7 +931,7 @@ class DefineOpenInterval(IntervalScene):
|
||||
open_interval, line = self.add_open_interval(0.5, 0.75, run_time = 1.0)
|
||||
left, right = open_interval.get_left(), open_interval.get_right()
|
||||
a, less_than1, x, less_than2, b = \
|
||||
tex_mobject(["a", "<", "x", "<", "b"]).shift(UP).split()
|
||||
TexMobject(["a", "<", "x", "<", "b"]).shift(UP).split()
|
||||
left_arrow = Arrow(a.get_corner(DOWN+LEFT), left)
|
||||
right_arrow = Arrow(b.get_corner(DOWN+RIGHT), right)
|
||||
|
||||
@ -1010,15 +1010,15 @@ class SumOfIntervalsMustBeLessThan1(IntervalScene):
|
||||
self.remove(line)
|
||||
int_copy = deepcopy(open_interval)
|
||||
int_copy.scale(0.6).next_to(last_plus, buff = 0.1)
|
||||
last_plus = tex_mobject("+").scale(0.3)
|
||||
last_plus = TexMobject("+").scale(0.3)
|
||||
last_plus.next_to(int_copy, buff = 0.1)
|
||||
anims.append(Transform(open_interval, int_copy))
|
||||
if num < 1.0:
|
||||
anims.append(FadeIn(last_plus))
|
||||
less_than1 = tex_mobject("<1").scale(0.5)
|
||||
less_than1 = TexMobject("<1").scale(0.5)
|
||||
less_than1.next_to(int_copy)
|
||||
dots = tex_mobject("\\dots").replace(int_copy)
|
||||
words = text_mobject("Use infinitely many intervals")
|
||||
dots = TexMobject("\\dots").replace(int_copy)
|
||||
words = TextMobject("Use infinitely many intervals")
|
||||
words.shift(UP)
|
||||
|
||||
self.dither()
|
||||
@ -1032,7 +1032,7 @@ class SumOfIntervalsMustBeLessThan1(IntervalScene):
|
||||
class RationalsAreDense(IntervalScene):
|
||||
def construct(self):
|
||||
IntervalScene.construct(self)
|
||||
words = text_mobject(["Rationals are", "\\emph{dense}", "in the reals"])
|
||||
words = TextMobject(["Rationals are", "\\emph{dense}", "in the reals"])
|
||||
words.shift(2*UP)
|
||||
words = words.split()
|
||||
words[1].highlight()
|
||||
@ -1057,12 +1057,12 @@ class RationalsAreDense(IntervalScene):
|
||||
|
||||
class SurelyItsImpossible(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("Surely it's impossible!"))
|
||||
self.add(TextMobject("Surely it's impossible!"))
|
||||
|
||||
class HowCanYouNotCoverEntireInterval(IntervalScene):
|
||||
def construct(self):
|
||||
IntervalScene.construct(self)
|
||||
small_words = text_mobject("""
|
||||
small_words = TextMobject("""
|
||||
In case you are wondering, it is indeed true
|
||||
that if you cover all real numbers between 0
|
||||
and 1 with a set of open intervals, the sum
|
||||
@ -1072,7 +1072,7 @@ class HowCanYouNotCoverEntireInterval(IntervalScene):
|
||||
it for yourself!
|
||||
""")
|
||||
small_words.scale(0.5).to_corner(UP+RIGHT)
|
||||
big_words = text_mobject("""
|
||||
big_words = TextMobject("""
|
||||
Covering all numbers from 0 to 1 \\emph{will}
|
||||
force the sum of the lengths of your intervals
|
||||
to be at least 1.
|
||||
@ -1105,8 +1105,8 @@ class HowCanYouNotCoverEntireInterval(IntervalScene):
|
||||
|
||||
class PauseNow(Scene):
|
||||
def construct(self):
|
||||
top_words = text_mobject("Try for yourself!").scale(2).shift(3*UP)
|
||||
bot_words = text_mobject("""
|
||||
top_words = TextMobject("Try for yourself!").scale(2).shift(3*UP)
|
||||
bot_words = TextMobject("""
|
||||
If you've never seen this before, you will get
|
||||
the most out of the solution and the intuitions
|
||||
I illustrate only after pulling out a pencil and
|
||||
@ -1118,7 +1118,7 @@ class StepsToSolution(IntervalScene):
|
||||
def construct(self):
|
||||
IntervalScene.construct(self)
|
||||
self.spacing = 0.7
|
||||
steps = map(text_mobject, [
|
||||
steps = map(TextMobject, [
|
||||
"Enumerate all rationals in (0, 1)",
|
||||
"Assign one interval to each rational",
|
||||
"Choose sum of the form $\\mathlarger{\\sum}_{n=1}^\\infty a_n = 1$",
|
||||
@ -1159,7 +1159,7 @@ class StepsToSolution(IntervalScene):
|
||||
mob_copy = deepcopy(mob).center()
|
||||
mob_copy.shift((2.4-mob_copy.get_bottom()[1])*UP)
|
||||
mob_copy.shift((-SPACE_WIDTH+self.spacing*count)*RIGHT)
|
||||
comma = text_mobject(",").next_to(mob_copy, buff = 0.1, aligned_edge = DOWN)
|
||||
comma = TextMobject(",").next_to(mob_copy, buff = 0.1, aligned_edge = DOWN)
|
||||
anims.append(Transform(mob, mob_copy))
|
||||
commas.add(comma)
|
||||
anims.append(ShimmerIn(commas))
|
||||
@ -1215,24 +1215,24 @@ class StepsToSolution(IntervalScene):
|
||||
scale_val = 0.6
|
||||
plus = None
|
||||
for count in range(1, 10):
|
||||
frac_bottom = tex_mobject("\\over %d"%(2**count))
|
||||
frac_bottom = TexMobject("\\over %d"%(2**count))
|
||||
frac_bottom.scale(scale_val)
|
||||
one = tex_mobject("1").scale(scale_val)
|
||||
one = TexMobject("1").scale(scale_val)
|
||||
one.next_to(frac_bottom, UP, buff = 0.1)
|
||||
compound = CompoundMobject(frac_bottom, one)
|
||||
if plus:
|
||||
compound.next_to(plus)
|
||||
else:
|
||||
compound.to_edge(LEFT)
|
||||
plus = tex_mobject("+").scale(scale_val)
|
||||
plus = TexMobject("+").scale(scale_val)
|
||||
plus.next_to(compound)
|
||||
frac_bottom, one = compound.split()
|
||||
self.ones.append(one)
|
||||
self.add(frac_bottom, one, plus)
|
||||
self.dither(0.2)
|
||||
dots = tex_mobject("\\dots").scale(scale_val).next_to(plus)
|
||||
dots = TexMobject("\\dots").scale(scale_val).next_to(plus)
|
||||
arrow = Arrow(ORIGIN, RIGHT).next_to(dots)
|
||||
one = tex_mobject("1").next_to(arrow)
|
||||
one = TexMobject("1").next_to(arrow)
|
||||
self.ones.append(one)
|
||||
self.play(*[ShowCreation(mob) for mob in dots, arrow, one])
|
||||
self.dither()
|
||||
@ -1241,7 +1241,7 @@ class StepsToSolution(IntervalScene):
|
||||
self.play(*[
|
||||
CounterclockwiseTransform(
|
||||
one,
|
||||
tex_mobject("\\epsilon").replace(one)
|
||||
TexMobject("\\epsilon").replace(one)
|
||||
)
|
||||
for one in self.ones
|
||||
])
|
||||
@ -1259,11 +1259,11 @@ class StepsToSolution(IntervalScene):
|
||||
class OurSumCanBeArbitrarilySmall(Scene):
|
||||
def construct(self):
|
||||
step_size = 0.01
|
||||
epsilon = tex_mobject("\\epsilon")
|
||||
equals = tex_mobject("=").next_to(epsilon)
|
||||
epsilon = TexMobject("\\epsilon")
|
||||
equals = TexMobject("=").next_to(epsilon)
|
||||
self.add(epsilon, equals)
|
||||
for num in np.arange(1, 0, -step_size):
|
||||
parts = map(tex_mobject, str(num))
|
||||
parts = map(TexMobject, str(num))
|
||||
parts[0].next_to(equals)
|
||||
for i in range(1, len(parts)):
|
||||
parts[i].next_to(parts[i-1], buff = 0.1, aligned_edge = DOWN)
|
||||
@ -1272,7 +1272,7 @@ class OurSumCanBeArbitrarilySmall(Scene):
|
||||
self.remove(*parts)
|
||||
self.dither()
|
||||
self.clear()
|
||||
words = text_mobject([
|
||||
words = TextMobject([
|
||||
"Not only can the sum be $< 1$,\\\\",
|
||||
"it can be \\emph{arbitrarily small} !"
|
||||
]).split()
|
||||
@ -1283,13 +1283,13 @@ class OurSumCanBeArbitrarilySmall(Scene):
|
||||
|
||||
class ProofDoesNotEqualIntuition(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("Proof $\\ne$ Intuition"))
|
||||
self.add(TextMobject("Proof $\\ne$ Intuition"))
|
||||
|
||||
class StillFeelsCounterintuitive(IntervalScene):
|
||||
def construct(self):
|
||||
IntervalScene.construct(self)
|
||||
ticks = self.add_fraction_ticks(run_time = 1.0)
|
||||
epsilon, equals, num = map(tex_mobject, ["\\epsilon", "=", "0.3"])
|
||||
epsilon, equals, num = map(TexMobject, ["\\epsilon", "=", "0.3"])
|
||||
epsilon.shift(2*UP)
|
||||
equals.next_to(epsilon)
|
||||
num.next_to(equals)
|
||||
@ -1303,11 +1303,11 @@ class StillFeelsCounterintuitive(IntervalScene):
|
||||
|
||||
class VisualIntuition(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("Visual Intuition:"))
|
||||
self.add(TextMobject("Visual Intuition:"))
|
||||
|
||||
class SideNote(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject("(Brief Sidenote)"))
|
||||
self.add(TextMobject("(Brief Sidenote)"))
|
||||
|
||||
class TroubleDrawingSmallInterval(IntervalScene):
|
||||
def construct(self):
|
||||
@ -1319,7 +1319,7 @@ class TroubleDrawingSmallInterval(IntervalScene):
|
||||
shrunk = deepcopy(big).scale_in_place(0.01/0.5)
|
||||
self.clear()
|
||||
IntervalScene.construct(self)
|
||||
words = text_mobject("This tiny stretch")
|
||||
words = TextMobject("This tiny stretch")
|
||||
words.shift(2*UP+2*LEFT)
|
||||
arrow = Arrow(words, line)
|
||||
|
||||
@ -1344,20 +1344,20 @@ class TroubleDrawingSmallInterval(IntervalScene):
|
||||
|
||||
class WhatDoesItLookLikeToBeOutside(Scene):
|
||||
def construct(self):
|
||||
self.add(text_mobject(
|
||||
self.add(TextMobject(
|
||||
"What does it look like for a number to be outside a dense set of intervals?"
|
||||
))
|
||||
|
||||
class ZoomInOnSqrt2Over2(IntervalScene):
|
||||
def construct(self):
|
||||
IntervalScene.construct(self)
|
||||
epsilon, equals, num = map(tex_mobject, ["\\epsilon", "=", "0.3"])
|
||||
epsilon, equals, num = map(TexMobject, ["\\epsilon", "=", "0.3"])
|
||||
equals.next_to(epsilon)
|
||||
num.next_to(equals)
|
||||
self.add(CompoundMobject(epsilon, equals, num).center().shift(2*UP))
|
||||
intervals, lines = self.cover_fractions()
|
||||
self.remove(*lines)
|
||||
irr = tex_mobject("\\frac{\\sqrt{2}}{2}")
|
||||
irr = TexMobject("\\frac{\\sqrt{2}}{2}")
|
||||
point = self.number_line.number_to_point(np.sqrt(2)/2)
|
||||
arrow = Arrow(point+UP, point)
|
||||
irr.next_to(arrow, UP)
|
||||
@ -1372,9 +1372,9 @@ class ZoomInOnSqrt2Over2(IntervalScene):
|
||||
|
||||
class NotCoveredMeansCacophonous(Scene):
|
||||
def construct(self):
|
||||
statement1 = text_mobject("$\\frac{\\sqrt{2}}{2}$ is not covered")
|
||||
implies = tex_mobject("\\Rightarrow")
|
||||
statement2 = text_mobject("Rationals which are close to $\\frac{\\sqrt{2}}{2}$ must have large denominators")
|
||||
statement1 = TextMobject("$\\frac{\\sqrt{2}}{2}$ is not covered")
|
||||
implies = TexMobject("\\Rightarrow")
|
||||
statement2 = TextMobject("Rationals which are close to $\\frac{\\sqrt{2}}{2}$ must have large denominators")
|
||||
statement1.to_edge(LEFT)
|
||||
implies.next_to(statement1)
|
||||
statement2.next_to(implies)
|
||||
@ -1401,7 +1401,7 @@ class ShiftSetupByOne(IntervalScene):
|
||||
self.add(new_interval)
|
||||
self.number_line.add_numbers(0)
|
||||
self.remove(*self.number_mobs)
|
||||
epsilon_mob = tex_mobject("\\epsilon = 0.01").to_edge(UP)
|
||||
epsilon_mob = TexMobject("\\epsilon = 0.01").to_edge(UP)
|
||||
self.add(epsilon_mob)
|
||||
fraction_ticks = self.add_fraction_ticks()
|
||||
self.remove(fraction_ticks)
|
||||
@ -1438,7 +1438,7 @@ class ShiftSetupByOne(IntervalScene):
|
||||
])
|
||||
self.number_line = new_interval
|
||||
self.dither()
|
||||
words = text_mobject(
|
||||
words = TextMobject(
|
||||
"Almost all the covered numbers are harmonious!",
|
||||
size = "\\small"
|
||||
).shift(2*UP)
|
||||
@ -1447,20 +1447,20 @@ class ShiftSetupByOne(IntervalScene):
|
||||
for num in [7, 5]:
|
||||
point = self.number_line.number_to_point(2**(num/12.))
|
||||
arrow = Arrow(point+DOWN, point)
|
||||
mob = tex_mobject(
|
||||
mob = TexMobject(
|
||||
"2^{\\left(\\frac{%d}{12}\\right)}"%num
|
||||
).next_to(arrow, DOWN)
|
||||
self.play(ShimmerIn(mob), ShowCreation(arrow))
|
||||
self.dither()
|
||||
self.remove(mob, arrow)
|
||||
self.remove(words)
|
||||
words = text_mobject(
|
||||
words = TextMobject(
|
||||
"Cacophonous covered numbers:",
|
||||
size = "\\small"
|
||||
)
|
||||
words.shift(2*UP)
|
||||
answer1 = text_mobject("Complicated rationals,", size = "\\small")
|
||||
answer2 = text_mobject(
|
||||
answer1 = TextMobject("Complicated rationals,", size = "\\small")
|
||||
answer2 = TextMobject(
|
||||
"real numbers \\emph{very very very} close to them",
|
||||
size = "\\small"
|
||||
)
|
||||
@ -1476,7 +1476,7 @@ class ShiftSetupByOne(IntervalScene):
|
||||
self.add(answer2)
|
||||
self.dither()
|
||||
self.remove(words, answer1, answer2)
|
||||
words = text_mobject([
|
||||
words = TextMobject([
|
||||
"To a", "savant,", "harmonious numbers could be ",
|
||||
"\\emph{precisely}", "those 1\\% covered by the intervals"
|
||||
]).shift(2*UP)
|
||||
@ -1503,9 +1503,9 @@ class FinalEquivalence(IntervalScene):
|
||||
interval.scale_in_place(2.0/frac.denominator)
|
||||
self.remove(*intervals+lines)
|
||||
intervals = CompoundMobject(*intervals)
|
||||
arrow = tex_mobject("\\Leftrightarrow")
|
||||
top_words = text_mobject("Harmonious numbers are rare,")
|
||||
bot_words = text_mobject("even for the savant")
|
||||
arrow = TexMobject("\\Leftrightarrow")
|
||||
top_words = TextMobject("Harmonious numbers are rare,")
|
||||
bot_words = TextMobject("even for the savant")
|
||||
bot_words.highlight().next_to(top_words, DOWN)
|
||||
words = CompoundMobject(top_words, bot_words)
|
||||
words.next_to(arrow)
|
||||
|
@ -187,7 +187,7 @@ class ShowCounting(SceneFromVideo):
|
||||
total_time = len(self.frames)*self.frame_duration
|
||||
for count in range(32):
|
||||
print count
|
||||
mob = tex_mobject(str(count)).scale(1.5)
|
||||
mob = TexMobject(str(count)).scale(1.5)
|
||||
mob.shift(0.3*LEFT).to_edge(UP, buff = 0.1)
|
||||
index_range = range(
|
||||
max(COUNT_TO_FRAME_NUM[count]-10, 0),
|
||||
@ -212,7 +212,7 @@ class ShowFrameNum(SceneFromVideo):
|
||||
for frame, count in zip(self.frames, it.count()):
|
||||
print count, "of", len(self.frames)
|
||||
mob = CompoundMobject(*[
|
||||
tex_mobject(char).shift(0.3*x*RIGHT)
|
||||
TexMobject(char).shift(0.3*x*RIGHT)
|
||||
for char, x, in zip(str(count), it.count())
|
||||
])
|
||||
self.frames[count] = disp.paint_mobject(
|
||||
|
@ -47,7 +47,7 @@ class Triangle(Polygon):
|
||||
return self
|
||||
|
||||
def add_letter(self, char, nudge = 0.3):
|
||||
mob = tex_mobject(char).scale(TEX_MOB_SCALE_VAL)
|
||||
mob = TexMobject(char).scale(TEX_MOB_SCALE_VAL)
|
||||
if char == "a":
|
||||
points = self.get_vertices()[[0, 2, 1]]
|
||||
elif char == "b":
|
||||
@ -89,7 +89,7 @@ def c_square(**kwargs):
|
||||
class DrawPointsReference(Scene):
|
||||
def construct(self):
|
||||
for point, count in zip(POINTS, it.count()):
|
||||
mob = tex_mobject(str(count)).scale(TEX_MOB_SCALE_VAL)
|
||||
mob = TexMobject(str(count)).scale(TEX_MOB_SCALE_VAL)
|
||||
mob.shift(POINTS[count])
|
||||
self.add(mob)
|
||||
|
||||
@ -104,7 +104,7 @@ class DrawAllThreeSquares(Scene):
|
||||
c = c_square()
|
||||
self.add(Triangle(), a, b, c)
|
||||
for letter, mob in zip("abc", [a, b, c]):
|
||||
char_mob = tex_mobject(letter+"^2").scale(TEX_MOB_SCALE_VAL)
|
||||
char_mob = TexMobject(letter+"^2").scale(TEX_MOB_SCALE_VAL)
|
||||
char_mob.shift(mob.get_center())
|
||||
self.add(char_mob)
|
||||
|
||||
@ -230,13 +230,13 @@ class ShowBigRectangleDimensions(DrawAllThreeSquaresWithMoreTriangles):
|
||||
args_list = [(10, False)]
|
||||
def construct(self, num, fill):
|
||||
DrawAllThreeSquaresWithMoreTriangles.construct(self, num, fill)
|
||||
u_brace = underbrace((-3, -2, 0), (4, -2, 0))
|
||||
side_brace = underbrace((-3, -3, 0), (2, -3, 0))
|
||||
u_brace = Underbrace((-3, -2, 0), (4, -2, 0))
|
||||
side_brace = Underbrace((-3, -3, 0), (2, -3, 0))
|
||||
for brace in u_brace, side_brace:
|
||||
brace.shift(0.2*DOWN)
|
||||
side_brace.rotate(-np.pi/2)
|
||||
a_plus_2b = tex_mobject("a+2b").scale(TEX_MOB_SCALE_VAL)
|
||||
b_plus_2a = tex_mobject("b+2a").scale(TEX_MOB_SCALE_VAL)
|
||||
a_plus_2b = TexMobject("a+2b").scale(TEX_MOB_SCALE_VAL)
|
||||
b_plus_2a = TexMobject("b+2a").scale(TEX_MOB_SCALE_VAL)
|
||||
a_plus_2b.next_to(u_brace, DOWN)
|
||||
b_plus_2a.next_to(side_brace, LEFT)
|
||||
self.add_local_mobjects()
|
||||
@ -263,7 +263,7 @@ class DrawOnlyABSquares(Scene):
|
||||
a = a_square()
|
||||
b = b_square()
|
||||
for char, mob in zip("ab", [a, b]):
|
||||
symobl = tex_mobject(char+"^2").scale(TEX_MOB_SCALE_VAL)
|
||||
symobl = TexMobject(char+"^2").scale(TEX_MOB_SCALE_VAL)
|
||||
symobl.shift(mob.get_center())
|
||||
self.add(symobl)
|
||||
triangle = Triangle()
|
||||
@ -394,8 +394,8 @@ class ZoomInOnTroublePoint(Scene):
|
||||
for mob in self.mobjects:
|
||||
mob.rotate(np.pi/2)
|
||||
if with_labels:
|
||||
alpha = tex_mobject("\\alpha").scale(TEX_MOB_SCALE_VAL)
|
||||
beta = tex_mobject("90-\\alpha").scale(TEX_MOB_SCALE_VAL)
|
||||
alpha = TexMobject("\\alpha").scale(TEX_MOB_SCALE_VAL)
|
||||
beta = TexMobject("90-\\alpha").scale(TEX_MOB_SCALE_VAL)
|
||||
if rotate:
|
||||
alpha.next_to(angle1_arc, UP+0.1*LEFT)
|
||||
beta.next_to(angle2_arc, DOWN+0.5*LEFT)
|
||||
@ -427,8 +427,8 @@ class DrawTriangleWithAngles(Scene):
|
||||
angle2_arc = Circle(radius = 0.2, **kwargs).filter_out(
|
||||
lambda (x, y, z) : not(x < 0 and y > 0 and y < -3*x)
|
||||
).shift(vertices[2])
|
||||
alpha = tex_mobject("\\alpha")
|
||||
beta = tex_mobject("90-\\alpha")
|
||||
alpha = TexMobject("\\alpha")
|
||||
beta = TexMobject("90-\\alpha")
|
||||
alpha.shift(vertices[1]+3*RIGHT+DOWN)
|
||||
beta.shift(vertices[2]+3*RIGHT+UP)
|
||||
arrow1 = Arrow(alpha, angle1_arc)
|
||||
@ -442,11 +442,11 @@ class LabelLargeSquare(DrawCSquareWithAllTraingles):
|
||||
def construct(self):
|
||||
DrawCSquareWithAllTraingles.construct(self)
|
||||
everything = CompoundMobject(*self.mobjects)
|
||||
u_brace = underbrace(2*(DOWN+LEFT), 2*(DOWN+RIGHT))
|
||||
u_brace = Underbrace(2*(DOWN+LEFT), 2*(DOWN+RIGHT))
|
||||
u_brace.shift(0.2*DOWN)
|
||||
side_brace = deepcopy(u_brace).rotate(np.pi/2)
|
||||
upper_brace = deepcopy(u_brace).rotate(np.pi)
|
||||
a_plus_b = tex_mobject("a+b").scale(TEX_MOB_SCALE_VAL)
|
||||
a_plus_b = TexMobject("a+b").scale(TEX_MOB_SCALE_VAL)
|
||||
upper_brace.add(a_plus_b.next_to(upper_brace, UP))
|
||||
side_brace.add(a_plus_b.next_to(side_brace, RIGHT))
|
||||
self.add(upper_brace, side_brace)
|
||||
|
@ -73,12 +73,12 @@ MOVIE_PREFIX = "tau_poem/"
|
||||
class Welcome(LogoGeneration):
|
||||
def construct(self):
|
||||
text = "Happy $\\tau$ Day, from 3Blue1Brown!"
|
||||
self.add(text_mobject(text).to_edge(UP))
|
||||
self.add(TextMobject(text).to_edge(UP))
|
||||
LogoGeneration.construct(self)
|
||||
|
||||
class HappyTauDayWords(Scene):
|
||||
def construct(self):
|
||||
words = text_mobject("Happy Tau Day Everybody!").scale(2)
|
||||
words = TextMobject("Happy Tau Day Everybody!").scale(2)
|
||||
tau = TauCreature().move_to(2*LEFT + UP)
|
||||
pi = PiCreature().move_to(2*RIGHT + 3*DOWN)
|
||||
pi.highlight("red")
|
||||
@ -128,7 +128,7 @@ class TauPoem(Scene):
|
||||
self.first_word_to_last_digit()
|
||||
|
||||
def add_line_and_number(self):
|
||||
self.first_digits, new_digit, last_digits = tex_mobject([
|
||||
self.first_digits, new_digit, last_digits = TexMobject([
|
||||
"".join(DIGITS[:self.line_num]),
|
||||
DIGITS[self.line_num],
|
||||
"".join(DIGITS[(self.line_num+1):]),
|
||||
@ -140,11 +140,11 @@ class TauPoem(Scene):
|
||||
index = line_str.index("ders")
|
||||
else:
|
||||
index = line_str.index(" ")
|
||||
first_word, rest_of_line = text_mobject(
|
||||
first_word, rest_of_line = TextMobject(
|
||||
[line_str[:index], line_str[index:]]
|
||||
).to_edge(UP).shift(BUFF*DOWN).split()
|
||||
first_word.shift(0.15*RIGHT) #Stupid
|
||||
number_word = text_mobject(DIGIT_TO_WORD[DIGITS[self.line_num][-1]])
|
||||
number_word = TextMobject(DIGIT_TO_WORD[DIGITS[self.line_num][-1]])
|
||||
number_word.shift(first_word.get_center())
|
||||
number_word.shift(BUFF * UP / 2)
|
||||
|
||||
@ -178,7 +178,7 @@ class TauPoem(Scene):
|
||||
)
|
||||
|
||||
def line0(self):
|
||||
two, pi = tex_mobject(["2", "\\pi"]).scale(2).split()
|
||||
two, pi = TexMobject(["2", "\\pi"]).scale(2).split()
|
||||
self.add(two, pi)
|
||||
two_copy = deepcopy(two).rotate(np.pi/10).highlight("yellow")
|
||||
self.play(Transform(
|
||||
@ -191,7 +191,7 @@ class TauPoem(Scene):
|
||||
))
|
||||
|
||||
def line1(self):
|
||||
two_pi = tex_mobject(["2", "\\pi"]).scale(2)
|
||||
two_pi = TexMobject(["2", "\\pi"]).scale(2)
|
||||
tau = TauCreature()
|
||||
tau.to_symbol()
|
||||
sphere = Mobject()
|
||||
@ -277,7 +277,7 @@ class TauPoem(Scene):
|
||||
""")
|
||||
self.add(pi, bubble)
|
||||
|
||||
formulae = tex_mobject(FORMULAE, size = "\\small")
|
||||
formulae = TexMobject(FORMULAE, size = "\\small")
|
||||
formulae.scale(1.25)
|
||||
formulae.to_corner([1, -1, 0])
|
||||
self.play(FadeIn(formulae))
|
||||
@ -349,12 +349,12 @@ class TauPoem(Scene):
|
||||
self.play(WaveArm(tau),Transform(pi, new_pi))
|
||||
|
||||
def line10(self):
|
||||
formulae = tex_mobject(FORMULAE, "\\small")
|
||||
formulae = TexMobject(FORMULAE, "\\small")
|
||||
formulae.scale(1.5).to_edge(DOWN)
|
||||
self.add(formulae)
|
||||
|
||||
def line11(self):
|
||||
formulae = tex_mobject(FORMULAE, "\\small")
|
||||
formulae = TexMobject(FORMULAE, "\\small")
|
||||
formulae.scale(1.5).to_edge(DOWN)
|
||||
formulae = formulae.split()
|
||||
f_copy = deepcopy(formulae)
|
||||
@ -391,14 +391,14 @@ class TauPoem(Scene):
|
||||
)
|
||||
grid = Grid(radius = radius).shift(grid_center)
|
||||
circle = Circle().scale(interval_size).shift(grid_center)
|
||||
grid.add(tex_mobject("e^{ix}").shift(grid_center+UP+RIGHT))
|
||||
grid.add(TexMobject("e^{ix}").shift(grid_center+UP+RIGHT))
|
||||
circle.highlight("white")
|
||||
tau_line = Line(
|
||||
*[np.pi*interval_size*vect for vect in LEFT, RIGHT],
|
||||
density = 5*DEFAULT_POINT_DENSITY_1D
|
||||
)
|
||||
tau_line.highlight("red")
|
||||
tau = tex_mobject("\\tau")
|
||||
tau = TexMobject("\\tau")
|
||||
tau.shift(tau_line.get_center() + 0.5*UP)
|
||||
|
||||
self.add(axes, grid)
|
||||
@ -423,7 +423,7 @@ class TauPoem(Scene):
|
||||
|
||||
|
||||
def line13(self):
|
||||
formula = form_start, two_pi, form_end = tex_mobject([
|
||||
formula = form_start, two_pi, form_end = TexMobject([
|
||||
"\\hat{f^{(n)}}(\\xi) = (",
|
||||
"2\\pi",
|
||||
"i\\xi)^n \\hat{f}(\\xi)"
|
||||
@ -453,7 +453,7 @@ class TauPoem(Scene):
|
||||
pi, bubble = self.pi_speaking(
|
||||
"sticks oddly \\\\ to one half when \\\\ tau's preferred."
|
||||
)
|
||||
formula = form_start, half, form_end = tex_mobject([
|
||||
formula = form_start, half, form_end = TexMobject([
|
||||
"A = ",
|
||||
"\\frac{1}{2}",
|
||||
"\\tau r^2"
|
||||
@ -464,7 +464,7 @@ class TauPoem(Scene):
|
||||
self.play(ApplyMethod(half.highlight, "yellow"))
|
||||
|
||||
def line16(self):
|
||||
self.add(tex_mobject(
|
||||
self.add(TexMobject(
|
||||
"\\frac{1}{2}\\tau r^2"
|
||||
).scale(2).shift(DOWN))
|
||||
|
||||
@ -489,8 +489,8 @@ class TauPoem(Scene):
|
||||
-norm,
|
||||
0
|
||||
)
|
||||
tau_r = tex_mobject("\\tau r").shift(1.3*DOWN)
|
||||
r = tex_mobject("r").shift(0.2*RIGHT + 0.7*DOWN)
|
||||
tau_r = TexMobject("\\tau r").shift(1.3*DOWN)
|
||||
r = TexMobject("r").shift(0.2*RIGHT + 0.7*DOWN)
|
||||
lines = [
|
||||
Line(DOWN+np.pi*LEFT, DOWN+np.pi*RIGHT),
|
||||
Line(ORIGIN, DOWN)
|
||||
|
153
tex_utils.py
153
tex_utils.py
@ -1,153 +0,0 @@
|
||||
|
||||
from image_mobject import ImageMobject
|
||||
from helpers import *
|
||||
|
||||
#TODO, Cleanup and refactor this file.
|
||||
#TODO, Make both of these proper mobject classes
|
||||
def text_mobject(text, size = None):
|
||||
size = size or "\\Large" #TODO, auto-adjust?
|
||||
return tex_mobject(text, size, TEMPLATE_TEXT_FILE)
|
||||
|
||||
def tex_mobject(expression,
|
||||
size = None,
|
||||
template_tex_file = TEMPLATE_TEX_FILE):
|
||||
if size == None:
|
||||
if len("".join(expression)) < MAX_LEN_FOR_HUGE_TEX_FONT:
|
||||
size = "\\Huge"
|
||||
else:
|
||||
size = "\\large"
|
||||
#Todo, make this more sophisticated.
|
||||
image_files = tex_to_image(expression, size, template_tex_file)
|
||||
config = {
|
||||
"point_thickness" : 1,
|
||||
"should_center" : False,
|
||||
}
|
||||
if isinstance(image_files, list):
|
||||
#TODO, is checking listiness really the best here?
|
||||
result = CompoundMobject(*[
|
||||
ImageMobject(f, **config)
|
||||
for f in image_files
|
||||
])
|
||||
else:
|
||||
result = ImageMobject(image_files, **config)
|
||||
return result.center().highlight("white")
|
||||
|
||||
|
||||
def underbrace(left, right, buff = 0.2):
|
||||
result = tex_mobject("\\underbrace{%s}"%(14*"\\quad"))
|
||||
result.stretch_to_fit_width(right[0]-left[0])
|
||||
result.shift(left - result.points[0] + buff*DOWN)
|
||||
return result
|
||||
|
||||
|
||||
def tex_to_image(expression,
|
||||
size = "\HUGE",
|
||||
template_tex_file = TEMPLATE_TEX_FILE):
|
||||
"""
|
||||
Returns list of images for correpsonding with a list of expressions
|
||||
"""
|
||||
return_list = isinstance(expression, list)
|
||||
simple_tex = "".join(expression)
|
||||
if return_list:
|
||||
expression = tex_expression_list_as_string(expression)
|
||||
exp_hash = str(hash(expression + size))
|
||||
image_dir = os.path.join(TEX_IMAGE_DIR, exp_hash)
|
||||
if os.path.exists(image_dir):
|
||||
result = [
|
||||
os.path.join(image_dir, png_file)
|
||||
for png_file in sorted(
|
||||
os.listdir(image_dir),
|
||||
cmp_enumerated_files
|
||||
)
|
||||
]
|
||||
else:
|
||||
filestem = os.path.join(TEX_DIR, exp_hash)
|
||||
if not os.path.exists(filestem + ".tex"):
|
||||
print "Writing %s at size %s to %s.tex"%(
|
||||
simple_tex, size, filestem
|
||||
)
|
||||
with open(template_tex_file, "r") as infile:
|
||||
body = infile.read()
|
||||
body = body.replace(SIZE_TO_REPLACE, size)
|
||||
body = body.replace(TEX_TEXT_TO_REPLACE, expression)
|
||||
with open(filestem + ".tex", "w") as outfile:
|
||||
outfile.write(body)
|
||||
if not os.path.exists(filestem + ".dvi"):
|
||||
commands = [
|
||||
"latex",
|
||||
"-interaction=batchmode",
|
||||
"-output-directory=" + TEX_DIR,
|
||||
filestem + ".tex",
|
||||
"> /dev/null"
|
||||
]
|
||||
#TODO, Error check
|
||||
os.system(" ".join(commands))
|
||||
result = dvi_to_png(filestem + ".dvi")
|
||||
return result if return_list else result[0]
|
||||
|
||||
def tex_expression_list_as_string(expression):
|
||||
return "\n".join([
|
||||
"\onslide<%d>{"%count + exp + "}"
|
||||
for count, exp in zip(it.count(1), expression)
|
||||
])
|
||||
|
||||
def dvi_to_png(filename, regen_if_exists = False):
|
||||
"""
|
||||
Converts a dvi, which potentially has multiple slides, into a
|
||||
directory full of enumerated pngs corresponding with these slides.
|
||||
Returns a list of PIL Image objects for these images sorted as they
|
||||
where in the dvi
|
||||
"""
|
||||
possible_paths = [
|
||||
filename,
|
||||
os.path.join(TEX_DIR, filename),
|
||||
os.path.join(TEX_DIR, filename + ".dvi"),
|
||||
]
|
||||
for path in possible_paths:
|
||||
if os.path.exists(path):
|
||||
directory, filename = os.path.split(path)
|
||||
name = filename.split(".")[0]
|
||||
images_dir = os.path.join(TEX_IMAGE_DIR, name)
|
||||
if not os.path.exists(images_dir):
|
||||
os.mkdir(images_dir)
|
||||
if os.listdir(images_dir) == [] or regen_if_exists:
|
||||
commands = [
|
||||
"convert",
|
||||
"-density",
|
||||
str(PDF_DENSITY),
|
||||
path,
|
||||
"-size",
|
||||
str(DEFAULT_WIDTH) + "x" + str(DEFAULT_HEIGHT),
|
||||
os.path.join(images_dir, name + ".png")
|
||||
]
|
||||
os.system(" ".join(commands))
|
||||
image_paths = [
|
||||
os.path.join(images_dir, name)
|
||||
for name in os.listdir(images_dir)
|
||||
if name.endswith(".png")
|
||||
]
|
||||
image_paths.sort(cmp_enumerated_files)
|
||||
return image_paths
|
||||
raise IOError("File not Found")
|
||||
|
||||
def cmp_enumerated_files(name1, name2):
|
||||
num1, num2 = [
|
||||
int(name.split(".")[0].split("-")[-1])
|
||||
for name in (name1, name2)
|
||||
]
|
||||
return num1 - num2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@ import itertools as it
|
||||
from helpers import *
|
||||
from scene import Scene
|
||||
from animation import Animation
|
||||
from mobject import TexMobject
|
||||
|
||||
class RearrangeEquation(Scene):
|
||||
def construct(
|
||||
@ -67,8 +68,8 @@ class RearrangeEquation(Scene):
|
||||
"""
|
||||
num_start_terms = len(start_terms)
|
||||
all_mobs = np.array(
|
||||
tex_mobject(start_terms, size = size).split() + \
|
||||
tex_mobject(end_terms, size = size).split()
|
||||
TexMobject(start_terms, size = size).split() + \
|
||||
TexMobject(end_terms, size = size).split()
|
||||
)
|
||||
all_terms = np.array(start_terms+end_terms)
|
||||
for term in set(all_terms):
|
||||
@ -88,7 +89,7 @@ class FlipThroughSymbols(Animation):
|
||||
"end_center" : ORIGIN,
|
||||
}
|
||||
def __init__(self, tex_list, **kwargs):
|
||||
mobject = tex_mobject(self.curr_tex).shift(start_center)
|
||||
mobject = TexMobject(self.curr_tex).shift(start_center)
|
||||
Animation.__init__(self, mobject, **kwargs)
|
||||
|
||||
def update_mobject(self, alpha):
|
||||
@ -96,7 +97,7 @@ class FlipThroughSymbols(Animation):
|
||||
|
||||
if new_tex != self.curr_tex:
|
||||
self.curr_tex = new_tex
|
||||
self.mobject = tex_mobject(new_tex).shift(self.start_center)
|
||||
self.mobject = TexMobject(new_tex).shift(self.start_center)
|
||||
if not all(self.start_center == self.end_center):
|
||||
self.mobject.center().shift(
|
||||
(1-alpha)*self.start_center + alpha*self.end_center
|
||||
|
@ -33,7 +33,7 @@ class PiCreature(CompoundMobject):
|
||||
self.mouth.center()
|
||||
self.smile = deepcopy(self.mouth)
|
||||
self.frown = deepcopy(self.mouth).rotate(np.pi, RIGHT)
|
||||
self.straight_mouth = tex_mobject("-").scale(0.5)
|
||||
self.straight_mouth = TexMobject("-").scale(0.5)
|
||||
for mouth_name in ["mouth"] + self.MOUTH_NAMES:
|
||||
mouth = getattr(self, mouth_name)
|
||||
mouth.sort_points(lambda p : p[0])
|
||||
@ -211,7 +211,7 @@ class Bubble(Mobject):
|
||||
return self
|
||||
|
||||
def write(self, text):
|
||||
self.add_content(text_mobject(text))
|
||||
self.add_content(TextMobject(text))
|
||||
return self
|
||||
|
||||
def clear(self):
|
||||
|
@ -40,7 +40,7 @@ class CountingScene(Scene):
|
||||
self.add(*mobjects)
|
||||
for mob, num in zip(mobjects, it.count(1)):
|
||||
if display_numbers:
|
||||
num_mob = tex_mobject(str(num))
|
||||
num_mob = TexMobject(str(num))
|
||||
num_mob.center().shift(num_offset)
|
||||
self.add(num_mob)
|
||||
if mode == "highlight":
|
||||
@ -69,7 +69,7 @@ class CountingScene(Scene):
|
||||
raise Warning("Unknown mode")
|
||||
frame_time = run_time / (len(regions))
|
||||
for region, count in zip(regions, it.count(1)):
|
||||
num_mob = tex_mobject(str(count))
|
||||
num_mob = TexMobject(str(count))
|
||||
num_mob.center().shift(num_offset)
|
||||
self.add(num_mob)
|
||||
self.highlight_region(region)
|
||||
@ -112,7 +112,7 @@ class PascalsTriangleScene(Scene):
|
||||
num = choose(n, k)
|
||||
center = self.coords_to_center(n, k)
|
||||
if num not in num_to_num_mob:
|
||||
num_to_num_mob[num] = tex_mobject(str(num))
|
||||
num_to_num_mob[num] = TexMobject(str(num))
|
||||
num_mob = deepcopy(num_to_num_mob[num])
|
||||
scale_factor = min(
|
||||
1,
|
||||
@ -135,7 +135,7 @@ class PascalsTriangleScene(Scene):
|
||||
def generate_n_choose_k_mobs(self):
|
||||
self.coords_to_n_choose_k = {}
|
||||
for n, k in self.coords:
|
||||
nck_mob = tex_mobject(r"{%d \choose %d}"%(n, k))
|
||||
nck_mob = TexMobject(r"{%d \choose %d}"%(n, k))
|
||||
scale_factor = min(
|
||||
1,
|
||||
self.portion_to_fill * self.cell_height / nck_mob.get_height(),
|
||||
@ -148,7 +148,7 @@ class PascalsTriangleScene(Scene):
|
||||
self.coords_to_n_choose_k[n][k] = nck_mob
|
||||
|
||||
def generate_sea_of_zeros(self):
|
||||
zero = tex_mobject("0")
|
||||
zero = TexMobject("0")
|
||||
self.sea_of_zeros = []
|
||||
for n in range(self.nrows):
|
||||
for a in range((self.nrows - n)/2 + 1):
|
||||
|
@ -49,7 +49,7 @@ class ComplexPlane(NumberPlane):
|
||||
num_str = "0"
|
||||
else:
|
||||
num_str = str(number).replace("j", "i")
|
||||
num = tex_mobject(num_str)
|
||||
num = TexMobject(num_str)
|
||||
num.scale(self.number_scale_factor)
|
||||
num.shift(point-num.get_corner(UP+LEFT)+nudge)
|
||||
result.append(num)
|
||||
@ -167,7 +167,7 @@ class ComplexMultiplication(Scene):
|
||||
radius = 0.1*self.plane.unit_to_spatial_width,
|
||||
color = BLUE if value == 1 else YELLOW
|
||||
)
|
||||
label = tex_mobject(tex_string)
|
||||
label = TexMobject(tex_string)
|
||||
label.shift(dot.get_center()+1.5*UP+RIGHT)
|
||||
arrow = Arrow(label, dot)
|
||||
self.add(label)
|
||||
|
@ -1,6 +1,6 @@
|
||||
from helpers import *
|
||||
|
||||
from mobject import Mobject1D
|
||||
from mobject import Mobject1D, TexMobject
|
||||
from scene import Scene
|
||||
|
||||
class NumberLine(Mobject1D):
|
||||
@ -80,7 +80,7 @@ class NumberLine(Mobject1D):
|
||||
numbers = self.default_numbers_to_display()
|
||||
result = []
|
||||
for number in numbers:
|
||||
mob = tex_mobject(str(int(number)))
|
||||
mob = TexMobject(str(int(number)))
|
||||
vert_scale = 2*self.tick_size/mob.get_height()
|
||||
hori_scale = self.tick_frequency*self.unit_length_to_spatial_width/mob.get_width()
|
||||
mob.scale(min(vert_scale, hori_scale))
|
||||
@ -187,7 +187,7 @@ class NumberPlane(Mobject1D):
|
||||
for val in vals:
|
||||
num_pair[index] = val
|
||||
point = self.num_pair_to_point(num_pair)
|
||||
num = tex_mobject(str(val))
|
||||
num = TexMobject(str(val))
|
||||
num.scale(self.number_scale_factor)
|
||||
num.shift(point-num.get_corner(UP+LEFT)+nudge)
|
||||
result.append(num)
|
||||
|
Reference in New Issue
Block a user