mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Finished ScaleUpCenterOfMass of fourier
This commit is contained in:
parent
ad4ceb3f1a
commit
27c6658eb1
1 changed files with 300 additions and 18 deletions
|
@ -1474,6 +1474,9 @@ class DrawFrequencyPlot(WrapCosineGraphAroundCircle, PiCreatureScene):
|
||||||
|
|
||||||
def change_frequency(self, new_freq, **kwargs):
|
def change_frequency(self, new_freq, **kwargs):
|
||||||
kwargs["run_time"] = kwargs.get("run_time", 3)
|
kwargs["run_time"] = kwargs.get("run_time", 3)
|
||||||
|
kwargs["rate_func"] = kwargs.get(
|
||||||
|
"rate_func", bezier([0, 0, 1, 1])
|
||||||
|
)
|
||||||
added_anims = kwargs.get("added_anims", [])
|
added_anims = kwargs.get("added_anims", [])
|
||||||
freq_label = filter(
|
freq_label = filter(
|
||||||
lambda sm : isinstance(sm, DecimalNumber),
|
lambda sm : isinstance(sm, DecimalNumber),
|
||||||
|
@ -2425,11 +2428,12 @@ class WriteComplexExponentialExpression(DrawFrequencyPlot):
|
||||||
circle_plane.add(circle)
|
circle_plane.add(circle)
|
||||||
|
|
||||||
time_axes = self.get_time_axes()
|
time_axes = self.get_time_axes()
|
||||||
time_axes.add_to_back(BackgroundRectangle(
|
time_axes.background_rectangle = BackgroundRectangle(
|
||||||
time_axes,
|
time_axes,
|
||||||
fill_opacity = 0.9,
|
fill_opacity = 0.9,
|
||||||
buff = MED_SMALL_BUFF,
|
buff = MED_SMALL_BUFF,
|
||||||
))
|
)
|
||||||
|
time_axes.add_to_back(time_axes.background_rectangle)
|
||||||
time_axes.scale(self.time_axes_scale_val)
|
time_axes.scale(self.time_axes_scale_val)
|
||||||
time_axes.to_corner(UP+LEFT, buff = 0)
|
time_axes.to_corner(UP+LEFT, buff = 0)
|
||||||
time_axes.set_stroke(color = WHITE, width = 1)
|
time_axes.set_stroke(color = WHITE, width = 1)
|
||||||
|
@ -2956,7 +2960,6 @@ class WriteComplexExponentialExpression(DrawFrequencyPlot):
|
||||||
)
|
)
|
||||||
return VGroup(time_graph.dots, pol_graph.dots)
|
return VGroup(time_graph.dots, pol_graph.dots)
|
||||||
|
|
||||||
|
|
||||||
class WhyAreYouTellingUsThis(TeacherStudentsScene):
|
class WhyAreYouTellingUsThis(TeacherStudentsScene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
self.student_says("Why are you \\\\ telling us this?")
|
self.student_says("Why are you \\\\ telling us this?")
|
||||||
|
@ -3010,19 +3013,23 @@ class BuildUpExpressionStepByStep(TeacherStudentsScene):
|
||||||
class ScaleUpCenterOfMass(WriteComplexExponentialExpression):
|
class ScaleUpCenterOfMass(WriteComplexExponentialExpression):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"time_axes_scale_val" : 0.6,
|
"time_axes_scale_val" : 0.6,
|
||||||
"initial_winding_frequency" : 1.95
|
"initial_winding_frequency" : 2.05
|
||||||
}
|
}
|
||||||
def construct(self):
|
def construct(self):
|
||||||
self.remove(self.pi_creature)
|
self.remove(self.pi_creature)
|
||||||
self.setup_plane()
|
self.setup_plane()
|
||||||
self.setup_graph()
|
self.setup_graph()
|
||||||
self.add_expression()
|
|
||||||
self.add_center_of_mass_dot()
|
self.add_center_of_mass_dot()
|
||||||
|
self.add_expression()
|
||||||
|
|
||||||
self.cross_out_denominator()
|
self.cross_out_denominator()
|
||||||
self.scale_up_center_of_mass()
|
self.scale_up_center_of_mass()
|
||||||
self.what_this_means_for_various_winding_frequencies()
|
self.comment_on_current_signal()
|
||||||
|
|
||||||
|
def add_center_of_mass_dot(self):
|
||||||
|
self.center_of_mass_dot = self.get_center_of_mass_dot()
|
||||||
|
self.generate_center_of_mass_dot_update_anim()
|
||||||
|
self.add(self.center_of_mass_dot)
|
||||||
|
|
||||||
def add_expression(self):
|
def add_expression(self):
|
||||||
expression = TexMobject(
|
expression = TexMobject(
|
||||||
|
@ -3035,30 +3042,305 @@ class ScaleUpCenterOfMass(WriteComplexExponentialExpression):
|
||||||
g[2].highlight(YELLOW)
|
g[2].highlight(YELLOW)
|
||||||
dt[1].highlight(YELLOW)
|
dt[1].highlight(YELLOW)
|
||||||
f.highlight(GREEN)
|
f.highlight(GREEN)
|
||||||
expression.add_background_rectangle()
|
|
||||||
self.expression = expression
|
self.expression = expression
|
||||||
self.add(expression)
|
self.add(expression)
|
||||||
|
|
||||||
self.winding_freq_label.to_edge(RIGHT)
|
self.winding_freq_label.to_edge(RIGHT)
|
||||||
self.winding_freq_label[1].match_color(f)
|
self.winding_freq_label[1].match_color(f)
|
||||||
|
self.winding_freq_label.align_to(
|
||||||
def add_center_of_mass_dot(self):
|
self.circle_plane.coords_to_point(0, 0.1), DOWN
|
||||||
self.center_of_mass_dot = self.get_center_of_mass_dot()
|
)
|
||||||
self.generate_center_of_mass_dot_update_anim()
|
|
||||||
self.add(self.center_of_mass_dot)
|
|
||||||
|
|
||||||
|
|
||||||
def cross_out_denominator(self):
|
def cross_out_denominator(self):
|
||||||
frac = self.expression[0]
|
frac = self.expression[0]
|
||||||
integral = VGroup(*self.expression[1:])
|
integral = self.expression[1:]
|
||||||
|
for mob in frac, integral:
|
||||||
|
mob.add_to_back(BackgroundRectangle(mob))
|
||||||
|
self.add(mob)
|
||||||
|
cross = Cross(frac)
|
||||||
|
brace = Brace(integral, DOWN)
|
||||||
|
label = brace.get_text("The actual \\\\ Fourier transform")
|
||||||
|
label.add_background_rectangle()
|
||||||
|
label.shift_onto_screen()
|
||||||
|
rect = SurroundingRectangle(integral)
|
||||||
|
|
||||||
|
self.play(ShowCreation(cross))
|
||||||
|
self.wait()
|
||||||
|
self.play(ShowCreation(rect))
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(brace),
|
||||||
|
FadeIn(label)
|
||||||
|
)
|
||||||
|
self.wait(2)
|
||||||
|
|
||||||
|
self.integral = integral
|
||||||
|
self.frac = frac
|
||||||
|
self.frac_cross = cross
|
||||||
|
self.integral_rect = rect
|
||||||
|
self.integral_brace = brace
|
||||||
|
self.integral_label = label
|
||||||
|
|
||||||
def scale_up_center_of_mass(self):
|
def scale_up_center_of_mass(self):
|
||||||
pass
|
plane = self.circle_plane
|
||||||
|
origin = plane.coords_to_point(0, 0)
|
||||||
|
com_dot = self.center_of_mass_dot
|
||||||
|
com_vector = Arrow(
|
||||||
|
origin, com_dot.get_center(),
|
||||||
|
buff = 0
|
||||||
|
)
|
||||||
|
com_vector.match_style(com_dot)
|
||||||
|
vector_to_scale = com_vector.copy()
|
||||||
|
def get_com_vector_copies(n):
|
||||||
|
com_vector_copies = VGroup(*[
|
||||||
|
com_vector.copy().shift(x*com_vector.get_vector())
|
||||||
|
for x in range(1, n+1)
|
||||||
|
])
|
||||||
|
com_vector_copies.highlight(TEAL)
|
||||||
|
return com_vector_copies
|
||||||
|
com_vector_update = UpdateFromFunc(
|
||||||
|
com_vector,
|
||||||
|
lambda v : v.put_start_and_end_on(origin, com_dot.get_center())
|
||||||
|
)
|
||||||
|
|
||||||
|
circle = Circle(color = TEAL)
|
||||||
|
circle.surround(com_dot, buffer_factor = 1.2)
|
||||||
|
|
||||||
|
time_span = Rectangle(
|
||||||
|
stroke_width = 0,
|
||||||
|
fill_color = TEAL,
|
||||||
|
fill_opacity = 0.4
|
||||||
|
)
|
||||||
|
axes = self.time_axes
|
||||||
|
time_span.replace(
|
||||||
|
Line(axes.coords_to_point(0, 0), axes.coords_to_point(3, 1.5)),
|
||||||
|
stretch = True
|
||||||
|
)
|
||||||
|
time_span.save_state()
|
||||||
|
time_span.stretch(0, 0, about_edge = LEFT)
|
||||||
|
|
||||||
|
graph = self.graph
|
||||||
|
short_graph, long_graph = [
|
||||||
|
axes.get_graph(
|
||||||
|
graph.underlying_function, x_min = 0, x_max = t_max,
|
||||||
|
).match_style(graph)
|
||||||
|
for t_max in 3, 6
|
||||||
|
]
|
||||||
|
for g in short_graph, long_graph:
|
||||||
|
self.get_polarized_mobject(g, freq = self.initial_winding_frequency)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FocusOn(circle, run_time = 2),
|
||||||
|
Succession(
|
||||||
|
ShowCreation, circle,
|
||||||
|
FadeOut, circle,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
com_dot.fade, 0.5,
|
||||||
|
FadeIn(vector_to_scale)
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
self.play(vector_to_scale.scale, 4, {"about_point" : origin})
|
||||||
|
self.wait()
|
||||||
|
self.play(
|
||||||
|
FadeOut(vector_to_scale),
|
||||||
|
FadeIn(com_vector),
|
||||||
|
)
|
||||||
|
self.remove(graph.polarized_mobject)
|
||||||
|
self.play(
|
||||||
|
com_dot.move_to,
|
||||||
|
center_of_mass(short_graph.polarized_mobject.points),
|
||||||
|
com_vector_update,
|
||||||
|
time_span.restore,
|
||||||
|
ShowCreation(short_graph.polarized_mobject),
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
# dot = Dot(fill_opacity = 0.5).move_to(time_span)
|
||||||
|
# self.play(
|
||||||
|
# dot.move_to, com_vector,
|
||||||
|
# dot.set_fill, {"opacity" : 0},
|
||||||
|
# remover = True
|
||||||
|
# )
|
||||||
|
com_vector_copies = get_com_vector_copies(2)
|
||||||
|
self.play(*[
|
||||||
|
ReplacementTransform(
|
||||||
|
com_vector.copy(), cvc,
|
||||||
|
path_arc = -TAU/10
|
||||||
|
)
|
||||||
|
for cvc in com_vector_copies
|
||||||
|
])
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
#Squish_graph
|
||||||
|
to_squish = VGroup(
|
||||||
|
axes, graph,
|
||||||
|
time_span,
|
||||||
|
)
|
||||||
|
to_squish.generate_target()
|
||||||
|
squish_factor = 0.75
|
||||||
|
to_squish.target.stretch(squish_factor, 0, about_edge = LEFT)
|
||||||
|
pairs = zip(
|
||||||
|
to_squish.family_members_with_points(),
|
||||||
|
to_squish.target.family_members_with_points()
|
||||||
|
)
|
||||||
|
to_unsquish = list(axes.x_axis.numbers) + list(axes.labels)
|
||||||
|
for sm, tsm in pairs:
|
||||||
|
if sm in to_unsquish:
|
||||||
|
tsm.stretch(1/squish_factor, 0)
|
||||||
|
if sm is axes.background_rectangle:
|
||||||
|
tsm.stretch(1/squish_factor, 0, about_edge = LEFT)
|
||||||
|
|
||||||
|
long_graph.stretch(squish_factor, 0)
|
||||||
|
self.play(
|
||||||
|
MoveToTarget(to_squish),
|
||||||
|
FadeOut(com_vector_copies)
|
||||||
|
)
|
||||||
|
long_graph.move_to(graph, LEFT)
|
||||||
|
self.play(
|
||||||
|
com_dot.move_to,
|
||||||
|
center_of_mass(long_graph.polarized_mobject.points),
|
||||||
|
com_vector_update,
|
||||||
|
time_span.stretch, 2, 0, {"about_edge" : LEFT},
|
||||||
|
*[
|
||||||
|
ShowCreation(
|
||||||
|
mob,
|
||||||
|
rate_func = lambda a : interpolate(
|
||||||
|
0.5, 1, smooth(a)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for mob in long_graph, long_graph.polarized_mobject
|
||||||
|
],
|
||||||
|
run_time = 2
|
||||||
|
)
|
||||||
|
self.remove(graph, short_graph.polarized_mobject)
|
||||||
|
self.graph = long_graph
|
||||||
|
self.wait()
|
||||||
|
self.play(FocusOn(com_dot))
|
||||||
|
com_vector_copies = get_com_vector_copies(5)
|
||||||
|
self.play(*[
|
||||||
|
ReplacementTransform(
|
||||||
|
com_vector.copy(), cvc,
|
||||||
|
path_arc = -TAU/10
|
||||||
|
)
|
||||||
|
for cvc in com_vector_copies
|
||||||
|
])
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
# Scale graph out even longer
|
||||||
|
to_shift = VGroup(self.integral, self.integral_rect)
|
||||||
|
to_fade = VGroup(
|
||||||
|
self.integral_brace, self.integral_label,
|
||||||
|
self.frac, self.frac_cross
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
to_shift.shift, 2*DOWN,
|
||||||
|
FadeOut(to_fade),
|
||||||
|
axes.background_rectangle.stretch, 2, 0, {"about_edge" : LEFT},
|
||||||
|
Animation(axes),
|
||||||
|
Animation(self.graph),
|
||||||
|
FadeOut(com_vector_copies),
|
||||||
|
)
|
||||||
|
self.change_frequency(2.0, added_anims = [com_vector_update])
|
||||||
|
very_long_graph = axes.get_graph(
|
||||||
|
graph.underlying_function,
|
||||||
|
x_min = 0, x_max = 12,
|
||||||
|
)
|
||||||
|
very_long_graph.match_style(graph)
|
||||||
|
self.get_polarized_mobject(very_long_graph, freq = 2.0)
|
||||||
|
self.play(
|
||||||
|
com_dot.move_to,
|
||||||
|
center_of_mass(very_long_graph.polarized_mobject.points),
|
||||||
|
com_vector_update,
|
||||||
|
ShowCreation(
|
||||||
|
very_long_graph,
|
||||||
|
rate_func = lambda a : interpolate(0.5, 1, a)
|
||||||
|
),
|
||||||
|
ShowCreation(very_long_graph.polarized_mobject)
|
||||||
|
)
|
||||||
|
self.remove(graph, graph.polarized_mobject)
|
||||||
|
self.graph = very_long_graph
|
||||||
|
self.wait()
|
||||||
|
self.play(
|
||||||
|
com_vector.scale, 12, {"about_point" : origin},
|
||||||
|
run_time = 2
|
||||||
|
)
|
||||||
|
# com_vector_copies = get_com_vector_copies(11)
|
||||||
|
# self.play(ReplacementTransform(
|
||||||
|
# VGroup(com_vector.copy()),
|
||||||
|
# com_vector_copies,
|
||||||
|
# path_arc = TAU/10,
|
||||||
|
# run_time = 1.5,
|
||||||
|
# submobject_mode = "lagged_start"
|
||||||
|
# ))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
self.com_vector = com_vector
|
||||||
|
self.com_vector_update = com_vector_update
|
||||||
|
self.com_vector_copies = com_vector_copies
|
||||||
|
|
||||||
|
def comment_on_current_signal(self):
|
||||||
|
graph = self.graph
|
||||||
|
com_dot = self.center_of_mass_dot
|
||||||
|
com_vector = self.com_vector
|
||||||
|
com_vector_update = self.com_vector_update
|
||||||
|
axes = self.time_axes
|
||||||
|
origin = self.circle_plane.coords_to_point(0, 0)
|
||||||
|
wps_label = self.winding_freq_label
|
||||||
|
|
||||||
|
new_com_vector_update = UpdateFromFunc(
|
||||||
|
com_vector, lambda v : v.put_start_and_end_on(
|
||||||
|
origin, com_dot.get_center()
|
||||||
|
).scale(12, about_point = origin)
|
||||||
|
)
|
||||||
|
|
||||||
|
v_lines = self.get_v_lines_indicating_periods(
|
||||||
|
freq = 1.0, n_lines = 3
|
||||||
|
)[:2]
|
||||||
|
graph_portion = axes.get_graph(
|
||||||
|
graph.underlying_function, x_min = 1, x_max = 2
|
||||||
|
)
|
||||||
|
graph_portion.highlight(TEAL)
|
||||||
|
bps_label = TextMobject("2 beats per second")
|
||||||
|
bps_label.scale(0.75)
|
||||||
|
bps_label.next_to(graph_portion, UP, aligned_edge = LEFT)
|
||||||
|
bps_label.shift(SMALL_BUFF*RIGHT)
|
||||||
|
bps_label.add_background_rectangle()
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
ShowCreation(v_lines, submobject_mode = "all_at_once"),
|
||||||
|
ShowCreation(graph_portion),
|
||||||
|
FadeIn(bps_label),
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
self.play(ReplacementTransform(
|
||||||
|
bps_label[1][0].copy(), wps_label[1]
|
||||||
|
))
|
||||||
|
self.wait()
|
||||||
|
self.play(
|
||||||
|
com_vector.scale, 0.5, {"about_point" : origin},
|
||||||
|
rate_func = there_and_back,
|
||||||
|
run_time = 2
|
||||||
|
)
|
||||||
|
self.wait(2)
|
||||||
|
self.change_frequency(2.5,
|
||||||
|
added_anims = [new_com_vector_update],
|
||||||
|
run_time = 20,
|
||||||
|
rate_func = None,
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
class TakeAStepBack(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
self.student_says(
|
||||||
|
"Hang on, go over \\\\ that again?",
|
||||||
|
target_mode = "confused"
|
||||||
|
),
|
||||||
|
self.change_student_modes(*["confused"]*3)
|
||||||
|
self.play(self.teacher.change, "happy")
|
||||||
|
self.wait(3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def what_this_means_for_various_winding_frequencies(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class CloseWithAPuzzle(TeacherStudentsScene):
|
class CloseWithAPuzzle(TeacherStudentsScene):
|
||||||
|
|
Loading…
Add table
Reference in a new issue