2017-08-24 11:44:06 -07:00
|
|
|
from helpers import *
|
|
|
|
|
|
|
|
from mobject.tex_mobject import TexMobject
|
|
|
|
from mobject import Mobject
|
|
|
|
from mobject.image_mobject import ImageMobject
|
|
|
|
from mobject.vectorized_mobject import *
|
|
|
|
|
|
|
|
from animation.animation import Animation
|
|
|
|
from animation.transform import *
|
|
|
|
from animation.simple_animations import *
|
2017-08-24 23:12:25 -07:00
|
|
|
from animation.continual_animation import *
|
2017-08-24 11:44:06 -07:00
|
|
|
from animation.playground import *
|
|
|
|
from topics.geometry import *
|
|
|
|
from topics.characters import *
|
|
|
|
from topics.functions import *
|
|
|
|
from topics.fractals import *
|
|
|
|
from topics.number_line import *
|
|
|
|
from topics.combinatorics import *
|
|
|
|
from topics.numerals import *
|
|
|
|
from topics.three_dimensions import *
|
|
|
|
from topics.objects import *
|
|
|
|
from topics.probability import *
|
|
|
|
from topics.complex_numbers import *
|
|
|
|
from scene import Scene
|
|
|
|
from scene.reconfigurable_scene import ReconfigurableScene
|
|
|
|
from scene.zoomed_scene import *
|
|
|
|
from camera import Camera
|
|
|
|
from mobject.svg_mobject import *
|
|
|
|
from mobject.tex_mobject import *
|
|
|
|
|
|
|
|
E_COLOR = BLUE
|
2017-08-25 17:56:55 -07:00
|
|
|
M_COLOR = YELLOW
|
2017-08-24 11:44:06 -07:00
|
|
|
|
|
|
|
class OscillatingVector(ContinualAnimation):
|
|
|
|
CONFIG = {
|
|
|
|
"tail" : ORIGIN,
|
|
|
|
"frequency" : 1,
|
2017-08-27 23:52:28 -07:00
|
|
|
"A_vect" : [1, 0, 0],
|
|
|
|
"phi_vect" : [0, 0, 0],
|
2017-08-24 23:12:25 -07:00
|
|
|
"vector_to_be_added_to" : None,
|
2017-08-24 11:44:06 -07:00
|
|
|
}
|
|
|
|
def setup(self):
|
|
|
|
self.vector = self.mobject
|
|
|
|
|
|
|
|
def update_mobject(self, dt):
|
|
|
|
f = self.frequency
|
2017-08-24 12:38:37 -07:00
|
|
|
t = self.internal_time
|
2017-08-24 11:44:06 -07:00
|
|
|
angle = 2*np.pi*f*t
|
|
|
|
vect = np.array([
|
2017-08-27 23:52:28 -07:00
|
|
|
A*np.exp(complex(0, angle + phi))
|
|
|
|
for A, phi in zip(self.A_vect, self.phi_vect)
|
2017-08-24 11:44:06 -07:00
|
|
|
]).real
|
2017-08-24 23:12:25 -07:00
|
|
|
self.update_tail()
|
2017-08-24 11:44:06 -07:00
|
|
|
self.vector.put_start_and_end_on(self.tail, self.tail+vect)
|
|
|
|
|
2017-08-24 23:12:25 -07:00
|
|
|
def update_tail(self):
|
|
|
|
if self.vector_to_be_added_to is not None:
|
|
|
|
self.tail = self.vector_to_be_added_to.get_end()
|
|
|
|
|
|
|
|
class OscillatingVectorComponents(ContinualAnimationGroup):
|
|
|
|
CONFIG = {
|
|
|
|
"tip_to_tail" : False,
|
|
|
|
}
|
|
|
|
def __init__(self, oscillating_vector, **kwargs):
|
|
|
|
digest_config(self, kwargs)
|
|
|
|
vx = Vector(UP, color = GREEN).fade()
|
|
|
|
vy = Vector(UP, color = RED).fade()
|
|
|
|
kwargs = {
|
|
|
|
"frequency" : oscillating_vector.frequency,
|
|
|
|
"tail" : oscillating_vector.tail,
|
|
|
|
}
|
|
|
|
ovx = OscillatingVector(
|
|
|
|
vx,
|
|
|
|
A_x = oscillating_vector.A_x,
|
|
|
|
phi_x = oscillating_vector.phi_x,
|
|
|
|
A_y = 0,
|
|
|
|
phi_y = 0,
|
|
|
|
**kwargs
|
|
|
|
)
|
|
|
|
ovy = OscillatingVector(
|
|
|
|
vy,
|
|
|
|
A_x = 0,
|
|
|
|
phi_x = 0,
|
|
|
|
A_y = oscillating_vector.A_y,
|
|
|
|
phi_y = oscillating_vector.phi_y,
|
|
|
|
**kwargs
|
|
|
|
)
|
|
|
|
components = [ovx, ovy]
|
|
|
|
self.vectors = VGroup(ovx.vector, ovy.vector)
|
|
|
|
if self.tip_to_tail:
|
|
|
|
ovy.vector_to_be_added_to = ovx.vector
|
|
|
|
else:
|
|
|
|
self.lines = VGroup()
|
|
|
|
for ov1, ov2 in (ovx, ovy), (ovy, ovx):
|
|
|
|
ov_line = ov1.copy()
|
|
|
|
ov_line.mobject = ov_line.vector = DashedLine(
|
|
|
|
UP, DOWN, color = ov1.vector.get_color()
|
|
|
|
)
|
|
|
|
ov_line.vector_to_be_added_to = ov2.vector
|
|
|
|
components.append(ov_line)
|
|
|
|
self.lines.add(ov_line.line)
|
|
|
|
|
|
|
|
ContinualAnimationGroup.__init__(self, *components, **kwargs)
|
|
|
|
|
|
|
|
class EMWave(ContinualAnimationGroup):
|
|
|
|
CONFIG = {
|
2017-08-25 17:56:55 -07:00
|
|
|
"wave_number" : 1,
|
2017-08-24 23:12:25 -07:00
|
|
|
"frequency" : 0.25,
|
|
|
|
"n_vectors" : 40,
|
|
|
|
"propogation_direction" : RIGHT,
|
|
|
|
"start_point" : SPACE_WIDTH*LEFT,
|
|
|
|
"length" : 2*SPACE_WIDTH,
|
|
|
|
"amplitude" : 1,
|
|
|
|
"rotation" : 0,
|
2017-08-27 23:52:28 -07:00
|
|
|
"A_vect" : [0, 0, 1],
|
|
|
|
"phi_vect" : [0, 0, 0],
|
2017-08-24 23:12:25 -07:00
|
|
|
}
|
|
|
|
def __init__(self, **kwargs):
|
|
|
|
digest_config(self, kwargs)
|
2017-08-27 23:52:28 -07:00
|
|
|
self.matrix_transform = np.dot(
|
|
|
|
z_to_vector(self.propogation_direction),
|
|
|
|
np.linalg.inv(z_to_vector(RIGHT)),
|
|
|
|
)
|
2017-08-24 23:12:25 -07:00
|
|
|
|
|
|
|
vector_oscillations = []
|
|
|
|
self.E_vects = VGroup()
|
|
|
|
self.M_vects = VGroup()
|
|
|
|
|
2017-08-27 23:52:28 -07:00
|
|
|
self.A_vect = np.array(self.A_vect)/np.linalg.norm(self.A_vect)
|
|
|
|
self.A_vect *= self.amplitude
|
2017-08-24 23:12:25 -07:00
|
|
|
|
|
|
|
for alpha in np.linspace(0, 1, self.n_vectors):
|
2017-08-27 23:52:28 -07:00
|
|
|
tail = interpolate(ORIGIN, self.length*RIGHT, alpha)
|
2017-08-25 17:56:55 -07:00
|
|
|
phase = -alpha*self.length*self.wave_number
|
2017-08-27 23:52:28 -07:00
|
|
|
kwargs = {
|
|
|
|
"phi_vect" : np.array(self.phi_vect) + phase,
|
|
|
|
"frequency" : self.frequency,
|
|
|
|
"tail" : np.array(tail),
|
|
|
|
}
|
2017-08-24 23:12:25 -07:00
|
|
|
E_ov = OscillatingVector(
|
2017-08-27 23:52:28 -07:00
|
|
|
Vector(
|
|
|
|
OUT, color = E_COLOR,
|
|
|
|
normal_vector = UP,
|
|
|
|
),
|
|
|
|
A_vect = self.A_vect,
|
|
|
|
**kwargs
|
2017-08-24 23:12:25 -07:00
|
|
|
)
|
|
|
|
M_ov = OscillatingVector(
|
2017-08-27 23:52:28 -07:00
|
|
|
Vector(
|
|
|
|
UP, color = M_COLOR,
|
|
|
|
normal_vector = OUT,
|
|
|
|
),
|
|
|
|
A_vect = rotate_vector(self.A_vect, np.pi/2, RIGHT),
|
|
|
|
**kwargs
|
2017-08-24 23:12:25 -07:00
|
|
|
)
|
|
|
|
vector_oscillations += [E_ov, M_ov]
|
|
|
|
self.E_vects.add(E_ov.vector)
|
|
|
|
self.M_vects.add(M_ov.vector)
|
|
|
|
ContinualAnimationGroup.__init__(self, *vector_oscillations)
|
|
|
|
|
|
|
|
def update_mobject(self, dt):
|
|
|
|
ContinualAnimationGroup.update_mobject(self, dt)
|
2017-08-27 23:52:28 -07:00
|
|
|
self.mobject.rotate(self.rotation, RIGHT)
|
2017-08-24 23:12:25 -07:00
|
|
|
self.mobject.apply_matrix(self.matrix_transform)
|
|
|
|
self.mobject.shift(self.start_point)
|
|
|
|
|
|
|
|
class WavePacket(Animation):
|
|
|
|
CONFIG = {
|
|
|
|
"EMWave_config" : {
|
|
|
|
"wave_number" : 0,
|
|
|
|
"start_point" : SPACE_WIDTH*LEFT,
|
2017-08-27 23:52:28 -07:00
|
|
|
"phi_vect" : np.ones(3)*np.pi/4,
|
2017-08-24 23:12:25 -07:00
|
|
|
},
|
2017-08-25 17:56:55 -07:00
|
|
|
"em_wave" : None,
|
2017-08-24 23:12:25 -07:00
|
|
|
"run_time" : 4,
|
|
|
|
"rate_func" : None,
|
|
|
|
"packet_width" : 6,
|
|
|
|
"include_E_vects" : True,
|
|
|
|
"include_M_vects" : True,
|
|
|
|
"filter_distance" : SPACE_WIDTH,
|
|
|
|
"get_filtered" : False,
|
2017-08-25 17:56:55 -07:00
|
|
|
"remover" : True,
|
2017-08-24 23:12:25 -07:00
|
|
|
}
|
|
|
|
def __init__(self, **kwargs):
|
|
|
|
digest_config(self, kwargs)
|
2017-08-25 17:56:55 -07:00
|
|
|
em_wave = self.em_wave
|
|
|
|
if em_wave is None:
|
|
|
|
em_wave = EMWave(**self.EMWave_config)
|
|
|
|
em_wave.update(0)
|
|
|
|
self.em_wave = em_wave
|
2017-08-24 23:12:25 -07:00
|
|
|
|
|
|
|
self.vects = VGroup()
|
|
|
|
if self.include_E_vects:
|
|
|
|
self.vects.add(*em_wave.E_vects)
|
|
|
|
if self.include_M_vects:
|
|
|
|
self.vects.add(*em_wave.M_vects)
|
|
|
|
for vect in self.vects:
|
|
|
|
vect.save_state()
|
|
|
|
|
|
|
|
u = em_wave.propogation_direction
|
|
|
|
self.wave_packet_start, self.wave_packet_end = [
|
|
|
|
em_wave.start_point - u*self.packet_width/2,
|
|
|
|
em_wave.start_point + u*(em_wave.length + self.packet_width/2)
|
|
|
|
]
|
|
|
|
Animation.__init__(self, self.vects, **kwargs)
|
|
|
|
|
|
|
|
def update_mobject(self, alpha):
|
|
|
|
packet_center = interpolate(
|
|
|
|
self.wave_packet_start,
|
|
|
|
self.wave_packet_end,
|
|
|
|
alpha
|
|
|
|
)
|
|
|
|
em_wave = self.em_wave
|
|
|
|
for vect in self.vects:
|
|
|
|
tail = vect.get_start()
|
|
|
|
distance_from_packet = np.dot(
|
|
|
|
tail - packet_center,
|
|
|
|
em_wave.propogation_direction
|
|
|
|
)
|
2017-08-25 17:56:55 -07:00
|
|
|
A = em_wave.amplitude*self.E_func(distance_from_packet)
|
2017-08-24 23:12:25 -07:00
|
|
|
distance_from_start = np.linalg.norm(tail - em_wave.start_point)
|
|
|
|
if self.get_filtered and distance_from_start > self.filter_distance:
|
|
|
|
A = 0
|
|
|
|
vect.restore()
|
|
|
|
vect.scale(A/vect.get_length(), about_point = tail)
|
|
|
|
|
2017-08-25 17:56:55 -07:00
|
|
|
def E_func(self, x):
|
2017-08-27 23:52:28 -07:00
|
|
|
return np.sin(x)*np.exp(-0.25*x*x)
|
2017-08-24 23:12:25 -07:00
|
|
|
|
|
|
|
class FilterLabel(TexMobject):
|
|
|
|
def __init__(self, tex, degrees, **kwargs):
|
|
|
|
TexMobject.__init__(self, tex + " \\uparrow", **kwargs)
|
|
|
|
self[-1].rotate(-degrees * np.pi / 180)
|
|
|
|
|
|
|
|
class PolarizingFilter(Circle):
|
|
|
|
CONFIG = {
|
|
|
|
"stroke_color" : DARK_GREY,
|
|
|
|
"fill_color" : LIGHT_GREY,
|
|
|
|
"fill_opacity" : 0.5,
|
|
|
|
"label_tex" : None,
|
|
|
|
"filter_angle" : 0,
|
2017-08-25 17:56:55 -07:00
|
|
|
"include_arrow_label" : True,
|
2017-08-24 23:12:25 -07:00
|
|
|
}
|
|
|
|
def __init__(self, **kwargs):
|
|
|
|
Circle.__init__(self, **kwargs)
|
|
|
|
|
|
|
|
if self.label_tex:
|
|
|
|
self.label = TexMobject(self.label_tex)
|
|
|
|
self.label.next_to(self.get_top(), DOWN, SMALL_BUFF)
|
|
|
|
self.add(self.label)
|
|
|
|
|
2017-08-25 17:56:55 -07:00
|
|
|
arrow = Arrow(
|
|
|
|
ORIGIN, 0.7*UP,
|
|
|
|
color = WHITE,
|
|
|
|
buff = 0,
|
|
|
|
)
|
2017-08-24 23:12:25 -07:00
|
|
|
arrow.shift(self.get_top())
|
|
|
|
arrow.rotate(-self.filter_angle)
|
|
|
|
self.add(arrow)
|
|
|
|
self.arrow = arrow
|
2017-08-25 17:56:55 -07:00
|
|
|
shade_in_3d(self)
|
2017-08-24 23:12:25 -07:00
|
|
|
|
2017-08-25 17:56:55 -07:00
|
|
|
if self.include_arrow_label:
|
|
|
|
arrow_label = TexMobject(
|
|
|
|
"%.1f^\\circ"%(self.filter_angle*180/np.pi)
|
|
|
|
)
|
|
|
|
arrow_label.add_background_rectangle()
|
|
|
|
arrow_label.next_to(arrow.get_tip(), UP)
|
|
|
|
self.add(arrow_label)
|
|
|
|
self.arrow_label = arrow_label
|
2017-08-24 11:44:06 -07:00
|
|
|
|
|
|
|
class EMScene(Scene):
|
|
|
|
def construct(self):
|
|
|
|
pass
|
|
|
|
|
2017-08-27 23:52:28 -07:00
|
|
|
class Test(ThreeDScene):
|
2017-08-24 11:44:06 -07:00
|
|
|
def construct(self):
|
2017-08-24 23:12:25 -07:00
|
|
|
self.add(ThreeDAxes())
|
|
|
|
|
|
|
|
self.set_camera_position(0.8*np.pi/2, -0.6*np.pi)
|
|
|
|
self.begin_ambient_camera_rotation(rate = 0.01)
|
2017-08-27 23:52:28 -07:00
|
|
|
self.add(EMWave(A_vect = [0, 1, 1]))
|
|
|
|
self.dither(2)
|
|
|
|
self.move_camera(theta = -1.1*np.pi)
|
|
|
|
self.dither(2)
|
2017-08-24 23:12:25 -07:00
|
|
|
|
|
|
|
# pol_filter = PolarizingFilter(
|
|
|
|
# label_tex = "C",
|
|
|
|
# filter_angle = np.pi/4,
|
|
|
|
# )
|
|
|
|
# pol_filter.rotate(np.pi/2, RIGHT)
|
|
|
|
# pol_filter.rotate(-np.pi/2, OUT)
|
|
|
|
# pol_filter.shift(DOWN+OUT)
|
|
|
|
# pol_filter.arrow_label.rotate_in_place(np.pi/4, OUT)
|
|
|
|
# shade_in_3d(pol_filter)
|
|
|
|
# self.add(pol_filter)
|
|
|
|
|
2017-08-27 23:52:28 -07:00
|
|
|
# photon = WavePacket(
|
|
|
|
# run_time = 2,
|
|
|
|
# # get_filtered = True,
|
|
|
|
# EMWave_config = {
|
|
|
|
# "start_point" : SPACE_WIDTH*LEFT + DOWN+OUT,
|
|
|
|
# "A_vect" : [0, 1, 0],
|
|
|
|
# },
|
|
|
|
# )
|
|
|
|
# photon.update(0.5)
|
|
|
|
# photon.mobject.show(self.camera)
|
|
|
|
|
|
|
|
# self.move_camera(theta = -1.2*np.pi/2)
|
|
|
|
# self.play(photon)
|
2017-08-24 11:44:06 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|