Turned VibratingString animation into more general Vibrate

This commit is contained in:
Grant Sanderson 2015-12-20 16:43:22 -08:00
parent d5c70fe0cb
commit 8c5929532a
2 changed files with 43 additions and 35 deletions

View file

@ -1,42 +1,50 @@
import numpy as np
import operator as op
from animation import Animation
from transform import Transform
from mobject import Mobject1D
from mobject import Mobject1D, Mobject
from topics.geometry import Line
from helpers import *
class VibratingString(Animation):
class Vibrate(Animation):
DEFAULT_CONFIG = {
"num_periods" : 1,
"overtones" : 4,
"amplitude" : 0.5,
"radius" : SPACE_WIDTH/2,
"center" : ORIGIN,
"color" : "white",
"run_time" : 3.0,
"alpha_func" : None
"spatial_period" : 6,
"temporal_period" : 1,
"overtones" : 4,
"amplitude" : 0.5,
"radius" : SPACE_WIDTH/2,
"run_time" : 3.0,
"alpha_func" : None
}
def __init__(self, **kwargs):
digest_config(self, kwargs)
def func(x, t):
return sum([
(self.amplitude/((k+1)**2.5))*np.sin(2*mult*t)*np.sin(k*mult*x)
for k in range(self.overtones)
for mult in [(self.num_periods+k)*np.pi]
def __init__(self, mobject = None, **kwargs):
if mobject is None:
mobject = Line(3*LEFT, 3*RIGHT)
Animation.__init__(self, mobject, **kwargs)
def wave_function(self, x, t):
return sum([
reduce(op.mul, [
self.amplitude/(k**2), #Amplitude
np.sin(2*np.pi*(k**1.5)*t/self.temporal_period), #Frequency
np.sin(2*np.pi*k*x/self.spatial_period) #Number of waves
])
self.func = func
Animation.__init__(self, Mobject1D(color = self.color), **kwargs)
for k in range(1, self.overtones+1)
])
def update_mobject(self, alpha):
self.mobject.init_points()
epsilon = self.mobject.epsilon
self.mobject.add_points([
[x*self.radius, self.func(x, alpha*self.run_time)+y, 0]
for x in np.arange(-1, 1, epsilon/self.radius)
for y in epsilon*np.arange(3)
])
self.mobject.shift(self.center)
time = alpha*self.run_time
families = map(
Mobject.get_full_submobject_family,
[self.mobject, self.starting_mobject]
)
for mob, start in zip(*families):
mob.points = np.apply_along_axis(
lambda (x, y, z) : (x, y + self.wave_function(x, time), z),
1, start.points
)
class TurnInsideOut(Transform):

View file

@ -126,7 +126,7 @@ class Piano(ImageMobject):
return keys
class VibratingString(Animation):
class Vibrate(Animation):
DEFAULT_CONFIG = {
"num_periods" : 1,
"overtones" : 4,
@ -302,7 +302,7 @@ class MeasureTheoryToHarmony(IntervalScene):
line = Line(radius*LEFT, radius*RIGHT).highlight("white")
self.play(DelayByOrder(Transform(all_mobs, line)))
self.clear()
self.play(VibratingString(alpha_func = smooth))
self.play(Vibrate(alpha_func = smooth))
self.clear()
self.add(line)
self.dither()
@ -313,12 +313,12 @@ class ChallengeOne(Scene):
title = TextMobject("Challenge #1").to_edge(UP)
start_color = Color("blue")
colors = start_color.range_to("white", 6)
self.bottom_vibration = VibratingString(
self.bottom_vibration = Vibrate(
num_periods = 1, run_time = 3.0,
center = DOWN, color = start_color
)
top_vibrations = [
VibratingString(
Vibrate(
num_periods = freq, run_time = 3.0,
center = 2*UP, color = colors.next()
)
@ -415,8 +415,8 @@ class QuestionAndAnswer(Scene):
def construct(self):
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")
string1 = Vibrate(center = 3*UP, color = "blue")
string2 = Vibrate(num_periods = 2, center = 3.5*UP, color = "green")
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(
@ -466,11 +466,11 @@ class PlaySimpleRatio(Scene):
return str(fraction).replace("/", "_to_")
def construct(self, fraction, color):
string1 = VibratingString(
string1 = Vibrate(
num_periods = 1, run_time = 5.0,
center = DOWN, color = "blue"
)
string2 = VibratingString(
string2 = Vibrate(
num_periods = fraction, run_time = 5.0,
center = 2*UP, color = color
)