mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Merge branch 'master' into basel
This commit is contained in:
commit
2c03f2fd6f
3 changed files with 93 additions and 11 deletions
|
@ -1,5 +1,5 @@
|
||||||
from helpers import *
|
from helpers import *
|
||||||
|
import scipy
|
||||||
|
|
||||||
from animation.animation import Animation
|
from animation.animation import Animation
|
||||||
from animation.transform import *
|
from animation.transform import *
|
||||||
|
@ -663,20 +663,24 @@ class FourierMachineScene(Scene):
|
||||||
"y_radius" : 2,
|
"y_radius" : 2,
|
||||||
},
|
},
|
||||||
"frequency_axes_config" : {
|
"frequency_axes_config" : {
|
||||||
|
"number_line_config" : {
|
||||||
|
"color" : TEAL,
|
||||||
|
},
|
||||||
"x_min" : 0,
|
"x_min" : 0,
|
||||||
"x_max" : 5.0,
|
"x_max" : 5.0,
|
||||||
"x_axis_config" : {
|
"x_axis_config" : {
|
||||||
"unit_size" : 1.5,
|
"unit_size" : 1.4,
|
||||||
},
|
},
|
||||||
"y_min" : -0.59,
|
"y_min" : -1.0,
|
||||||
"y_max" : 0.59,
|
"y_max" : 1.0,
|
||||||
"y_axis_config" : {
|
"y_axis_config" : {
|
||||||
"unit_size" : 3,
|
"unit_size" : 1.8,
|
||||||
"tick_frequency" : 0.1,
|
"tick_frequency" : 0.5,
|
||||||
"line_to_number_vect" : LEFT,
|
"line_to_number_vect" : LEFT,
|
||||||
},
|
},
|
||||||
|
"color" : TEAL,
|
||||||
},
|
},
|
||||||
"frequency_axes_box_color" : BLUE,
|
"frequency_axes_box_color" : TEAL_E,
|
||||||
"text_scale_val" : 0.75,
|
"text_scale_val" : 0.75,
|
||||||
"default_graph_config" : {
|
"default_graph_config" : {
|
||||||
"num_graph_points" : 100,
|
"num_graph_points" : 100,
|
||||||
|
@ -728,7 +732,7 @@ class FourierMachineScene(Scene):
|
||||||
frequency_axes = Axes(**self.frequency_axes_config)
|
frequency_axes = Axes(**self.frequency_axes_config)
|
||||||
frequency_axes.x_axis.add_numbers(*range(1, 6))
|
frequency_axes.x_axis.add_numbers(*range(1, 6))
|
||||||
frequency_axes.y_axis.add_numbers(
|
frequency_axes.y_axis.add_numbers(
|
||||||
*self.frequency_y_axis_numbers
|
*frequency_axes.y_axis.get_tick_numbers()
|
||||||
)
|
)
|
||||||
box = SurroundingRectangle(
|
box = SurroundingRectangle(
|
||||||
frequency_axes,
|
frequency_axes,
|
||||||
|
@ -739,6 +743,17 @@ class FourierMachineScene(Scene):
|
||||||
frequency_axes.add(box)
|
frequency_axes.add(box)
|
||||||
frequency_axes.to_corner(DOWN+RIGHT, buff = MED_SMALL_BUFF)
|
frequency_axes.to_corner(DOWN+RIGHT, buff = MED_SMALL_BUFF)
|
||||||
|
|
||||||
|
frequency_label = TextMobject("Frequency")
|
||||||
|
frequency_label.scale(self.text_scale_val)
|
||||||
|
frequency_label.next_to(
|
||||||
|
frequency_axes.x_axis.get_right(), DOWN,
|
||||||
|
buff = MED_LARGE_BUFF,
|
||||||
|
aligned_edge = RIGHT,
|
||||||
|
)
|
||||||
|
frequency_axes.label = frequency_label
|
||||||
|
frequency_axes.add(frequency_label)
|
||||||
|
|
||||||
|
self.frequency_axes = frequency_axes
|
||||||
return frequency_axes
|
return frequency_axes
|
||||||
|
|
||||||
def get_time_graph(self, func, **kwargs):
|
def get_time_graph(self, func, **kwargs):
|
||||||
|
@ -752,6 +767,35 @@ class FourierMachineScene(Scene):
|
||||||
def get_cosine_wave(self, freq = 1):
|
def get_cosine_wave(self, freq = 1):
|
||||||
return self.get_time_graph(lambda t : 1 + 0.5*np.cos(TAU*freq*t))
|
return self.get_time_graph(lambda t : 1 + 0.5*np.cos(TAU*freq*t))
|
||||||
|
|
||||||
|
def get_fourier_transform_graph(self, time_graph, **kwargs):
|
||||||
|
if not hasattr(self, "frequency_axes"):
|
||||||
|
self.get_frequency_axes()
|
||||||
|
func = time_graph.underlying_function
|
||||||
|
t_min = self.time_axes.x_min
|
||||||
|
t_max = self.time_axes.x_max
|
||||||
|
return self.frequency_axes.get_graph(
|
||||||
|
self.get_fourier_transform(func, t_min, t_max, **kwargs),
|
||||||
|
color = self.center_of_mass_color,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_fourier_transform(
|
||||||
|
self, func, t_min, t_max,
|
||||||
|
real_part = True,
|
||||||
|
use_almost_fourier = True,
|
||||||
|
):
|
||||||
|
part = "real" if real_part else "imag"
|
||||||
|
scalar = 1./(t_max - t_min) if use_almost_fourier else 1.0
|
||||||
|
def fourier_transform(f):
|
||||||
|
return scalar*scipy.integrate.quad(
|
||||||
|
lambda t : getattr(
|
||||||
|
func(t)*np.exp(complex(0, -TAU*f*t)),
|
||||||
|
part
|
||||||
|
),
|
||||||
|
t_min, t_max
|
||||||
|
)[0]
|
||||||
|
return fourier_transform
|
||||||
|
|
||||||
|
|
||||||
def get_polarized_mobject(self, mobject, freq = 1.0):
|
def get_polarized_mobject(self, mobject, freq = 1.0):
|
||||||
if not hasattr(self, "circle_plane"):
|
if not hasattr(self, "circle_plane"):
|
||||||
self.get_circle_plane()
|
self.get_circle_plane()
|
||||||
|
@ -879,6 +923,7 @@ class FourierMachineScene(Scene):
|
||||||
v_lines.set_stroke(LIGHT_GREY)
|
v_lines.set_stroke(LIGHT_GREY)
|
||||||
return v_lines
|
return v_lines
|
||||||
|
|
||||||
|
|
||||||
class WrapCosineGraphAroundCircle(FourierMachineScene):
|
class WrapCosineGraphAroundCircle(FourierMachineScene):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"initial_winding_frequency" : 0.5,
|
"initial_winding_frequency" : 0.5,
|
||||||
|
@ -1162,13 +1207,15 @@ class DrawFrequencyPlot(WrapCosineGraphAroundCircle, PiCreatureScene):
|
||||||
|
|
||||||
self.revert_to_original_skipping_status()
|
self.revert_to_original_skipping_status()
|
||||||
self.play(
|
self.play(
|
||||||
wps_label.move_to, self.circle_plane, UP,
|
wps_label.move_to, self.circle_plane.get_top(),
|
||||||
com_label.move_to, self.circle_plane, DOWN,
|
com_label.move_to, self.circle_plane, DOWN,
|
||||||
)
|
)
|
||||||
self.play(FadeIn(frequency_axes))
|
self.play(FadeIn(frequency_axes))
|
||||||
|
|
||||||
self.wait()
|
self.wait()
|
||||||
|
|
||||||
|
fourier_graph = self.get_fourier_transform_graph(self.graph)
|
||||||
|
print fourier_graph.underlying_function(0)
|
||||||
|
self.add(fourier_graph)
|
||||||
|
|
||||||
def draw_full_frequency_plot(self):
|
def draw_full_frequency_plot(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -260,6 +260,35 @@ class MaintainPositionRelativeTo(Animation):
|
||||||
self.diff
|
self.diff
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class WiggleOutThenIn(Animation):
|
||||||
|
CONFIG = {
|
||||||
|
"scale_value" : 1.1,
|
||||||
|
"rotation_angle" : 0.01*TAU,
|
||||||
|
"n_wiggles" : 6,
|
||||||
|
"run_time" : 2,
|
||||||
|
"scale_about_point" : None,
|
||||||
|
"rotate_about_point" : None,
|
||||||
|
}
|
||||||
|
def __init__(self, mobject, **kwargs):
|
||||||
|
digest_config(self, kwargs)
|
||||||
|
if self.scale_about_point is None:
|
||||||
|
self.scale_about_point = mobject.get_center()
|
||||||
|
if self.rotate_about_point is None:
|
||||||
|
self.rotate_about_point = mobject.get_center()
|
||||||
|
Animation.__init__(self, mobject, **kwargs)
|
||||||
|
|
||||||
|
def update_submobject(self, submobject, starting_sumobject, alpha):
|
||||||
|
submobject.points[:,:] = starting_sumobject.points
|
||||||
|
submobject.scale(
|
||||||
|
interpolate(1, self.scale_value, there_and_back(alpha)),
|
||||||
|
about_point = self.scale_about_point
|
||||||
|
)
|
||||||
|
submobject.rotate(
|
||||||
|
wiggle(alpha, self.n_wiggles)*self.rotation_angle,
|
||||||
|
about_point = self.rotate_about_point
|
||||||
|
)
|
||||||
|
|
||||||
### Animation modifiers ###
|
### Animation modifiers ###
|
||||||
|
|
||||||
class ApplyToCenters(Animation):
|
class ApplyToCenters(Animation):
|
||||||
|
|
|
@ -38,9 +38,15 @@ class NumberLine(VMobject):
|
||||||
self.main_line = Line(self.x_min*RIGHT, self.x_max*RIGHT)
|
self.main_line = Line(self.x_min*RIGHT, self.x_max*RIGHT)
|
||||||
self.tick_marks = VGroup()
|
self.tick_marks = VGroup()
|
||||||
self.add(self.main_line, self.tick_marks)
|
self.add(self.main_line, self.tick_marks)
|
||||||
|
rounding_value = int(-np.log10(0.1*self.tick_frequency))
|
||||||
|
rounded_numbers_with_elongated_ticks = np.round(
|
||||||
|
self.numbers_with_elongated_ticks,
|
||||||
|
rounding_value
|
||||||
|
)
|
||||||
|
|
||||||
for x in self.get_tick_numbers():
|
for x in self.get_tick_numbers():
|
||||||
if x in self.numbers_with_elongated_ticks:
|
rounded_x = np.round(x, rounding_value)
|
||||||
|
if rounded_x in rounded_numbers_with_elongated_ticks:
|
||||||
tick_size_used = self.longer_tick_multiple*self.tick_size
|
tick_size_used = self.longer_tick_multiple*self.tick_size
|
||||||
else:
|
else:
|
||||||
tick_size_used = self.tick_size
|
tick_size_used = self.tick_size
|
||||||
|
|
Loading…
Add table
Reference in a new issue