Merge branch 'master' into eop

This commit is contained in:
Ben Hambrecht 2018-04-10 09:26:40 +02:00
commit 9e2ce6ea62
6 changed files with 403 additions and 13 deletions

View file

@ -0,0 +1,75 @@
from big_ol_pile_of_manim_imports import *
NAME_WITH_SPACES = "Prime Meridian"
DIAMETER = 3.0
RADIUS = DIAMETER / 2
LETTER_SCALE = 1
class NameAnimationScene(Scene):
def construct(self):
name = ''.join(NAME_WITH_SPACES.split(' '))
letters = list(name)
nb_letters = len(letters)
randy = PiCreature()
randy.move_to(ORIGIN).scale_to_fit_height(0.5 * DIAMETER)
randy.set_color(BLUE_E)
randy.look_at(UP + RIGHT)
self.add(randy)
dtheta = TAU/nb_letters
angles = np.arange(TAU/4,-3 * TAU / 4,-dtheta)
name_mob = VGroup()
for (letter, angle) in zip(letters, angles):
letter_mob = TextMobject(letter).scale(LETTER_SCALE)
pos = RADIUS * np.cos(angle) * RIGHT + RADIUS * np.sin(angle) * UP
letter_mob.move_to(pos)
name_mob.add(letter_mob)
pos2 = RADIUS * np.cos(angles[2]) * RIGHT + RADIUS * np.sin(angles[2]) * UP
self.play(
LaggedStart(Write, name_mob, run_time = 3),
ApplyMethod(randy.look_at, pos2, run_time = 3)
)
for i in range(2,nb_letters + 2):
group = []
for (j,letter_mob) in enumerate(name_mob.submobjects):
new_angle = TAU / 4 - i * j * dtheta
new_pos = RADIUS * np.cos(new_angle) * RIGHT + RADIUS * np.sin(new_angle) * UP
letter_mob.target = letter_mob.copy().move_to(new_pos)
anim = MoveToTarget(letter_mob, path_arc = - j * dtheta)
group.append(anim)
self.play(
AnimationGroup(*group, run_time = 3),
ApplyMethod(randy.look_at,name_mob.submobjects[2], run_time = 3)
)
self.wait(0.5)
thank_you = TextMobject("Thank You!").next_to(randy, DOWN)
new_randy = randy.copy()
new_randy.change("hooray")
new_randy.set_color(BLUE_E)
new_randy.look_at(ORIGIN)
self.play(
Transform(name_mob, thank_you),
Transform(randy, new_randy)
)

303
active_projects/wallis_g.py Normal file
View file

@ -0,0 +1,303 @@
from big_ol_pile_of_manim_imports import *
from once_useful_constructs.light import AmbientLight
from once_useful_constructs.light import Lighthouse
from once_useful_constructs.light import SwitchOn
# from once_useful_constructs.light import LightSource
class IntroduceDistanceProduct(MovingCameraScene):
CONFIG = {
"ambient_light_config": {
"opacity_function": inverse_quadratic(1, 1.1, 1),
"num_levels": 100,
# "num_levels": 10,
"light_radius": 10,
# "radius": 1,
"max_opacity": 0.4,
"color": YELLOW,
},
"num_lighthouses": 6,
"circle_radius": 3,
"observer_color": MAROON_B,
"lighthouse_height": 0.5,
"camera_class": MovingCamera,
}
def construct(self):
self.draw_circle_with_points()
self.turn_into_lighthouses_and_observer()
self.show_sum_of_inverse_squares()
def draw_circle_with_points(self):
circle = Circle(color=BLUE)
circle.scale(self.circle_radius)
lh_dots = self.lh_dots = VGroup(*[
Dot().move_to(circle.point_from_proportion(alpha))
for alpha in np.arange(0, 1, 1.0 / self.num_lighthouses)
])
lh_dot_arrows = VGroup(*[
Arrow(*[
interpolate(circle.get_center(), dot.get_center(), a)
for a in 0.6, 0.9
], buff=0)
for dot in lh_dots
])
evenly_space_dots_label = TextMobject("Evenly-spaced \\\\ dots")
evenly_space_dots_label.scale_to_fit_width(0.5 * circle.get_width())
evenly_space_dots_label.move_to(circle)
special_dot = self.special_dot = Dot(color=self.observer_color)
special_dot.move_to(circle.point_from_proportion(0.04))
special_dot_arrow = Vector(DL)
special_dot_arrow.next_to(special_dot, UR, SMALL_BUFF)
special_dot_arrow.match_color(special_dot)
special_dot_label = TextMobject("Special dot")
special_dot_label.next_to(
special_dot_arrow.get_start(), UP, SMALL_BUFF)
special_dot_label.match_color(special_dot)
special_dot.save_state()
special_dot.next_to(special_dot_arrow, UR)
special_dot.set_fill(opacity=0)
self.play(ShowCreation(circle))
self.play(
LaggedStart(ShowCreation, lh_dots),
LaggedStart(GrowArrow, lh_dot_arrows),
Write(evenly_space_dots_label)
)
self.wait()
self.play(
special_dot.restore,
GrowArrow(special_dot_arrow),
Write(special_dot_label, run_time=1),
FadeOut(VGroup(lh_dot_arrows, evenly_space_dots_label))
)
self.wait()
self.play(FadeOut(VGroup(special_dot_arrow, special_dot_label)))
def turn_into_lighthouses_and_observer(self):
lighthouses = self.lighthouses = VGroup()
lights = self.lights = VGroup()
for dot in self.lh_dots:
point = dot.get_center()
lighthouse = Lighthouse()
lighthouse.scale_to_fit_height(self.lighthouse_height)
lighthouse.move_to(point)
lighthouses.add(lighthouse)
light = AmbientLight(
source_point=VectorizedPoint(point),
**self.ambient_light_config
)
lights.add(light)
observer = self.observer = PiCreature(color=self.observer_color)
observer.flip()
observer.move_to(self.special_dot)
observer.to_edge(RIGHT)
self.play(
LaggedStart(FadeOut, self.lh_dots),
LaggedStart(FadeIn, lighthouses),
LaggedStart(SwitchOn, lights),
)
self.wait()
self.play(FadeIn(observer))
self.play(
observer.scale_to_fit_height, 0.25,
observer.next_to, self.special_dot, RIGHT, 0.5 * SMALL_BUFF,
)
self.wait()
def show_sum_of_inverse_squares(self):
lines = VGroup(*[
Line(self.special_dot.get_center(), dot.get_center())
for dot in self.lh_dots
])
labels = VGroup(*[TexMobject("d_%d" % i) for i in range(len(lines))])
for label, line in zip(labels, lines):
label.scale(0.75)
vect = rotate_vector(line.get_vector(), TAU / 4)
vect *= 2 * SMALL_BUFF / np.linalg.norm(vect)
label.move_to(line.get_center() + vect)
sum_of_inverse_squares = TexMobject(*it.chain(*[
["{1", "\\over", "(", "d_%d" % i, ")", "^2}", "+"]
for i in range(len(lines))
]))
sum_of_inverse_squares.submobjects.pop(-1)
sum_of_inverse_squares.to_edge(UP)
d_terms = sum_of_inverse_squares.get_parts_by_tex("d_")
d_terms.set_color(YELLOW)
plusses = sum_of_inverse_squares.get_parts_by_tex("+")
last_term = sum_of_inverse_squares[-6:]
non_d_terms = VGroup(*filter(
lambda m: m not in d_terms and m not in last_term,
sum_of_inverse_squares
))
brace = Brace(sum_of_inverse_squares, DOWN)
brace_text = brace.get_text("Total intensity of light")
arrow = Vector(DOWN, color=WHITE).next_to(brace, DOWN)
basel_sum = TexMobject(
"{1 \\over 1^2} + ",
"{1 \\over 2^2} + ",
"{1 \\over 3^2} + ",
"{1 \\over 4^2} + ",
"\\cdots",
)
basel_sum.next_to(arrow, DOWN)
basel_cross = Cross(basel_sum)
useful_for = TextMobject("Useful for")
useful_for.next_to(arrow, RIGHT)
wallis_product = TexMobject(
"{2 \\over 1} \\cdot", "{2 \\over 3} \\cdot",
"{4 \\over 3} \\cdot", "{4 \\over 5} \\cdot",
"{6 \\over 5} \\cdot", "{6 \\over 7} \\cdot",
"\\cdots"
)
wallis_product.move_to(basel_sum)
light_rings = VGroup(*it.chain(*self.lights))
self.play(
LaggedStart(ShowCreation, lines),
LaggedStart(Write, labels),
)
circle_group = VGroup(*self.get_top_level_mobjects())
self.wait()
self.play(
ReplacementTransform(labels[-1].copy(), last_term[3]),
Write(VGroup(*it.chain(last_term[:3], last_term[4:])))
)
self.remove(last_term)
self.add(last_term)
self.wait()
self.play(
Write(non_d_terms),
ReplacementTransform(
labels[:-1].copy(),
d_terms[:-1],
),
circle_group.scale, 0.8, {"about_edge": DOWN}
)
self.wait()
self.play(LaggedStart(
ApplyMethod, light_rings,
lambda m: (m.set_fill, {"opacity": 2 * m.get_fill_opacity()}),
rate_func=there_and_back,
run_time=3,
))
self.wait()
# Mention useful just to basel problem
circle_group.save_state()
self.play(
circle_group.scale, 0.5,
circle_group.to_corner, DL,
)
self.play(
GrowFromCenter(brace),
Write(brace_text)
)
self.wait()
self.play(
FadeOut(brace_text),
GrowArrow(arrow),
FadeIn(useful_for),
FadeIn(basel_sum),
)
self.wait()
self.play(
ShowCreation(basel_cross),
FadeOut(VGroup(arrow, useful_for, brace))
)
basel_group = VGroup(basel_sum, basel_cross)
self.play(
basel_group.scale, 0.5,
basel_group.to_corner, DR,
)
self.play(Write(wallis_product))
self.wait()
# Transition to distance product
self.play(
circle_group.restore,
wallis_product.match_width, basel_sum,
wallis_product.next_to, basel_sum, UP, {"aligned_edge": RIGHT},
)
self.play(
d_terms.shift, d_terms.get_height() * UP / 2,
*[
FadeOut(mob)
for mob in sum_of_inverse_squares
if mob not in d_terms and mob not in plusses
]
)
self.wait()
self.play(
FadeOut(plusses),
d_terms.arrange_submobjects, RIGHT, 0.5 * SMALL_BUFF,
d_terms.move_to, sum_of_inverse_squares, DOWN,
)
self.wait()
# Label distance product
brace = Brace(d_terms, UP, buff=SMALL_BUFF)
distance_product_label = brace.get_text("``Distance product''")
self.play(
GrowFromCenter(brace),
Write(distance_product_label)
)
line_copies = lines.copy().set_color(RED)
self.play(LaggedStart(ShowCreationThenDestruction, line_copies))
self.wait()
self.play(LaggedStart(
ApplyFunction, light_rings,
lambda mob: (
lambda m: m.shift(MED_SMALL_BUFF * UP).set_fill(opacity=2 * m.get_fill_opacity()),
mob
),
rate_func=wiggle,
run_time=6,
))
self.wait()

View file

@ -1,6 +1,9 @@
from __future__ import absolute_import
from constants import FRAME_HEIGHT
from camera.camera import Camera
from mobject.frame import ScreenRectangle
class MovingCamera(Camera):
@ -12,11 +15,14 @@ class MovingCamera(Camera):
"aligned_dimension": "width" # or height
}
def __init__(self, frame, **kwargs):
def __init__(self, frame=None, **kwargs):
"""
frame is a Mobject, (should be a rectangle) determining
which region of space the camera displys
"""
if frame is None:
frame = ScreenRectangle(height=FRAME_HEIGHT)
frame.fade(1)
self.frame = frame
Camera.__init__(self, **kwargs)

View file

@ -67,6 +67,12 @@ X_AXIS = np.array((1., 0., 0.))
Y_AXIS = np.array((0., 1., 0.))
Z_AXIS = np.array((0., 0., 1.))
# Useful abbreviations for diagonals
UL = UP + LEFT
UR = UP + RIGHT
DL = DOWN + LEFT
DR = DOWN + RIGHT
TOP = FRAME_Y_RADIUS * UP
BOTTOM = FRAME_Y_RADIUS * DOWN
LEFT_SIDE = FRAME_X_RADIUS * LEFT

View file

@ -99,14 +99,15 @@ class PiCreature(SVGMobject):
def set_color(self, color):
self.body.set_fill(color)
self.color = color
return self
def change_mode(self, mode):
new_self = self.__class__(
mode=mode,
color=self.color
mode = mode,
)
new_self.scale_to_fit_height(self.get_height())
new_self.match_style(self)
new_self.match_height(self)
if self.is_flipped() ^ new_self.is_flipped():
new_self.flip()
new_self.shift(self.eyes.get_center() - new_self.eyes.get_center())

View file

@ -139,7 +139,7 @@ class Mobject(Container):
self.target = self.copy()
return self.target
#### Transforming operations ######
# Transforming operations
def apply_to_family(self, func):
for mob in self.family_members_with_points():
@ -156,7 +156,7 @@ class Mobject(Container):
"""
Default behavior is to scale about the center of the mobject.
The argument about_edge can be a vector, indicating which side of
the mobject to scale about, e.g., mob.scale(about_edge = RIGHT)
the mobject to scale about, e.g., mob.scale(about_edge = RIGHT)
scales about mob.get_right().
Otherwise, if about_point is given a value, scaling is done with
@ -249,7 +249,7 @@ class Mobject(Container):
mob.apply_over_attr_arrays(repeat_array)
return self
#### In place operations ######
# In place operations.
# Note, much of these are now redundant with default behavior of
# above methods
@ -278,7 +278,7 @@ class Mobject(Container):
self.rotate(TAU / 14, RIGHT + UP, **kwargs)
return self
#### Positioning methods ####
# Positioning methods
def center(self):
self.shift(-self.get_center())
@ -334,7 +334,7 @@ class Mobject(Container):
def align_to(self, mobject_or_point, direction=ORIGIN, alignment_vect=UP):
"""
Examples:
Examples:
mob1.align_to(mob2, UP) moves mob1 vertically so that its
top edge lines ups with mob2's top edge.
@ -488,7 +488,7 @@ class Mobject(Container):
def set_color(self, color=YELLOW_C, family=True):
"""
Condition is function which takes in one arguments, (x, y, z).
Here it just recurses to submobjects, but in subclasses this
Here it just recurses to submobjects, but in subclasses this
should be further implemented based on the the inner workings
of color
"""
@ -521,8 +521,7 @@ class Mobject(Container):
return self
def set_submobject_colors_by_radial_gradient(self, center=None, radius=1, inner_color=WHITE, outer_color=BLACK):
mobs = self.family_members_with_points()
if center == None:
if center is None:
center = self.get_center()
for mob in self.family_members_with_points():
@ -618,7 +617,7 @@ class Mobject(Container):
def get_all_points(self):
return self.get_merged_array("points")
### Getters ###
# Getters
def get_points_defining_boundary(self):
return self.points