On to cycloid animations

This commit is contained in:
Grant Sanderson 2016-03-22 00:01:24 -07:00
parent efcaae4d2a
commit 04077971ee
3 changed files with 158 additions and 20 deletions

View file

@ -30,7 +30,7 @@ class Cycloid(ParametricFunction):
"radius" : 2,
"end_theta" : 3*np.pi/2,
"density" : 5*DEFAULT_POINT_DENSITY_1D,
"color" : BLUE_D
"color" : YELLOW
}
def __init__(self, **kwargs):
digest_config(self, kwargs)

126
brachistochrone/cycloid.py Normal file
View file

@ -0,0 +1,126 @@
import numpy as np
import itertools as it
from helpers import *
from mobject.tex_mobject import TexMobject, TextMobject, Brace
from mobject import Mobject, Mobject1D
from mobject.image_mobject import \
ImageMobject, MobjectFromPixelArray
from topics.three_dimensions import Stars
from animation import Animation
from animation.transform import *
from animation.simple_animations import *
from topics.geometry import *
from topics.characters import Randolph
from topics.functions import *
from mobject.region import Region
from scene import Scene
from scene.zoomed_scene import ZoomedScene
from camera import Camera
from brachistochrone.curves import *
class RollAlongVector(Animation):
def __init__(self, mobject, vector, **kwargs):
radius = mobject.get_width()/2
radians = np.linalg.norm(vector)/radius
last_alpha = 0
digest_config(self, kwargs, locals())
Animation.__init__(self, mobject, **kwargs)
def update_mobject(self, alpha):
d_alpha = alpha - self.last_alpha
self.last_alpha = alpha
self.mobject.rotate_in_place(d_alpha*self.radians)
self.mobject.shift(d_alpha*self.vector)
class CycloidScene(Scene):
CONFIG = {
"point_a" : 6*LEFT+3*UP,
"radius" : 2,
"end_theta" : 2*np.pi
}
def construct(self):
self.generate_cycloid()
self.generate_circle()
self.generate_ceiling()
def grow_parts(self):
self.play(*[
ShowCreation(mob)
for mob in self.circle, self.ceiling
])
def generate_cycloid(self):
self.cycloid = Cycloid(
point_a = self.point_a,
radius = self.radius,
end_theta = self.end_theta
)
def generate_circle(self, **kwargs):
self.circle = Circle(radius = self.radius, **kwargs)
self.circle.shift(self.point_a - self.circle.get_top())
radial_line = Line(
self.circle.get_center(), self.point_a
)
self.circle.add(radial_line)
def generate_ceiling(self):
self.ceiling = Line(SPACE_WIDTH*LEFT, SPACE_WIDTH*RIGHT)
self.ceiling.shift(self.cycloid.get_top()[1]*UP)
def draw_cycloid(self, run_time = 3, **kwargs):
kwargs["run_time"] = run_time
self.play(
RollAlongVector(
self.circle,
self.cycloid.points[-1]-self.cycloid.points[0],
**kwargs
),
ShowCreation(self.cycloid, **kwargs)
)
class IntroduceCycloid(CycloidScene):
def construct(self):
CycloidScene.construct(self)
equation = TexMobject("""
\\dfrac{\\sin(\\theta)}{\\sqrt{y}} =
\\text{constant}
""")
new_eq = equation.copy()
new_eq.to_edge(UP, buff = 1.3)
cycloid_word = TextMobject("Cycloid")
arrow = Arrow(2*UP, cycloid_word)
arrow.reverse_points()
self.play(ShimmerIn(equation))
self.dither()
self.play(
ApplyMethod(equation.shift, 2.2*UP),
ShowCreation(arrow)
)
self.play(ShimmerIn(cycloid_word))
self.dither()
self.grow_parts()
self.draw_cycloid()
self.dither()

View file

@ -329,7 +329,7 @@ class ContinuouslyObeyingSnellsLaw(MultilayeredScene):
self.add(glass)
self.freeze_background()
cycloid = Cycloid()
cycloid = Cycloid(end_theta = np.pi)
cycloid.highlight(YELLOW)
chopped_cycloid = cycloid.copy()
n = cycloid.get_num_points()
@ -337,28 +337,40 @@ class ContinuouslyObeyingSnellsLaw(MultilayeredScene):
chopped_cycloid.reverse_points()
self.play(ShowCreation(cycloid))
self.snells_law_at_every_point(cycloid, chopped_cycloid)
self.show_equation(chopped_cycloid)
# self.play(ShowCreation(cycloid))
# ref_mob = self.snells_law_at_every_point(cycloid, chopped_cycloid)
ref_mob = Point()
self.show_equation(chopped_cycloid, ref_mob)
def snells_law_at_every_point(self, cycloid, chopped_cycloid):
square = Square(side_length = 0.2, color = WHITE)
words = TextMobject("Snell's law at every point")
words = TextMobject(["Snell's law", " at every point"], use_cache = False)
words.show()
snells, rest = words.split()
colon = TextMobject(":")
words.next_to(square)
words.shift(0.3*UP)
combo = Mobject(square, words)
combo.get_center = lambda : square.get_center()
new_snells = snells.copy().center().to_edge(UP, buff = 1.3)
colon.next_to(new_snells)
self.play(MoveAlongPath(
combo, cycloid,
run_time = 3
run_time = 5
))
self.play(MoveAlongPath(
combo, chopped_cycloid,
run_time = 2
run_time = 4
))
dot = Dot(combo.get_center())
self.play(Transform(combo.ingest_sub_mobjects(), dot))
self.play(Transform(square, dot))
self.play(
Transform(snells, new_snells),
Transform(rest, colon)
)
self.dither()
return colon
def get_marks(self, point1, point2):
vert_line = Line(2*DOWN, 2*UP)
@ -375,7 +387,6 @@ class ContinuouslyObeyingSnellsLaw(MultilayeredScene):
arc = Arc(angle_from_vert, start_angle = np.pi/2)
arc.scale(self.arc_radius)
arc.shift(point1)
self.add(arc)
vect_angle = angle_from_vert/2 + np.pi/2
vect = rotate_vector(RIGHT, vect_angle)
theta.center()
@ -384,24 +395,23 @@ class ContinuouslyObeyingSnellsLaw(MultilayeredScene):
return arc, theta, vert_line, tangent_line
def show_equation(self, chopped_cycloid):
point1, point2 = chopped_cycloid.points[-2:]
def show_equation(self, chopped_cycloid, ref_mob):
point2, point1 = chopped_cycloid.points[-2:]
arc, theta, vert_line, tangent_line = self.get_marks(
point1, point2
)
sin, sqrt_y = TexMobject([
equation = TexMobject([
"\\sin(\\theta)",
"\\over \\sqrt{y}",
]).split()
equation = Mobject(sin, sqrt_y)
equation.next_to(Point(self.top), DOWN)
equation.shift(LEFT)
])
sin, sqrt_y = equation.split()
equation.next_to(ref_mob)
const = TexMobject(" = \\text{constant}")
const.next_to(equation)
ceil_point = np.array(point)
ceil_point = np.array(point1)
ceil_point[1] = self.top[1]
brace = Brace(
Mobject(Point(point), Point(ceil_point)),
Mobject(Point(point1), Point(ceil_point)),
RIGHT
)
y_mob = TexMobject("y").next_to(brace)
@ -417,7 +427,9 @@ class ContinuouslyObeyingSnellsLaw(MultilayeredScene):
GrowFromCenter(y_mob)
)
self.dither()
self.play(ShimmerIn(const))
self.play(Transform(
Point(const.get_left()), const
))
self.dither()