Finished ShowVectorEquation of waves.py

This commit is contained in:
Grant Sanderson
2017-09-01 10:41:27 -07:00
parent 41e715718b
commit 43c07680cb
3 changed files with 261 additions and 141 deletions

157
bell.py
View File

@ -34,131 +34,7 @@ from waves import *
#force_skipping
#revert_to_original_skipping_status
class FilterScene(ThreeDScene):
CONFIG = {
"filter_x_coordinates" : [0],
"pol_filter_configs" : [{}],
"EMWave_config" : {
"start_point" : SPACE_WIDTH*LEFT + DOWN+OUT
},
"start_phi" : 0.8*np.pi/2,
"start_theta" : -0.6*np.pi,
"ambient_rotation_rate" : 0.01,
}
def setup(self):
self.axes = ThreeDAxes()
self.add(self.axes)
for x in range(len(self.filter_x_coordinates) - len(self.pol_filter_configs)):
self.pol_filter_configs.append({})
self.pol_filters = VGroup(*[
PolarizingFilter(**config)
for config in self.pol_filter_configs
])
self.pol_filters.rotate(np.pi/2, RIGHT)
self.pol_filters.rotate(-np.pi/2, OUT)
self.pol_filters.shift(DOWN+OUT)
for x, pf in zip(self.filter_x_coordinates, self.pol_filters):
pf.shift(x*RIGHT)
self.add(self.pol_filters)
self.pol_filter = self.pol_filters[0]
self.set_camera_position(self.start_phi, self.start_theta)
if self.ambient_rotation_rate > 0:
self.begin_ambient_camera_rotation(self.ambient_rotation_rate)
def get_filter_absorbtion_animation(self, pol_filter, photon):
x = pol_filter.get_center()[0]
alpha = (x + SPACE_WIDTH) / (2*SPACE_WIDTH)
return ApplyMethod(
pol_filter.set_fill, RED,
run_time = photon.run_time,
rate_func = squish_rate_func(there_and_back, alpha - 0.1, alpha + 0.1)
)
class DirectionOfPolarization(FilterScene):
CONFIG = {
"pol_filter_configs" : [{
"include_arrow_label" : False,
}],
"target_theta" : -0.97*np.pi,
"target_phi" : 0.9*np.pi/2,
"ambient_rotation_rate" : 0.005,
"apply_filter" : False,
}
def setup(self):
self.reference_line = Line(ORIGIN, RIGHT)
self.reference_line.set_stroke(width = 0)
self.em_wave = EMWave(**self.EMWave_config)
self.add(self.em_wave)
FilterScene.setup(self)
def construct(self):
self.remove(self.pol_filter)
words = TextMobject("Polarization direction")
words.next_to(ORIGIN, UP+RIGHT, LARGE_BUFF)
words.shift(2*UP)
words.rotate(np.pi/2, RIGHT)
words.rotate(-np.pi/2, OUT)
em_wave = self.em_wave
self.add(em_wave)
self.dither(2)
self.move_camera(
phi = self.target_phi,
theta = self.target_theta
)
self.play(Write(words, run_time = 1))
self.change_polarization_direction(
2*np.pi/3,
run_time = 6,
rate_func = there_and_back
)
self.dither(2)
def change_polarization_direction(self, angle, **kwargs):
added_anims = kwargs.get("added_anims", [])
self.play(
ApplyMethod(
self.reference_line.rotate, angle,
**kwargs
),
*added_anims
)
def continual_update(self):
reference_angle = self.reference_line.get_angle()
self.em_wave.rotation = reference_angle
FilterScene.continual_update(self)
vect_groups = [self.em_wave.E_vects, self.em_wave.M_vects]
if self.apply_filter:
filters = sorted(
self.pol_filters,
lambda pf1, pf2 : cmp(
pf1.get_center()[0],
pf2.get_center()[0],
)
)
for pol_filter in filters:
filter_x = pol_filter.get_center()[0]
for vect_group, angle in zip(vect_groups, [0, -np.pi/2]):
proj_vect = rotate_vector(
OUT, pol_filter.filter_angle + angle, RIGHT,
)
proj_matrix = np.array([RIGHT] + [
proj_vect*np.dot(proj_vect, basis)
for basis in UP, OUT
]).T
for vect in vect_group:
start, end = vect.get_start_and_end()
if start[0] > filter_x:
vect.apply_matrix(proj_matrix)
vect.shift(start - vect.get_start())
vect.set_tip_points(vect.tip)
vect.set_rectangular_stem_points()
class PhotonPassesCompletelyOrNotAtAll(DirectionOfPolarization):
class PhotonPassesCompletelyOrNotAtAll(DirectionOfPolarizationScene):
CONFIG = {
"pol_filter_configs" : [{
"include_arrow_label" : False,
@ -236,6 +112,31 @@ class PhotonPassesCompletelyOrNotAtAll(DirectionOfPolarization):
)
self.dither()
class DirectionOfPolarization(DirectionOfPolarizationScene):
def construct(self):
self.remove(self.pol_filter)
words = TextMobject("Polarization direction")
words.next_to(ORIGIN, UP+RIGHT, LARGE_BUFF)
words.shift(2*UP)
words.rotate(np.pi/2, RIGHT)
words.rotate(-np.pi/2, OUT)
em_wave = self.em_wave
self.add(em_wave)
self.dither(2)
self.move_camera(
phi = self.target_phi,
theta = self.target_theta
)
self.play(Write(words, run_time = 1))
self.change_polarization_direction(
2*np.pi/3,
run_time = 6,
rate_func = there_and_back
)
self.dither(2)
class PhotonsThroughPerpendicularFilters(PhotonPassesCompletelyOrNotAtAll):
CONFIG = {
"filter_x_coordinates" : [-2, 2],
@ -515,7 +416,7 @@ class SecondVideoWrapper(Scene):
self.play(ShowCreation(screen_rect))
self.dither(3)
class BasicsOfPolarization(DirectionOfPolarization):
class BasicsOfPolarization(DirectionOfPolarizationScene):
CONFIG = {
"apply_filter" : True,
}
@ -648,8 +549,8 @@ class BasicsOfPolarization(DirectionOfPolarization):
for index in 1, 0, 0, 1:
self.play(*anim_sets[index])
def continual_update(self):
DirectionOfPolarization.continual_update(self)
def continual_update(self, *args, **kwargs):
DirectionOfPolarization.continual_update(self, *args, **kwargs)
if self.rectangles not in self.mobjects:
return

View File

@ -164,8 +164,8 @@ class Axes(VGroup):
self.add(self.x_axis, self.y_axis)
if self.three_d:
self.z_axis = NumberLine(
x_min = self.min,
x_max = self.max,
x_min = self.z_min,
x_max = self.z_max,
**self.number_line_config
)
self.z_axis.rotate(-np.pi/2, UP)
@ -177,7 +177,7 @@ class ThreeDAxes(Axes):
"x_min" : -5.5,
"x_max" : 5.5,
"y_min" : -4.5,
"y_max" : -4.5,
"y_max" : 4.5,
"three_d" : True,
}

239
waves.py
View File

@ -296,6 +296,110 @@ class PolarizingFilter(Circle):
################
class FilterScene(ThreeDScene):
CONFIG = {
"filter_x_coordinates" : [0],
"pol_filter_configs" : [{}],
"EMWave_config" : {
"start_point" : SPACE_WIDTH*LEFT + DOWN+OUT
},
"start_phi" : 0.8*np.pi/2,
"start_theta" : -0.6*np.pi,
"ambient_rotation_rate" : 0.01,
}
def setup(self):
self.axes = ThreeDAxes()
self.add(self.axes)
for x in range(len(self.filter_x_coordinates) - len(self.pol_filter_configs)):
self.pol_filter_configs.append({})
self.pol_filters = VGroup(*[
PolarizingFilter(**config)
for config in self.pol_filter_configs
])
self.pol_filters.rotate(np.pi/2, RIGHT)
self.pol_filters.rotate(-np.pi/2, OUT)
self.pol_filters.shift(DOWN+OUT)
for x, pf in zip(self.filter_x_coordinates, self.pol_filters):
pf.shift(x*RIGHT)
self.add(self.pol_filters)
self.pol_filter = self.pol_filters[0]
self.set_camera_position(self.start_phi, self.start_theta)
if self.ambient_rotation_rate > 0:
self.begin_ambient_camera_rotation(self.ambient_rotation_rate)
def get_filter_absorbtion_animation(self, pol_filter, photon):
x = pol_filter.get_center()[0]
alpha = (x + SPACE_WIDTH) / (2*SPACE_WIDTH)
return ApplyMethod(
pol_filter.set_fill, RED,
run_time = photon.run_time,
rate_func = squish_rate_func(there_and_back, alpha - 0.1, alpha + 0.1)
)
class DirectionOfPolarizationScene(FilterScene):
CONFIG = {
"pol_filter_configs" : [{
"include_arrow_label" : False,
}],
"target_theta" : -0.97*np.pi,
"target_phi" : 0.9*np.pi/2,
"ambient_rotation_rate" : 0.005,
"apply_filter" : False,
}
def setup(self):
self.reference_line = Line(ORIGIN, RIGHT)
self.reference_line.set_stroke(width = 0)
self.em_wave = EMWave(**self.EMWave_config)
self.add(self.em_wave)
FilterScene.setup(self)
def change_polarization_direction(self, angle, **kwargs):
added_anims = kwargs.get("added_anims", [])
self.play(
ApplyMethod(
self.reference_line.rotate, angle,
**kwargs
),
*added_anims
)
def continual_update(self, *args, **kwargs):
reference_angle = self.reference_line.get_angle()
self.em_wave.rotation = reference_angle
FilterScene.continual_update(self, *args, **kwargs)
vect_groups = [self.em_wave.E_vects, self.em_wave.M_vects]
if self.apply_filter:
filters = sorted(
self.pol_filters,
lambda pf1, pf2 : cmp(
pf1.get_center()[0],
pf2.get_center()[0],
)
)
for pol_filter in filters:
filter_x = pol_filter.get_center()[0]
for vect_group, angle in zip(vect_groups, [0, -np.pi/2]):
proj_vect = rotate_vector(
OUT, pol_filter.filter_angle + angle, RIGHT,
)
proj_matrix = np.array([RIGHT] + [
proj_vect*np.dot(proj_vect, basis)
for basis in UP, OUT
]).T
for vect in vect_group:
start, end = vect.get_start_and_end()
if start[0] > filter_x:
vect.apply_matrix(proj_matrix)
vect.shift(start - vect.get_start())
vect.set_tip_points(vect.tip)
vect.set_rectangular_stem_points()
################
class IntroduceElectricField(PiCreatureScene):
CONFIG = {
"vector_field_colors" : [BLUE_B, BLUE_D],
@ -412,8 +516,8 @@ class IntroduceElectricField(PiCreatureScene):
###
def continual_update(self):
Scene.continual_update(self)
def continual_update(self, *args, **kwargs):
Scene.continual_update(self, *args, **kwargs)
if hasattr(self, "moving_particles"):
dt = self.frame_duration
for p in self.moving_particles:
@ -574,8 +678,8 @@ class IntroduceMagneticField(IntroduceElectricField, ThreeDScene):
###
def continual_update(self):
Scene.continual_update(self)
def continual_update(self, *args, **kwargs):
Scene.continual_update(self, *args, **kwargs)
if hasattr(self, "moving_particles"):
dt = self.frame_duration
for p in self.moving_particles:
@ -854,8 +958,6 @@ class ShowVectorEquation(Scene):
"A_color" : GREEN,
}
def construct(self):
self.force_skipping()
self.add_vector()
self.add_plane()
self.write_horizontally_polarized()
@ -894,7 +996,10 @@ class ShowVectorEquation(Scene):
self.dither(2)
def write_horizontally_polarized(self):
words = TextMobject("``Horizontally polarized''")
words = TextMobject(
"``", "Horizontally", " polarized", "''",
arg_separator = ""
)
words.next_to(ORIGIN, LEFT)
words.to_edge(UP)
words.add_background_rectangle()
@ -907,7 +1012,7 @@ class ShowVectorEquation(Scene):
def write_components(self):
x, y = components = VGroup(
TexMobject("\\cos(", "2\\pi", "f_x", "t", "+ ", "\\phi_x", ")"),
TexMobject("0")
TexMobject("0", "")
)
components.arrange_submobjects(DOWN)
lb, rb = brackets = TexMobject("[]")
@ -1131,7 +1236,6 @@ class ShowVectorEquation(Scene):
self.oscillating_vector.A_vect[0] = h_brace.get_width()
return vect
self.revert_to_original_skipping_status()
self.play(
GrowFromCenter(h_brace),
GrowFromCenter(v_brace),
@ -1142,6 +1246,8 @@ class ShowVectorEquation(Scene):
corner_cos.next_to, corner_A, RIGHT, SMALL_BUFF,
FadeIn(all_As)
)
x.add(A)
corner_cos.add(corner_A)
self.dither()
factor = 0.5
self.play(
@ -1156,11 +1262,122 @@ class ShowVectorEquation(Scene):
)
self.dither(4)
self.h_brace = h_brace
self.v_brace = v_brace
def add_kets(self):
pass
x, y = self.components
E_equals = self.E_equals
for mob in x, y, E_equals:
mob.add_background_rectangle()
mob.generate_target()
right_ket = TexMobject("|\\rightarrow\\rangle")
up_ket = TexMobject("|\\uparrow\\rangle")
kets = VGroup(right_ket, up_ket)
kets.highlight(YELLOW)
for ket in kets:
ket.add_background_rectangle()
plus = TextMobject("+")
group = VGroup(
E_equals.target,
x.target, right_ket, plus,
y.target, up_ket,
)
group.arrange_submobjects(RIGHT)
E_equals.target.shift(SMALL_BUFF*UP)
group.scale(0.8)
group.move_to(self.brackets, DOWN)
group.to_edge(LEFT, buff = MED_SMALL_BUFF)
kets_word = TextMobject("``kets''")
kets_word.next_to(kets, DOWN, buff = 0.8)
arrows = VGroup(*[
Arrow(kets_word.get_top(), ket, color = ket.get_color())
for ket in kets
])
ket_rects = VGroup(*map(SurroundingRectangle, kets))
ket_rects.highlight(WHITE)
unit_vectors = VGroup(*[Vector(2*vect) for vect in RIGHT, UP])
unit_vectors.set_fill(YELLOW)
self.play(
FadeOut(self.brackets),
*map(MoveToTarget, [E_equals, x, y])
)
self.play(*map(Write, [right_ket, plus, up_ket]), run_time = 1)
self.play(
Write(kets_word),
LaggedStart(ShowCreation, arrows, lag_ratio = 0.7),
run_time = 2,
)
self.dither()
for ket, ket_rect, unit_vect in zip(kets, ket_rects, unit_vectors):
self.play(ShowCreation(ket_rect))
self.play(FadeOut(ket_rect))
self.play(ReplacementTransform(ket[1][1].copy(), unit_vect))
self.dither()
self.play(FadeOut(unit_vectors))
self.play(*map(FadeOut, [kets_word, arrows]))
self.kets = kets
self.plus = plus
def switch_to_vertically_polarized_light(self):
x, y = self.components
x_ket, y_ket = self.kets
plus = self.plus
x.target = TexMobject("0", "").add_background_rectangle()
y.target = TexMobject(
"A_y", "\\cos(", "2\\pi", "f_y", "t", "+", "\\phi_y", ")"
)
y.target.highlight_by_tex_to_color_map({
"A" : self.A_color,
"f" : self.f_color,
"phi" : self.phi_color,
})
y.target.add_background_rectangle()
VGroup(x.target, y.target).scale(0.8)
for mob in [plus] + list(self.kets):
mob.generate_target()
movers = x, x_ket, plus, y, y_ket
group = VGroup(*[m.target for m in movers])
group.arrange_submobjects(RIGHT)
group.move_to(x, LEFT)
vector_A_vect = np.array(self.oscillating_vector.A_vect)
def update_vect(vect, alpha):
self.oscillating_vector.A_vect = rotate_vector(
vector_A_vect, alpha*np.pi/2
)
return vect
new_h_brace = Brace(Line(ORIGIN, UP), RIGHT)
words = TextMobject(
"``", "Vertically", " polarized", "''",
arg_separator = "",
)
words.add_background_rectangle()
words.move_to(self.horizontally_polarized_words)
self.play(
UpdateFromAlphaFunc(self.vector, update_vect),
Transform(self.h_brace, new_h_brace),
self.h_brace.A.next_to, new_h_brace, RIGHT, SMALL_BUFF,
Transform(self.horizontally_polarized_words, words),
*map(FadeOut, [
self.corner_group, self.v_brace,
self.v_brace.A, self.low_f_graph,
])
)
self.play(*map(MoveToTarget, movers))
self.dither(5)
class ChangeFromHorizontalToVerticallyPolarized(Scene):
def construct(self):
pass
@ -1183,6 +1400,8 @@ class ShowVectorEquation(Scene):