mirror of
https://github.com/3b1b/manim.git
synced 2025-07-31 22:13:30 +08:00
Photon through lens
This commit is contained in:
0
brachistochrone/__init__.py
Normal file
0
brachistochrone/__init__.py
Normal file
@ -323,39 +323,6 @@ class RollingRandolph(PathSlidingScene):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class OceanScene(Scene):
|
|
||||||
def construct(self):
|
|
||||||
self.rolling_waves()
|
|
||||||
|
|
||||||
def rolling_waves(self):
|
|
||||||
if not hasattr(self, "ocean"):
|
|
||||||
self.setup_ocean()
|
|
||||||
for state in self.ocean_states:
|
|
||||||
self.play(Transform(self.ocean, state))
|
|
||||||
|
|
||||||
|
|
||||||
def setup_ocean(self):
|
|
||||||
def func(points):
|
|
||||||
result = np.zeros(points.shape)
|
|
||||||
result[:,1] = 0.25 * np.sin(points[:,0]) * np.sin(points[:,1])
|
|
||||||
return result
|
|
||||||
|
|
||||||
self.ocean_states = []
|
|
||||||
for unit in -1, 1:
|
|
||||||
ocean = FilledRectangle(
|
|
||||||
color = BLUE_D,
|
|
||||||
density = 25
|
|
||||||
)
|
|
||||||
nudges = unit*func(ocean.points)
|
|
||||||
ocean.points += nudges
|
|
||||||
alphas = nudges[:,1]
|
|
||||||
alphas -= np.min(alphas)
|
|
||||||
whites = np.ones(ocean.rgbs.shape)
|
|
||||||
thick_alphas = alphas.repeat(3).reshape((len(alphas), 3))
|
|
||||||
ocean.rgbs = interpolate(ocean.rgbs, whites, thick_alphas)
|
|
||||||
self.ocean_states.append(ocean)
|
|
||||||
self.ocean = self.ocean_states[1].copy()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,26 @@ from topics.number_line import NumberPlane
|
|||||||
from region import Region, region_from_polygon_vertices
|
from region import Region, region_from_polygon_vertices
|
||||||
from scene import Scene
|
from scene import Scene
|
||||||
|
|
||||||
|
from brachistochrone.curves import Cycloid
|
||||||
|
|
||||||
|
class Lens(Arc):
|
||||||
|
DEFAULT_CONFIG = {
|
||||||
|
"radius" : 2,
|
||||||
|
"angle" : np.pi/2,
|
||||||
|
"color" : BLUE_B,
|
||||||
|
}
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
digest_config(self, kwargs)
|
||||||
|
Arc.__init__(self, self.angle, **kwargs)
|
||||||
|
|
||||||
|
def generate_points(self):
|
||||||
|
Arc.generate_points(self)
|
||||||
|
self.rotate(-np.pi/4)
|
||||||
|
self.shift(-self.get_left())
|
||||||
|
self.add_points(self.copy().rotate(np.pi).points)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PhotonScene(Scene):
|
class PhotonScene(Scene):
|
||||||
def wavify(self, mobject):
|
def wavify(self, mobject):
|
||||||
tangent_vectors = mobject.points[1:]-mobject.points[:-1]
|
tangent_vectors = mobject.points[1:]-mobject.points[:-1]
|
||||||
@ -46,14 +66,11 @@ class PhotonScene(Scene):
|
|||||||
result.points[1:] += nudges
|
result.points[1:] += nudges
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def photon_along_path(self, path, color = YELLOW, run_time = 1):
|
|
||||||
|
def photon_run_along_path(self, path, color = YELLOW, **kwargs):
|
||||||
photon = self.wavify(path)
|
photon = self.wavify(path)
|
||||||
photon.highlight(color)
|
photon.highlight(color)
|
||||||
self.play(ShowPassingFlash(
|
return ShowPassingFlash(photon, **kwargs)
|
||||||
photon,
|
|
||||||
run_time = run_time,
|
|
||||||
rate_func = None
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
class SimplePhoton(PhotonScene):
|
class SimplePhoton(PhotonScene):
|
||||||
@ -61,5 +78,60 @@ class SimplePhoton(PhotonScene):
|
|||||||
text = TextMobject("Light")
|
text = TextMobject("Light")
|
||||||
text.to_edge(UP)
|
text.to_edge(UP)
|
||||||
self.play(ShimmerIn(text))
|
self.play(ShimmerIn(text))
|
||||||
self.photon_along_path(Cycloid())
|
self.play(self.photon_run_along_path(
|
||||||
|
Cycloid(), rate_func = None
|
||||||
|
))
|
||||||
self.dither()
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
|
class PhotonThroughLens(PhotonScene):
|
||||||
|
def construct(self):
|
||||||
|
lens = Lens()
|
||||||
|
num_paths = 5
|
||||||
|
interval_values = np.arange(num_paths)/(num_paths-1.)
|
||||||
|
first_contact = [
|
||||||
|
lens.point_from_interval(0.4*v+0.55)
|
||||||
|
for v in reversed(interval_values)
|
||||||
|
]
|
||||||
|
second_contact = [
|
||||||
|
lens.point_from_interval(0.3*v + 0.1)
|
||||||
|
for v in interval_values
|
||||||
|
]
|
||||||
|
focal_point = 2*RIGHT
|
||||||
|
paths = [
|
||||||
|
Mobject(
|
||||||
|
Line(SPACE_WIDTH*LEFT + fc[1]*UP, fc),
|
||||||
|
Line(fc, sc),
|
||||||
|
Line(sc, focal_point),
|
||||||
|
Line(focal_point, 6*focal_point-5*sc)
|
||||||
|
).ingest_sub_mobjects()
|
||||||
|
for fc, sc in zip(first_contact, second_contact)
|
||||||
|
]
|
||||||
|
colors = Color(YELLOW).range_to(WHITE, len(paths))
|
||||||
|
for path, color in zip(paths, colors):
|
||||||
|
path.highlight(color)
|
||||||
|
photon_runs = [
|
||||||
|
self.photon_run_along_path(path)
|
||||||
|
for path in paths
|
||||||
|
]
|
||||||
|
self.add(lens)
|
||||||
|
for photon_run, path in zip(photon_runs, paths):
|
||||||
|
self.play(
|
||||||
|
photon_run,
|
||||||
|
ShowCreation(
|
||||||
|
path,
|
||||||
|
rate_func = lambda t : 0.9*smooth(t)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,8 +19,8 @@ MEDIUM_QUALITY_DISPLAY_CONFIG = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOW_QUALITY_DISPLAY_CONFIG = {
|
LOW_QUALITY_DISPLAY_CONFIG = {
|
||||||
"height" : 480,
|
"height" : 600,#480,
|
||||||
"width" : 840,
|
"width" : 1000,#840,
|
||||||
"frame_duration" : 0.04,
|
"frame_duration" : 0.04,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,6 +460,9 @@ class Mobject(object):
|
|||||||
def get_height(self):
|
def get_height(self):
|
||||||
return self.length_over_dim(1)
|
return self.length_over_dim(1)
|
||||||
|
|
||||||
|
def point_from_interval(self, alpha):
|
||||||
|
index = alpha*(self.get_num_points()-1)
|
||||||
|
return self.points[index]
|
||||||
|
|
||||||
def get_color(self):
|
def get_color(self):
|
||||||
color = Color()
|
color = Color()
|
||||||
|
Reference in New Issue
Block a user