Finished Basel project

This commit is contained in:
Grant Sanderson 2018-03-04 10:43:23 -08:00
parent ebc418d2bd
commit 8b1643f55d

View file

@ -224,6 +224,45 @@ class ScaleLightSources(Transform):
Transform.__init__(self,light_sources_mob,ls_target,**kwargs)
class ThreeDSpotlight(VGroup):
CONFIG = {
"fill_color" : YELLOW,
}
def __init__(self, screen, ambient_light, source_point_func, **kwargs):
self.screen = screen
self.ambient_light = ambient_light
self.source_point_func = source_point_func
self.dr = ambient_light.radius/ambient_light.num_levels
VGroup.__init__(self, **kwargs)
def update(self):
screen = self.screen
source_point = self.source_point_func()
dr = self.dr
corners = screen.get_anchors()
self.submobjects = [VGroup() for a in screen.get_anchors()]
distance = np.linalg.norm(
screen.get_center() - source_point
)
n_parts = np.ceil(distance/dr)
alphas = np.linspace(0, 1, n_parts+1)
for face, (c1, c2) in zip(self, adjacent_pairs(corners)):
face.submobjects = []
for a1, a2 in zip(alphas, alphas[1:]):
face.add(Polygon(
interpolate(source_point, c1, a1),
interpolate(source_point, c1, a2),
interpolate(source_point, c2, a2),
interpolate(source_point, c2, a1),
fill_color = self.fill_color,
fill_opacity = self.ambient_light.opacity_function(a1*distance),
stroke_width = 0
))
class ContinualThreeDLightConeUpdate(ContinualAnimation):
def update(self, dt):
self.mobject.update()
###
@ -236,7 +275,7 @@ class ThinkAboutPondScene(PiCreatureScene):
randy.to_corner(DOWN+LEFT)
bubble = ThoughtBubble(
width = 11,
height = 7,
height = 8,
)
circles = bubble[:3]
angle = -15*DEGREES
@ -245,6 +284,12 @@ class ThinkAboutPondScene(PiCreatureScene):
for circle in circles:
circle.rotate(-angle)
bubble.pin_to(randy)
bubble.shift(DOWN)
bubble[:3].rotate(np.pi, axis = UP+2*RIGHT, about_edge = UP+LEFT)
bubble[:3].scale(0.7, about_edge = DOWN+RIGHT)
bubble[:3].shift(1.5*DOWN)
for oval in bubble[:3]:
oval.rotate(TAU/3)
self.play(
randy.change, "thinking",
@ -252,7 +297,7 @@ class ThinkAboutPondScene(PiCreatureScene):
)
self.wait(2)
self.play(randy.change, "happy", bubble)
self.wait(2)
self.wait(4)
self.play(randy.change, "hooray", bubble)
self.wait(2)
@ -615,7 +660,7 @@ class MathematicalWebOfConnections(PiCreatureScene):
jerk, randy = self.pi_creatures
words = self.words = TextMobject(
"$\\pi$ is not",
"I am not",
"fundamentally \\\\",
"about circles"
)
@ -657,9 +702,8 @@ class MathematicalWebOfConnections(PiCreatureScene):
formula_equals_x = formula.get_part_by_tex("=").get_center()[0]
formula.shift((basel_equals_x - formula_equals_x)*RIGHT)
formulas.move_to(randy)
formulas.to_edge(UP)
formulas.shift_onto_screen()
formulas.to_corner(UP+RIGHT)
formulas.shift(2*LEFT)
self.formulas = formulas
self.play(
@ -1165,6 +1209,9 @@ class IntroduceScreen(Scene):
"num_rays" : 250,
"min_ray_angle" : 0,
"max_ray_angle" : TAU,
"source_point" : 2.5*LEFT,
"observer_point" : 3.5*RIGHT,
"screen_height" : 2,
}
def construct(self):
self.setup_elements()
@ -1174,24 +1221,17 @@ class IntroduceScreen(Scene):
def setup_elements(self):
SCREEN_SIZE = 3.0
source_point = self.source_point = 2.5*LEFT
observer_point = 3.5*RIGHT
source_point = self.source_point
observer_point = self.observer_point,
# Light source
light_source = self.light_source = LightSource(
opacity_function = inverse_quadratic(1,2,1),
num_levels = self.num_levels,
radius = self.radius,
max_opacity_ambient = AMBIENT_FULL,
)
light_source.move_source_to(source_point)
light_source = self.light_source = self.get_light_source()
# Screen
screen = self.screen = Rectangle(
width = 0.05,
height = 2,
height = self.screen_height,
mark_paths_closed = True,
fill_color = WHITE,
fill_opacity = 1.0,
@ -1333,6 +1373,16 @@ class IntroduceScreen(Scene):
##
def get_light_source(self):
light_source = LightSource(
opacity_function = inverse_quadratic(1,2,1),
num_levels = self.num_levels,
radius = self.radius,
max_opacity_ambient = AMBIENT_FULL,
)
light_source.move_source_to(self.source_point)
return light_source
def shoot_rays(self, show_creation_kwargs = None):
if show_creation_kwargs is None:
show_creation_kwargs = {}
@ -1489,6 +1539,73 @@ class EarthScene(IntroduceScreen):
})
self.wait()
class ShowLightInThreeDimensions(IntroduceScreen, ThreeDScene):
CONFIG = {
"num_levels" : 200,
}
def construct(self):
light_source = self.get_light_source()
screens = VGroup(
Square(),
RegularPolygon(8),
Circle().insert_n_anchor_points(25),
)
for screen in screens:
screen.scale_to_fit_height(self.screen_height)
screens.rotate(TAU/4, UP)
screens.next_to(self.observer_point, LEFT)
screens.set_stroke(WHITE, 2)
screens.set_fill(WHITE, 0.5)
screen = screens[0]
cone = ThreeDSpotlight(
screen, light_source.ambient_light,
light_source.get_source_point
)
cone_update_anim = ContinualThreeDLightConeUpdate(cone)
self.add(light_source, screen, cone)
self.add(cone_update_anim)
self.move_camera(
phi = 60*DEGREES,
theta = -155*DEGREES,
run_time = 3,
)
self.begin_ambient_camera_rotation()
kwargs = {"run_time" : 2}
self.play(screen.stretch, 0.5, 1, **kwargs)
self.play(screen.stretch, 2, 2, **kwargs)
self.play(Rotate(
screen, TAU/4,
axis = UP+OUT,
rate_func = there_and_back,
run_time = 3,
))
self.play(Transform(screen, screens[1], **kwargs))
self.play(screen.stretch, 0.5, 2, **kwargs)
self.play(Transform(screen, screens[2], **kwargs))
self.wait(2)
self.play(
screen.stretch, 0.5, 1,
screen.stretch, 2, 2,
**kwargs
)
self.play(
screen.stretch, 3, 1,
screen.stretch, 0.7, 2,
**kwargs
)
self.wait(2)
class LightInThreeDimensionsOverlay(Scene):
def construct(self):
words = TextMobject("""
``Solid angle'' \\\\
(measured in ``steradians'')
""")
self.play(Write(words))
self.wait()
class InverseSquareLaw(ThreeDScene):
CONFIG = {
"screen_height" : 1.0,
@ -1628,7 +1745,6 @@ class InverseSquareLaw(ThreeDScene):
unit_distance = self.unit_distance
light_indicator = self.light_indicator
morty = self.morty
dr = ambient_light.radius/ambient_light.num_levels
new_screen = Square(
side_length = self.screen_height,
@ -1640,31 +1756,13 @@ class InverseSquareLaw(ThreeDScene):
new_screen.rotate(TAU/4, UP)
new_screen.move_to(old_screen, IN)
old_screen.fade(1)
screen_group = VGroup(old_screen, new_screen)
cone = VGroup(*[VGroup() for x in range(4)])
cone.set_stroke(width = 0)
cone.set_fill(YELLOW, opacity = 0.5)
corner_directions = [OUT+UP, OUT+DOWN, IN+DOWN, IN+UP]
def update_cone(cone):
corners = map(new_screen.get_corner, corner_directions)
distance = np.linalg.norm(old_screen.get_reference_point() - self.source_point)
n_parts = np.ceil(distance/dr)
alphas = np.linspace(0, 1, n_parts+1)
for face, (c1, c2) in zip(cone, adjacent_pairs(corners)):
face.submobjects = []
for a1, a2 in zip(alphas, alphas[1:]):
face.add(Polygon(
interpolate(source_point, c1, a1),
interpolate(source_point, c1, a2),
interpolate(source_point, c2, a2),
interpolate(source_point, c2, a1),
fill_color = YELLOW,
fill_opacity = ambient_light.opacity_function(a1*distance),
stroke_width = 0
))
cone_update_anim = ContinualUpdateFromFunc(cone, update_cone)
cone_update_anim.update(0)
cone = ThreeDSpotlight(
new_screen, ambient_light,
source_point_func = lambda : source_point
)
cone_update_anim = ContinualThreeDLightConeUpdate(cone)
self.remove(self.spotlight_update, self.light_indicator_update)
self.add(
@ -1690,26 +1788,41 @@ class InverseSquareLaw(ThreeDScene):
run_time = 2,
)
self.wait()
self.screen = screen_group
self.shift_by_distance(1)
self.shift_by_distance(-1)
self.wait()
## Create screen copies
screen_copy = new_screen.copy()
four_copies = VGroup(*[new_screen.copy() for x in range(4)])
nine_copies = VGroup(*[new_screen.copy() for x in range(9)])
def update_four_copies(four_copies):
for mob, corner_direction in zip(four_copies, corner_directions):
mob.move_to(new_screen, corner_direction)
four_copies_update_anim = UpdateFromFunc(four_copies, update_four_copies)
edge_directions = [
UP, UP+OUT, OUT, DOWN+OUT, DOWN, DOWN+IN, IN, UP+IN, ORIGIN
]
def update_nine_copies(nine_copies):
for mob, corner_direction in zip(nine_copies, edge_directions):
mob.move_to(new_screen, corner_direction)
nine_copies_update_anim = UpdateFromFunc(nine_copies, update_nine_copies)
def get_screen_copy_group(distance):
n = int(distance)**2
copies = VGroup(*[new_screen.copy() for x in range(n)])
copies.rotate(-TAU/4, axis = UP)
copies.arrange_submobjects_in_grid(buff = 0)
copies.rotate(TAU/4, axis = UP)
copies.move_to(source_point, IN)
copies.shift(distance*RIGHT*unit_distance)
return copies
screen_copy_groups = map(get_screen_copy_group, range(1, 8))
def get_screen_copy_group_anim(n):
group = screen_copy_groups[n]
prev_group = screen_copy_groups[n-1]
group.save_state()
group.fade(1)
group.replace(prev_group, dim_to_match = 1)
return ApplyMethod(group.restore)
# corner_directions = [UP+OUT, DOWN+OUT, DOWN+IN, UP+IN]
# edge_directions = [
# UP, UP+OUT, OUT, DOWN+OUT, DOWN, DOWN+IN, IN, UP+IN, ORIGIN
# ]
# four_copies = VGroup(*[new_screen.copy() for x in range(4)])
# nine_copies = VGroup(*[new_screen.copy() for x in range(9)])
# def update_four_copies(four_copies):
# for mob, corner_direction in zip(four_copies, corner_directions):
# mob.move_to(new_screen, corner_direction)
# four_copies_update_anim = UpdateFromFunc(four_copies, update_four_copies)
# def update_nine_copies(nine_copies):
# for mob, corner_direction in zip(nine_copies, edge_directions):
# mob.move_to(new_screen, corner_direction)
# nine_copies_update_anim = UpdateFromFunc(nine_copies, update_nine_copies)
three_arrow = DoubleArrow(
source_point + 4*DOWN,
@ -1721,19 +1834,17 @@ class InverseSquareLaw(ThreeDScene):
three.next_to(three_arrow, DOWN)
new_screen.fade(1)
self.add(
ContinualAnimation(screen_copy),
ContinualAnimation(four_copies),
)
# self.add(
# ContinualAnimation(screen_copy),
# ContinualAnimation(four_copies),
# )
self.add(ContinualAnimation(screen_copy_groups[0]))
self.add(ContinualAnimation(screen_copy_groups[1]))
self.play(
screen_group.scale, 2, {"about_edge" : IN + DOWN},
screen_group.shift, unit_distance*RIGHT,
UpdateFromAlphaFunc(
four_copies,
lambda nc, a : nc.set_stroke(width = a).set_fill(opacity = 0.5*a)
),
four_copies_update_anim,
screen_copy.shift, 0.25*OUT, #WHY?
new_screen.scale, 2, {"about_edge" : IN},
new_screen.shift, unit_distance*RIGHT,
get_screen_copy_group_anim(1),
run_time = 2,
)
self.wait()
@ -1744,20 +1855,40 @@ class InverseSquareLaw(ThreeDScene):
run_time = 10,
)
self.begin_ambient_camera_rotation(rate = -0.01)
self.add(ContinualAnimation(nine_copies))
self.add(ContinualAnimation(screen_copy_groups[2]))
self.play(
screen_group.scale, 3./2, {"about_edge" : IN + DOWN},
screen_group.shift, unit_distance*RIGHT,
nine_copies_update_anim,
UpdateFromAlphaFunc(
nine_copies,
lambda nc, a : nc.set_stroke(width = a).set_fill(opacity = 0.5*a)
),
new_screen.scale, 3./2, {"about_edge" : IN},
new_screen.shift, unit_distance*RIGHT,
get_screen_copy_group_anim(2),
GrowFromPoint(three_arrow, three_arrow.get_left()),
Write(three, rate_func = squish_rate_func(smooth, 0.5, 1)),
run_time = 2,
)
self.wait(10)
self.begin_ambient_camera_rotation(rate = -0.01)
self.play(LaggedStart(
ApplyMethod, screen_copy_groups[2],
lambda m : (m.highlight, RED),
run_time = 5,
rate_func = there_and_back,
))
self.wait(2)
self.move_camera(distance = 18)
self.play(*[
ApplyMethod(mob.fade, 1)
for mob in screen_copy_groups[:2]
])
last_group = screen_copy_groups[2]
for n in range(4, len(screen_copy_groups)+1):
group = screen_copy_groups[n-1]
self.add(ContinualAnimation(group))
self.play(
new_screen.scale, float(n)/(n-1), {"about_edge" : IN},
new_screen.shift, unit_distance*RIGHT,
get_screen_copy_group_anim(n-1),
last_group.fade, 1,
)
last_group = group
self.wait()
###
@ -2189,7 +2320,25 @@ class TwoLightSourcesScene(ManipulateLightsourceSetups):
self.wait()
#Write IPT
self.play(Write(theorem))
a_part = theorem[:2]
b_part = theorem[2:5]
h_part = theorem[5:]
for part in a_part, b_part, h_part:
part.save_state()
part.scale(3)
part.fade(1)
a_part.move_to(lsA)
b_part.move_to(lsB)
h_part.move_to(lsC)
self.play(*map(FadeOut, [lsA, lsB, lsC, indicator]))
for ls, part in (lsA, a_part), (lsB, b_part), (lsC, h_part):
self.add(ls)
self.play(
SwitchOn(ls.ambient_light, run_time = 2),
FadeIn(ls.lighthouse),
part.restore
)
self.wait()
self.play(
Write(theorem_name),
@ -2874,7 +3023,7 @@ class PondScene(ThreeDScene):
self.zoomable_mobs.add(lake0)
# Morty and indicator
morty = Randolph().scale(0.3)
morty = Mortimer().flip().scale(0.3)
morty.next_to(OBSERVER_POINT,DOWN)
indicator = LightIndicator(precision = 2,
radius = INDICATOR_RADIUS,
@ -3622,6 +3771,42 @@ class PondScene(ThreeDScene):
self.play(randy.change,"happy")
self.play(randy.change,"hooray")
class CircumferenceText(Scene):
CONFIG = {"n" : 16}
def construct(self):
words = TextMobject("Circumference %d"%self.n)
words.scale(1.25)
words.to_corner(UP+LEFT)
self.add(words)
class CenterOfLargerCircleOverlayText(Scene):
def construct(self):
words = TextMobject("Center of \\\\ larger circle")
arrow = Vector(DOWN+LEFT, color = WHITE)
arrow.shift(words.get_bottom() + SMALL_BUFF*DOWN - arrow.get_start())
group = VGroup(words, arrow)
group.scale_to_fit_height(2*SPACE_HEIGHT - 1)
group.to_edge(UP)
self.add(group)
class DiameterWordOverlay(Scene):
def construct(self):
word = TextMobject("Diameter")
word.scale_to_fit_width(SPACE_WIDTH)
word.rotate(-45*DEGREES)
self.play(Write(word))
self.wait()
class YayIPTApplies(TeacherStudentsScene):
def construct(self):
self.teacher_says(
"Heyo! The Inverse \\\\ Pythagorean Theorem \\\\ applies!",
bubble_kwargs = {"width" : 5},
target_mode = "surprised"
)
self.change_student_modes(*3*["hooray"])
self.wait(2)
class WalkThroughOneMoreStep(TeacherStudentsScene):
def construct(self):
self.student_says("""
@ -3631,6 +3816,113 @@ class WalkThroughOneMoreStep(TeacherStudentsScene):
self.play(self.teacher.change, "happy")
self.wait(4)
class ThinkBackToHowAmazingThisIs(ThreeDScene):
CONFIG = {
"x_radius" : 100,
"max_shown_n" : 20,
}
def construct(self):
self.show_sum()
self.show_giant_circle()
def show_sum(self):
number_line = NumberLine(
x_min = -self.x_radius,
x_max = self.x_radius,
numbers_to_show = range(-self.max_shown_n, self.max_shown_n),
)
number_line.add_numbers()
number_line.shift(2*DOWN)
positive_dots, negative_dots = [
VGroup(*[
Dot(number_line.number_to_point(u*x))
for x in range(1, int(self.x_radius), 2)
])
for u in 1, -1
]
dot_pairs = it.starmap(VGroup, zip(positive_dots, negative_dots))
# Decimal
decimal = DecimalNumber(0, num_decimal_points = 6)
decimal.to_edge(UP)
terms = [2./(n**2) for n in range(1, 100, 2)]
partial_sums = np.cumsum(terms)
# pi^2/4 label
brace = Brace(decimal, DOWN)
pi_term = TexMobject("\pi^2 \over 4")
pi_term.next_to(brace, DOWN)
term_mobjects = VGroup()
for n in range(1, self.max_shown_n, 2):
p_term = TexMobject("\\left(\\frac{1}{%d}\\right)^2"%n)
n_term = TexMobject("\\left(\\frac{-1}{%d}\\right)^2"%n)
group = VGroup(p_term, n_term)
group.scale(0.7)
p_term.next_to(number_line.number_to_point(n), UP, LARGE_BUFF)
n_term.next_to(number_line.number_to_point(-n), UP, LARGE_BUFF)
term_mobjects.add(group)
term_mobjects.gradient_highlight(BLUE, YELLOW)
plusses = VGroup(*[
VGroup(*[
TexMobject("+").next_to(
number_line.number_to_point(u*n), UP, buff = 1.25,
)
for u in -1, 1
])
for n in range(0, self.max_shown_n, 2)
])
zoom_out = AmbientMovement(
self.camera.rotation_mobject,
direction = OUT, rate = 0.4
)
def update_decimal(decimal):
z = self.camera.rotation_mobject.get_center()[2]
decimal.scale_to_fit_height(0.07*z)
decimal.move_to(0.7*z*UP)
scale_decimal = ContinualUpdateFromFunc(decimal, update_decimal)
self.add(number_line, *dot_pairs)
self.add(zoom_out, scale_decimal)
tuples = zip(term_mobjects, plusses, partial_sums)
run_time = 1
for term_mobs, plus_pair, partial_sum in tuples:
self.play(
FadeIn(term_mobs),
Write(plus_pair, run_time = 1),
ChangeDecimalToValue(decimal, partial_sum),
run_time = run_time
)
self.wait(run_time)
run_time *= 0.9
self.play(ChangeDecimalToValue(decimal, np.pi**2/4, run_time = 5))
zoom_out.begin_wind_down()
self.wait()
self.remove(zoom_out, scale_decimal)
self.play(*map(FadeOut, it.chain(
term_mobjects, plusses,
number_line.numbers, [decimal]
)))
self.number_line = number_line
def show_giant_circle(self):
self.number_line.main_line.insert_n_anchor_points(10000)
everything = VGroup(*self.mobjects)
circle = everything.copy()
circle.move_to(ORIGIN)
circle.apply_function(
lambda (x, y, z) : complex_to_R3(7*np.exp(complex(0, 0.0315*x)))
)
circle.rotate(-TAU/4, about_point = ORIGIN)
circle.center()
self.play(Transform(everything, circle, run_time = 6))
class ButWait(TeacherStudentsScene):
def construct(self):
self.student_says(
@ -4044,50 +4336,6 @@ class ArcHighlightOverlaySceneCircumferenceSixteen(ArcHighlightOverlaySceneCircu
"n" : 3,
}
class ThumbnailScene(Scene):
def construct(self):
equation = TexMobject("1+{1\over 4}+{1\over 9}+{1\over 16}+{1\over 25}+\dots")
equation.scale(1.5)
equation.move_to(1.5 * UP)
q_mark = TexMobject("=?", color = LIGHT_COLOR).scale(5)
q_mark.next_to(equation, DOWN, buff = 1.5)
#equation.move_to(2 * UP)
#q_mark = TexMobject("={\pi^2\over 6}", color = LIGHT_COLOR).scale(3)
#q_mark.next_to(equation, DOWN, buff = 1)
lake_radius = 6
lake_center = ORIGIN
op_scale = 0.4
lake = Circle(
fill_color = LAKE_COLOR,
fill_opacity = LAKE_OPACITY,
radius = lake_radius,
stroke_color = LAKE_STROKE_COLOR,
stroke_width = LAKE_STROKE_WIDTH,
)
lake.move_to(lake_center)
for i in range(16):
theta = -TAU/4 + (i + 0.5) * TAU/16
pos = lake_center + lake_radius * np.array([np.cos(theta), np.sin(theta), 0])
ls = LightSource(
radius = 15.0,
num_levels = 150,
max_opacity_ambient = 1.0,
opacity_function = inverse_quadratic(1,op_scale,1)
)
ls.move_source_to(pos)
lake.add(ls.ambient_light, ls.lighthouse)
self.add(lake)
self.add(equation, q_mark)
self.wait()
class InfiniteCircleScene(PiCreatureScene):
def construct(self):
@ -4165,6 +4413,73 @@ class InfiniteCircleScene(PiCreatureScene):
self.wait()
class Credits(Scene):
def construct(self):
credits = VGroup(*[
VGroup(*map(TextMobject, pair))
for pair in [
("Primary writer and animator:", "Ben Hambrecht"),
("Editing, advising, narrating:", "Grant Sanderson"),
("Based on a paper originally by:", "Johan Wästlund"),
]
])
for credit, color in zip(credits, [MAROON_D, BLUE_D, WHITE]):
credit[1].highlight(color)
credit.arrange_submobjects(DOWN, buff = SMALL_BUFF)
credits.arrange_submobjects(DOWN, buff = LARGE_BUFF)
credits.center()
patreon_logo = PatreonLogo()
patreon_logo.to_edge(UP)
for credit in credits:
self.play(LaggedStart(FadeIn, credit[0]))
self.play(FadeIn(credit[1]))
self.wait()
self.play(
credits.next_to, patreon_logo.get_bottom(), DOWN, MED_LARGE_BUFF,
DrawBorderThenFill(patreon_logo)
)
self.wait()
class Promotion(PiCreatureScene):
CONFIG = {
"seconds_to_blink" : 5,
}
def construct(self):
url = TextMobject("https://brilliant.org/3b1b/")
url.to_corner(UP+LEFT)
rect = Rectangle(height = 9, width = 16)
rect.scale_to_fit_height(5.5)
rect.next_to(url, DOWN)
rect.to_edge(LEFT)
self.play(
Write(url),
self.pi_creature.change, "raise_right_hand"
)
self.play(ShowCreation(rect))
self.wait(2)
self.change_mode("thinking")
self.wait()
self.look_at(url)
self.wait(10)
self.change_mode("happy")
self.wait(10)
self.change_mode("raise_right_hand")
self.wait(10)
self.remove(rect)
self.play(
url.next_to, self.pi_creature, UP+LEFT
)
url_rect = SurroundingRectangle(url)
self.play(ShowCreation(url_rect))
self.play(FadeOut(url_rect))
self.wait(3)
class BaselPatreonThanks(PatreonEndScreen):
CONFIG = {
"specific_patrons" : [
@ -4182,7 +4497,7 @@ class BaselPatreonThanks(PatreonEndScreen):
"Achille Brighton",
"Rish Kundalia",
"Yana Chernobilsky",
"Shìmín kuāng",
"Shìmín Ku$\\overline{\\text{a}}$ng",
"Mathew Bramson",
"Jerry Ling",
"Mustafa Mahdi",
@ -4272,8 +4587,6 @@ class BaselPatreonThanks(PatreonEndScreen):
self.add_foreground_mobject(next_video)
PatreonEndScreen.construct(self)
class Thumbnail(Scene):
CONFIG = {
"light_source_config" : {
@ -4291,7 +4604,7 @@ class Thumbnail(Scene):
)
equation.scale(1.8)
equation.move_to(2*UP)
equation.set_stroke(BLACK, 1)
equation.set_stroke(RED, 1)
answer = TexMobject("= \\frac{\\pi^2}{6}", color = LIGHT_COLOR)
answer.scale(3)
answer.set_stroke(RED, 1)
@ -4336,7 +4649,3 @@ class Thumbnail(Scene):