mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Beginning of ShowPlan in Uncertainty
This commit is contained in:
parent
6f829c98fb
commit
3b8bbbccab
1 changed files with 139 additions and 47 deletions
|
@ -39,55 +39,46 @@ class GaussianDistributionWrapper(Line):
|
||||||
"""
|
"""
|
||||||
This is meant to encode a 2d normal distribution as
|
This is meant to encode a 2d normal distribution as
|
||||||
a mobject (so as to be able to have it be interpolated
|
a mobject (so as to be able to have it be interpolated
|
||||||
during animations). It is a line whose start_point coordinates
|
during animations). It is a line whose center is the mean
|
||||||
encode the coordinates of mu, and whose end_point - start_point
|
mu of a distribution, and whose radial vector (center to end)
|
||||||
encodes the coordinates of sigma.
|
is the distribution's standard deviation
|
||||||
"""
|
"""
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"stroke_width" : 0,
|
"stroke_width" : 0,
|
||||||
"mu_x" : 0,
|
"mu" : ORIGIN,
|
||||||
"sigma_x" : 1,
|
"sigma" : RIGHT,
|
||||||
"mu_y" : 0,
|
|
||||||
"sigma_y" : 0,
|
|
||||||
}
|
}
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
Line.__init__(self, ORIGIN, RIGHT, **kwargs)
|
Line.__init__(self, ORIGIN, RIGHT, **kwargs)
|
||||||
self.change_parameters(self.mu_x, self.mu_y, self.sigma_x, self.sigma_y)
|
self.change_parameters(self.mu, self.sigma)
|
||||||
|
|
||||||
def change_parameters(self, mu_x = None, mu_y = None, sigma_x = None, sigma_y = None):
|
def change_parameters(self, mu = None, sigma = None):
|
||||||
curr_parameters = self.get_parameteters()
|
curr_mu, curr_sigma = self.get_parameters()
|
||||||
args = [mu_x, mu_y, sigma_x, sigma_y]
|
mu = mu if mu is not None else curr_mu
|
||||||
new_parameters = [
|
sigma = sigma if sigma is not None else curr_sigma
|
||||||
arg or curr
|
self.put_start_and_end_on(mu - sigma, mu + sigma)
|
||||||
for curr, arg in zip(curr_parameters, args)
|
|
||||||
]
|
|
||||||
mu_x, mu_y, sigma_x, sigma_y = new_parameters
|
|
||||||
mu_point = mu_x*RIGHT + mu_y*UP
|
|
||||||
sigma_vect = sigma_x*RIGHT + sigma_y*UP
|
|
||||||
self.put_start_and_end_on(mu_point, mu_point + sigma_vect)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def get_parameteters(self):
|
def get_parameters(self):
|
||||||
""" Return mu_x, mu_y, sigma_x, sigma_y"""
|
""" Return mu_x, mu_y, sigma_x, sigma_y"""
|
||||||
start, end = self.get_start_and_end()
|
center, end = self.get_center(), self.get_end()
|
||||||
return tuple(it.chain(start[:2], (end - start)[:2]))
|
return center, end-center
|
||||||
|
|
||||||
def get_random_points(self, size = 1):
|
def get_random_points(self, size = 1):
|
||||||
mu_x, mu_y, sigma_x, sigma_y = self.get_parameteters()
|
mu, sigma = self.get_parameters()
|
||||||
x_vals = np.random.normal(mu_x, sigma_x, size)
|
|
||||||
y_vals = np.random.normal(mu_y, sigma_y, size)
|
|
||||||
return np.array([
|
return np.array([
|
||||||
x*RIGHT + y*UP
|
np.array([
|
||||||
for x, y in zip(x_vals, y_vals)
|
np.random.normal(mu_coord, sigma_coord)
|
||||||
|
for mu_coord, sigma_coord in zip(mu, sigma)
|
||||||
|
])
|
||||||
|
for x in range(size)
|
||||||
])
|
])
|
||||||
|
|
||||||
class ProbabalisticMobjectCloud(ContinualAnimation):
|
class ProbabalisticMobjectCloud(ContinualAnimation):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"fill_opacity" : 0.25,
|
"fill_opacity" : 0.25,
|
||||||
"n_copies" : 100,
|
"n_copies" : 100,
|
||||||
"gaussian_distribution_wrapper_config" : {
|
"gaussian_distribution_wrapper_config" : {}
|
||||||
"sigma_x" : 1,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
def __init__(self, prototype, **kwargs):
|
def __init__(self, prototype, **kwargs):
|
||||||
digest_config(self, kwargs)
|
digest_config(self, kwargs)
|
||||||
|
@ -142,6 +133,14 @@ class ProbabalisticVectorCloud(ProbabalisticMobjectCloud):
|
||||||
point
|
point
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class RadarDish(SVGMobject):
|
||||||
|
CONFIG = {
|
||||||
|
"file_name" : "radar_dish",
|
||||||
|
"color" : LIGHT_GREY,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###################
|
###################
|
||||||
|
|
||||||
class MentionUncertaintyPrinciple(TeacherStudentsScene):
|
class MentionUncertaintyPrinciple(TeacherStudentsScene):
|
||||||
|
@ -152,32 +151,33 @@ class MentionUncertaintyPrinciple(TeacherStudentsScene):
|
||||||
dot_cloud = ProbabalisticDotCloud()
|
dot_cloud = ProbabalisticDotCloud()
|
||||||
vector_cloud = ProbabalisticVectorCloud(
|
vector_cloud = ProbabalisticVectorCloud(
|
||||||
gaussian_distribution_wrapper_config = {"sigma_x" : 0.2},
|
gaussian_distribution_wrapper_config = {"sigma_x" : 0.2},
|
||||||
center_func = dot_cloud.gaussian_distribution_wrapper.get_start,
|
center_func = lambda : dot_cloud.gaussian_distribution_wrapper.get_parameters()[0],
|
||||||
)
|
)
|
||||||
for cloud in dot_cloud, vector_cloud:
|
for cloud in dot_cloud, vector_cloud:
|
||||||
gdw = cloud.gaussian_distribution_wrapper
|
cloud.gaussian_distribution_wrapper.next_to(
|
||||||
gdw.move_to(title.get_center(), LEFT)
|
title, DOWN, 2*LARGE_BUFF
|
||||||
gdw.shift(2*DOWN)
|
)
|
||||||
vector_cloud.gaussian_distribution_wrapper.shift(3*RIGHT)
|
vector_cloud.gaussian_distribution_wrapper.shift(3*RIGHT)
|
||||||
|
|
||||||
def get_brace_text_group_update(gdw, vect, text):
|
def get_brace_text_group_update(gdw, vect, text, color):
|
||||||
brace = Brace(gdw, vect)
|
brace = Brace(gdw, vect)
|
||||||
text = brace.get_tex("\\sigma_{\\text{%s}}"%text, buff = SMALL_BUFF)
|
text = brace.get_tex("2\\sigma_{\\text{%s}}"%text, buff = SMALL_BUFF)
|
||||||
group = VGroup(brace, text)
|
group = VGroup(brace, text)
|
||||||
def update_group(group):
|
def update_group(group):
|
||||||
brace, text = group
|
brace, text = group
|
||||||
brace.match_width(gdw, stretch = True)
|
brace.match_width(gdw, stretch = True)
|
||||||
brace.next_to(gdw, vect)
|
brace.next_to(gdw, vect)
|
||||||
text.next_to(brace, vect, buff = SMALL_BUFF)
|
text.next_to(brace, vect, buff = SMALL_BUFF)
|
||||||
|
group.highlight(color)
|
||||||
return ContinualUpdateFromFunc(group, update_group)
|
return ContinualUpdateFromFunc(group, update_group)
|
||||||
|
|
||||||
dot_brace_anim = get_brace_text_group_update(
|
dot_brace_anim = get_brace_text_group_update(
|
||||||
dot_cloud.gaussian_distribution_wrapper,
|
dot_cloud.gaussian_distribution_wrapper,
|
||||||
DOWN, "position",
|
DOWN, "position", dot_cloud.color
|
||||||
)
|
)
|
||||||
vector_brace_anim = get_brace_text_group_update(
|
vector_brace_anim = get_brace_text_group_update(
|
||||||
vector_cloud.gaussian_distribution_wrapper,
|
vector_cloud.gaussian_distribution_wrapper,
|
||||||
UP, "momentum",
|
UP, "momentum", vector_cloud.color
|
||||||
)
|
)
|
||||||
|
|
||||||
self.add(title)
|
self.add(title)
|
||||||
|
@ -195,7 +195,7 @@ class MentionUncertaintyPrinciple(TeacherStudentsScene):
|
||||||
# self.wait(2)
|
# self.wait(2)
|
||||||
self.play(
|
self.play(
|
||||||
dot_cloud.gaussian_distribution_wrapper.change_parameters,
|
dot_cloud.gaussian_distribution_wrapper.change_parameters,
|
||||||
{"sigma_x" : 0.1},
|
{"sigma" : 0.1*RIGHT},
|
||||||
run_time = 2,
|
run_time = 2,
|
||||||
)
|
)
|
||||||
self.wait()
|
self.wait()
|
||||||
|
@ -206,7 +206,7 @@ class MentionUncertaintyPrinciple(TeacherStudentsScene):
|
||||||
self.add(vector_brace_anim)
|
self.add(vector_brace_anim)
|
||||||
self.play(
|
self.play(
|
||||||
vector_cloud.gaussian_distribution_wrapper.change_parameters,
|
vector_cloud.gaussian_distribution_wrapper.change_parameters,
|
||||||
{"sigma_x" : 1},
|
{"sigma" : RIGHT},
|
||||||
self.get_student_changes(*3*["confused"]),
|
self.get_student_changes(*3*["confused"]),
|
||||||
run_time = 3,
|
run_time = 3,
|
||||||
)
|
)
|
||||||
|
@ -214,17 +214,17 @@ class MentionUncertaintyPrinciple(TeacherStudentsScene):
|
||||||
for x in range(2):
|
for x in range(2):
|
||||||
self.play(
|
self.play(
|
||||||
dot_cloud.gaussian_distribution_wrapper.change_parameters,
|
dot_cloud.gaussian_distribution_wrapper.change_parameters,
|
||||||
{"sigma_x" : 2},
|
{"sigma" : 2*RIGHT},
|
||||||
vector_cloud.gaussian_distribution_wrapper.change_parameters,
|
vector_cloud.gaussian_distribution_wrapper.change_parameters,
|
||||||
{"sigma_x" : 0.1},
|
{"sigma" : 0.1*RIGHT},
|
||||||
run_time = 3,
|
run_time = 3,
|
||||||
)
|
)
|
||||||
self.change_student_modes("thinking", "erm", "sassy")
|
self.change_student_modes("thinking", "erm", "sassy")
|
||||||
self.play(
|
self.play(
|
||||||
dot_cloud.gaussian_distribution_wrapper.change_parameters,
|
dot_cloud.gaussian_distribution_wrapper.change_parameters,
|
||||||
{"sigma_x" : 0.1},
|
{"sigma" : 0.1*RIGHT},
|
||||||
vector_cloud.gaussian_distribution_wrapper.change_parameters,
|
vector_cloud.gaussian_distribution_wrapper.change_parameters,
|
||||||
{"sigma_x" : 1},
|
{"sigma" : 1*RIGHT},
|
||||||
run_time = 3,
|
run_time = 3,
|
||||||
)
|
)
|
||||||
self.wait()
|
self.wait()
|
||||||
|
@ -299,7 +299,8 @@ class FourierTradeoff(Scene):
|
||||||
t_min = time_mean - time_radius,
|
t_min = time_mean - time_radius,
|
||||||
t_max = time_mean + time_radius,
|
t_max = time_mean + time_radius,
|
||||||
n_samples = 2*time_radius*17,
|
n_samples = 2*time_radius*17,
|
||||||
complex_to_real_func = abs,
|
# complex_to_real_func = abs,
|
||||||
|
complex_to_real_func = lambda z : z.real,
|
||||||
color = FREQUENCY_COLOR,
|
color = FREQUENCY_COLOR,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -351,8 +352,99 @@ class FourierTradeoff(Scene):
|
||||||
self.wait()
|
self.wait()
|
||||||
self.wait()
|
self.wait()
|
||||||
|
|
||||||
|
class ShowPlan(PiCreatureScene):
|
||||||
|
def construct(self):
|
||||||
|
self.add_title()
|
||||||
|
words = self.get_words()
|
||||||
|
self.play_sound_anims(words[0])
|
||||||
|
self.play_doppler_anims(words[1], words[0])
|
||||||
|
self.play_quantum_anims(words[2], words[1])
|
||||||
|
|
||||||
|
def add_title(self):
|
||||||
|
title = TextMobject("The plan")
|
||||||
|
title.scale(1.5)
|
||||||
|
title.to_edge(UP)
|
||||||
|
h_line = Line(LEFT, RIGHT).scale(SPACE_WIDTH)
|
||||||
|
h_line.next_to(title, DOWN)
|
||||||
|
self.add(title, h_line)
|
||||||
|
|
||||||
|
def get_words(self):
|
||||||
|
colors = [YELLOW, GREEN, BLUE]
|
||||||
|
topics = ["sound waves", "Doppler radar", "quantum particles"]
|
||||||
|
words = VGroup()
|
||||||
|
for topic, color in zip(topics, colors):
|
||||||
|
word = TextMobject("Uncertainty for", topic)
|
||||||
|
word[1].highlight(color)
|
||||||
|
words.add(word)
|
||||||
|
words.arrange_submobjects(DOWN, aligned_edge = LEFT, buff = LARGE_BUFF)
|
||||||
|
words.to_edge(LEFT)
|
||||||
|
|
||||||
|
return words
|
||||||
|
|
||||||
|
def play_sound_anims(self, word):
|
||||||
|
morty = self.pi_creature
|
||||||
|
wave = FunctionGraph(
|
||||||
|
lambda x : 0.3*np.sin(15*x)*np.sin(0.5*x),
|
||||||
|
x_min = 0, x_max = 30,
|
||||||
|
num_anchor_points = 500,
|
||||||
|
)
|
||||||
|
wave.next_to(word, RIGHT)
|
||||||
|
rect = BackgroundRectangle(wave, fill_opacity = 1)
|
||||||
|
rect.stretch(2, 1)
|
||||||
|
rect.next_to(wave, LEFT, buff = 0)
|
||||||
|
wave_shift = AmbientMovement(
|
||||||
|
wave, direction = LEFT, rate = 5
|
||||||
|
)
|
||||||
|
wave_fader = UpdateFromAlphaFunc(
|
||||||
|
wave,
|
||||||
|
lambda w, a : w.set_stroke(width = 3*a)
|
||||||
|
)
|
||||||
|
checkmark = self.get_checkmark(word)
|
||||||
|
|
||||||
|
self.add(wave_shift)
|
||||||
|
self.add_foreground_mobjects(rect, word)
|
||||||
|
self.play(
|
||||||
|
Animation(word),
|
||||||
|
wave_fader,
|
||||||
|
morty.change, "raise_right_hand", word
|
||||||
|
)
|
||||||
|
self.wait(2)
|
||||||
|
wave_fader.rate_func = lambda a : 1-smooth(a)
|
||||||
|
self.add_foreground_mobjects(checkmark)
|
||||||
|
self.play(
|
||||||
|
Write(checkmark),
|
||||||
|
morty.change, "happy",
|
||||||
|
wave_fader,
|
||||||
|
)
|
||||||
|
self.remove_foreground_mobjects(rect, word)
|
||||||
|
self.add(word)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
def play_doppler_anims(self, word, to_fade):
|
||||||
|
morty = self.pi_creature
|
||||||
|
|
||||||
|
radar_dish = RadarDish()
|
||||||
|
radar_dish.next_to(to_fade, RIGHT)
|
||||||
|
self.add(radar_dish)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
to_fade.fade, 0.5,
|
||||||
|
Write(word),
|
||||||
|
morty.change, "pondering",
|
||||||
|
run_time = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
def play_quantum_anims(self, word, to_fade):
|
||||||
|
pass
|
||||||
|
|
||||||
|
##
|
||||||
|
|
||||||
|
def get_checkmark(self, word):
|
||||||
|
checkmark = TexMobject("\\checkmark")
|
||||||
|
checkmark.highlight(GREEN)
|
||||||
|
checkmark.scale(1.5)
|
||||||
|
checkmark.next_to(word, UP+RIGHT, buff = 0)
|
||||||
|
return checkmark
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue