mirror of
https://github.com/3b1b/manim.git
synced 2025-09-01 00:48:45 +00:00
commit
3b088b1284
24 changed files with 3272 additions and 170 deletions
|
@ -1,28 +0,0 @@
|
||||||
# from active_projects.clacks import question
|
|
||||||
# from active_projects.clacks import solution1
|
|
||||||
from active_projects.clacks.solution2 import block_collision_scenes
|
|
||||||
from active_projects.clacks.solution2 import simple_scenes
|
|
||||||
from active_projects.clacks.solution2 import wordy_scenes
|
|
||||||
from active_projects.clacks.solution2 import pi_creature_scenes
|
|
||||||
from active_projects.clacks.solution2 import position_phase_space
|
|
||||||
|
|
||||||
OUTPUT_DIRECTORY = "clacks_solution2"
|
|
||||||
ALL_SCENE_CLASSES = [
|
|
||||||
block_collision_scenes.IntroducePreviousTwoVideos,
|
|
||||||
block_collision_scenes.PreviousTwoVideos,
|
|
||||||
wordy_scenes.ConnectionToOptics,
|
|
||||||
pi_creature_scenes.OnAnsweringTwice,
|
|
||||||
simple_scenes.LastVideoWrapper,
|
|
||||||
position_phase_space.IntroducePositionPhaseSpace,
|
|
||||||
position_phase_space.UnscaledPositionPhaseSpaceMass100,
|
|
||||||
position_phase_space.EqualMassCase,
|
|
||||||
pi_creature_scenes.AskAboutEqualMassMomentumTransfer,
|
|
||||||
position_phase_space.FailedAngleRelation,
|
|
||||||
position_phase_space.UnscaledPositionPhaseSpaceMass10,
|
|
||||||
pi_creature_scenes.ComplainAboutRelevanceOfAnalogy,
|
|
||||||
simple_scenes.LastVideoWrapper,
|
|
||||||
position_phase_space.RescaleCoordinates,
|
|
||||||
wordy_scenes.ConnectionToOpticsTransparent,
|
|
||||||
position_phase_space.RescaleCoordinatesMass16,
|
|
||||||
position_phase_space.RescaleCoordinatesMass64,
|
|
||||||
]
|
|
|
@ -1,15 +0,0 @@
|
||||||
from big_ol_pile_of_manim_imports import *
|
|
||||||
|
|
||||||
|
|
||||||
class LastVideoWrapper(Scene):
|
|
||||||
def construct(self):
|
|
||||||
title = TextMobject("Last time...")
|
|
||||||
title.scale(1.5)
|
|
||||||
title.to_edge(UP)
|
|
||||||
rect = ScreenRectangle(height=6)
|
|
||||||
rect.next_to(title, DOWN)
|
|
||||||
self.play(
|
|
||||||
FadeInFromDown(title),
|
|
||||||
ShowCreation(rect)
|
|
||||||
)
|
|
||||||
self.wait()
|
|
|
@ -29,6 +29,9 @@ class Animation(object):
|
||||||
mobject = instantiate(mobject)
|
mobject = instantiate(mobject)
|
||||||
assert(isinstance(mobject, Mobject))
|
assert(isinstance(mobject, Mobject))
|
||||||
digest_config(self, kwargs, locals())
|
digest_config(self, kwargs, locals())
|
||||||
|
# Make sure it's all up to date
|
||||||
|
mobject.update()
|
||||||
|
# Keep track of where it started
|
||||||
self.starting_mobject = self.mobject.copy()
|
self.starting_mobject = self.mobject.copy()
|
||||||
if self.rate_func is None:
|
if self.rate_func is None:
|
||||||
self.rate_func = (lambda x: x)
|
self.rate_func = (lambda x: x)
|
||||||
|
|
|
@ -5,7 +5,6 @@ from manimlib.animation.transform import Transform
|
||||||
from manimlib.constants import *
|
from manimlib.constants import *
|
||||||
from manimlib.mobject.svg.tex_mobject import TextMobject
|
from manimlib.mobject.svg.tex_mobject import TextMobject
|
||||||
from manimlib.mobject.types.vectorized_mobject import VMobject
|
from manimlib.mobject.types.vectorized_mobject import VMobject
|
||||||
from manimlib.mobject.types.vectorized_mobject import VectorizedPoint
|
|
||||||
from manimlib.utils.bezier import interpolate
|
from manimlib.utils.bezier import interpolate
|
||||||
from manimlib.utils.config_ops import digest_config
|
from manimlib.utils.config_ops import digest_config
|
||||||
from manimlib.utils.paths import counterclockwise_path
|
from manimlib.utils.paths import counterclockwise_path
|
||||||
|
|
|
@ -44,7 +44,7 @@ class Rotate(Transform):
|
||||||
if "path_arc_axis" not in kwargs:
|
if "path_arc_axis" not in kwargs:
|
||||||
kwargs["path_arc_axis"] = axis
|
kwargs["path_arc_axis"] = axis
|
||||||
digest_config(self, kwargs, locals())
|
digest_config(self, kwargs, locals())
|
||||||
target = mobject.copy()
|
target = mobject.deepcopy()
|
||||||
if self.in_place:
|
if self.in_place:
|
||||||
self.about_point = mobject.get_center()
|
self.about_point = mobject.get_center()
|
||||||
target.rotate(
|
target.rotate(
|
||||||
|
|
|
@ -29,8 +29,10 @@ class Transform(Animation):
|
||||||
# Copy target_mobject so as to not mess with caller
|
# Copy target_mobject so as to not mess with caller
|
||||||
self.original_target_mobject = target_mobject
|
self.original_target_mobject = target_mobject
|
||||||
target_mobject = target_mobject.copy()
|
target_mobject = target_mobject.copy()
|
||||||
mobject.align_data(target_mobject)
|
target_mobject.update()
|
||||||
self.target_mobject = target_mobject
|
self.target_mobject = target_mobject
|
||||||
|
|
||||||
|
mobject.align_data(target_mobject)
|
||||||
digest_config(self, kwargs)
|
digest_config(self, kwargs)
|
||||||
self.init_path_func()
|
self.init_path_func()
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ class Camera(object):
|
||||||
"background_image": None,
|
"background_image": None,
|
||||||
"pixel_height": DEFAULT_PIXEL_HEIGHT,
|
"pixel_height": DEFAULT_PIXEL_HEIGHT,
|
||||||
"pixel_width": DEFAULT_PIXEL_WIDTH,
|
"pixel_width": DEFAULT_PIXEL_WIDTH,
|
||||||
"frame_duration": DEFAULT_FRAME_DURATION,
|
"frame_rate": DEFAULT_FRAME_RATE,
|
||||||
# Note: frame height and width will be resized to match
|
# Note: frame height and width will be resized to match
|
||||||
# the pixel aspect ratio
|
# the pixel aspect ratio
|
||||||
"frame_height": FRAME_HEIGHT,
|
"frame_height": FRAME_HEIGHT,
|
||||||
|
|
|
@ -109,7 +109,7 @@ LOW_QUALITY_CAMERA_CONFIG = {
|
||||||
|
|
||||||
DEFAULT_PIXEL_HEIGHT = PRODUCTION_QUALITY_CAMERA_CONFIG["pixel_height"]
|
DEFAULT_PIXEL_HEIGHT = PRODUCTION_QUALITY_CAMERA_CONFIG["pixel_height"]
|
||||||
DEFAULT_PIXEL_WIDTH = PRODUCTION_QUALITY_CAMERA_CONFIG["pixel_width"]
|
DEFAULT_PIXEL_WIDTH = PRODUCTION_QUALITY_CAMERA_CONFIG["pixel_width"]
|
||||||
DEFAULT_FRAME_DURATION = 30
|
DEFAULT_FRAME_RATE = 60
|
||||||
|
|
||||||
DEFAULT_POINT_DENSITY_2D = 25
|
DEFAULT_POINT_DENSITY_2D = 25
|
||||||
DEFAULT_POINT_DENSITY_1D = 250
|
DEFAULT_POINT_DENSITY_1D = 250
|
||||||
|
|
|
@ -307,6 +307,7 @@ class Banner(Scene):
|
||||||
"date": "Sunday, February 3rd",
|
"date": "Sunday, February 3rd",
|
||||||
"message_scale_val": 0.9,
|
"message_scale_val": 0.9,
|
||||||
"add_supporter_note": False,
|
"add_supporter_note": False,
|
||||||
|
"pre_date_text": "Next video on ",
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
@ -363,7 +364,8 @@ class Banner(Scene):
|
||||||
|
|
||||||
def get_date_message(self):
|
def get_date_message(self):
|
||||||
return TextMobject(
|
return TextMobject(
|
||||||
"Next video on ", self.date,
|
self.pre_date_text,
|
||||||
|
self.date,
|
||||||
tex_to_color_map={self.date: YELLOW},
|
tex_to_color_map={self.date: YELLOW},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -403,10 +403,11 @@ class Line(VMobject):
|
||||||
start, end = self.get_start_and_end()
|
start, end = self.get_start_and_end()
|
||||||
return angle_of_vector(end - start)
|
return angle_of_vector(end - start)
|
||||||
|
|
||||||
# def put_start_and_end_on(self, new_start, new_end):
|
def set_angle(self, angle):
|
||||||
# self.set_start_and_end(new_start, new_end)
|
self.rotate(
|
||||||
# self.buff = 0
|
angle - self.get_angle(),
|
||||||
# self.generate_points()
|
about_point=self.get_start(),
|
||||||
|
)
|
||||||
|
|
||||||
def put_start_and_end_on(self, new_start, new_end):
|
def put_start_and_end_on(self, new_start, new_end):
|
||||||
self.start = new_start
|
self.start = new_start
|
||||||
|
|
|
@ -125,6 +125,7 @@ class Mobject(Container):
|
||||||
copy_mobject.submobjects = [
|
copy_mobject.submobjects = [
|
||||||
submob.copy() for submob in self.submobjects
|
submob.copy() for submob in self.submobjects
|
||||||
]
|
]
|
||||||
|
copy_mobject.updaters = list(self.updaters)
|
||||||
family = self.get_family()
|
family = self.get_family()
|
||||||
for attr, value in list(self.__dict__.items()):
|
for attr, value in list(self.__dict__.items()):
|
||||||
if isinstance(value, Mobject) and value in family and value is not self:
|
if isinstance(value, Mobject) and value in family and value is not self:
|
||||||
|
@ -147,13 +148,14 @@ class Mobject(Container):
|
||||||
# Updating
|
# Updating
|
||||||
|
|
||||||
def update(self, dt=0, recursive=True):
|
def update(self, dt=0, recursive=True):
|
||||||
if not self.updating_suspended:
|
if self.updating_suspended:
|
||||||
for updater in self.updaters:
|
return self
|
||||||
parameters = get_parameters(updater)
|
for updater in self.updaters:
|
||||||
if "dt" in parameters:
|
parameters = get_parameters(updater)
|
||||||
updater(self, dt)
|
if "dt" in parameters:
|
||||||
else:
|
updater(self, dt)
|
||||||
updater(self)
|
else:
|
||||||
|
updater(self)
|
||||||
if recursive:
|
if recursive:
|
||||||
for submob in self.submobjects:
|
for submob in self.submobjects:
|
||||||
submob.update(dt, recursive)
|
submob.update(dt, recursive)
|
||||||
|
@ -182,8 +184,11 @@ class Mobject(Container):
|
||||||
self.updaters.remove(update_function)
|
self.updaters.remove(update_function)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def clear_updaters(self):
|
def clear_updaters(self, recursive=True):
|
||||||
self.updaters = []
|
self.updaters = []
|
||||||
|
if recursive:
|
||||||
|
for submob in self.submobjects:
|
||||||
|
submob.clear_updaters()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def suspend_updating(self, recursive=True):
|
def suspend_updating(self, recursive=True):
|
||||||
|
|
|
@ -32,9 +32,9 @@ class VMobject(Mobject):
|
||||||
"background_stroke_width": 0,
|
"background_stroke_width": 0,
|
||||||
# When a color c is set, there will be a second color
|
# When a color c is set, there will be a second color
|
||||||
# computed based on interpolating c to WHITE by with
|
# computed based on interpolating c to WHITE by with
|
||||||
# sheen, and the display will gradient to this
|
# sheen_factor, and the display will gradient to this
|
||||||
# secondary color in the direction of sheen_direction.
|
# secondary color in the direction of sheen_direction.
|
||||||
"sheen": 0.0,
|
"sheen_factor": 0.0,
|
||||||
"sheen_direction": UL,
|
"sheen_direction": UL,
|
||||||
# Indicates that it will not be displayed, but
|
# Indicates that it will not be displayed, but
|
||||||
# that it should count in parent mobject's path
|
# that it should count in parent mobject's path
|
||||||
|
@ -71,7 +71,7 @@ class VMobject(Mobject):
|
||||||
family=self.propagate_style_to_family,
|
family=self.propagate_style_to_family,
|
||||||
)
|
)
|
||||||
self.set_sheen(
|
self.set_sheen(
|
||||||
factor=self.sheen,
|
factor=self.sheen_factor,
|
||||||
direction=self.sheen_direction,
|
direction=self.sheen_direction,
|
||||||
family=self.propagate_style_to_family
|
family=self.propagate_style_to_family
|
||||||
)
|
)
|
||||||
|
@ -81,7 +81,7 @@ class VMobject(Mobject):
|
||||||
"""
|
"""
|
||||||
First arg can be either a color, or a tuple/list of colors.
|
First arg can be either a color, or a tuple/list of colors.
|
||||||
Likewise, opacity can either be a float, or a tuple of floats.
|
Likewise, opacity can either be a float, or a tuple of floats.
|
||||||
If self.sheen is not zero, and only
|
If self.sheen_factor is not zero, and only
|
||||||
one color was passed in, a second slightly light color
|
one color was passed in, a second slightly light color
|
||||||
will automatically be added for the gradient
|
will automatically be added for the gradient
|
||||||
"""
|
"""
|
||||||
|
@ -92,10 +92,10 @@ class VMobject(Mobject):
|
||||||
for c, o in zip(*make_even(colors, opacities))
|
for c, o in zip(*make_even(colors, opacities))
|
||||||
])
|
])
|
||||||
|
|
||||||
sheen = self.get_sheen()
|
sheen_factor = self.get_sheen_factor()
|
||||||
if sheen != 0 and len(rgbas) == 1:
|
if sheen_factor != 0 and len(rgbas) == 1:
|
||||||
light_rgbas = np.array(rgbas)
|
light_rgbas = np.array(rgbas)
|
||||||
light_rgbas[:, :3] += sheen
|
light_rgbas[:, :3] += sheen_factor
|
||||||
clip_in_place(light_rgbas, 0, 1)
|
clip_in_place(light_rgbas, 0, 1)
|
||||||
rgbas = np.append(rgbas, light_rgbas, axis=0)
|
rgbas = np.append(rgbas, light_rgbas, axis=0)
|
||||||
return rgbas
|
return rgbas
|
||||||
|
@ -160,8 +160,10 @@ class VMobject(Mobject):
|
||||||
fill_opacity=None,
|
fill_opacity=None,
|
||||||
stroke_color=None,
|
stroke_color=None,
|
||||||
stroke_width=None,
|
stroke_width=None,
|
||||||
|
stroke_opacity=None,
|
||||||
background_stroke_color=None,
|
background_stroke_color=None,
|
||||||
background_stroke_width=None,
|
background_stroke_width=None,
|
||||||
|
background_stroke_opacity=None,
|
||||||
sheen_factor=None,
|
sheen_factor=None,
|
||||||
sheen_direction=None,
|
sheen_direction=None,
|
||||||
background_image_file=None,
|
background_image_file=None,
|
||||||
|
@ -174,11 +176,13 @@ class VMobject(Mobject):
|
||||||
self.set_stroke(
|
self.set_stroke(
|
||||||
color=stroke_color,
|
color=stroke_color,
|
||||||
width=stroke_width,
|
width=stroke_width,
|
||||||
|
opacity=stroke_opacity,
|
||||||
family=family,
|
family=family,
|
||||||
)
|
)
|
||||||
self.set_background_stroke(
|
self.set_background_stroke(
|
||||||
color=background_stroke_color,
|
color=background_stroke_color,
|
||||||
width=background_stroke_width,
|
width=background_stroke_width,
|
||||||
|
opacity=background_stroke_opacity,
|
||||||
family=family,
|
family=family,
|
||||||
)
|
)
|
||||||
if sheen_factor:
|
if sheen_factor:
|
||||||
|
@ -198,7 +202,7 @@ class VMobject(Mobject):
|
||||||
"stroke_width": self.get_stroke_width(),
|
"stroke_width": self.get_stroke_width(),
|
||||||
"background_stroke_color": self.get_stroke_colors(background=True),
|
"background_stroke_color": self.get_stroke_colors(background=True),
|
||||||
"background_stroke_width": self.get_stroke_width(background=True),
|
"background_stroke_width": self.get_stroke_width(background=True),
|
||||||
"sheen_factor": self.get_sheen(),
|
"sheen_factor": self.get_sheen_factor(),
|
||||||
"sheen_direction": self.get_sheen_direction(),
|
"sheen_direction": self.get_sheen_direction(),
|
||||||
"background_image_file": self.get_background_image_file(),
|
"background_image_file": self.get_background_image_file(),
|
||||||
}
|
}
|
||||||
|
@ -309,12 +313,12 @@ class VMobject(Mobject):
|
||||||
if family:
|
if family:
|
||||||
for submob in self.submobjects:
|
for submob in self.submobjects:
|
||||||
submob.set_sheen(factor, direction, family)
|
submob.set_sheen(factor, direction, family)
|
||||||
self.sheen = factor
|
self.sheen_factor = factor
|
||||||
if direction is not None:
|
if direction is not None:
|
||||||
# family set to false because recursion will
|
# family set to false because recursion will
|
||||||
# already be handled above
|
# already be handled above
|
||||||
self.set_sheen_direction(direction, family=False)
|
self.set_sheen_direction(direction, family=False)
|
||||||
# Reset color to put sheen into effect
|
# Reset color to put sheen_factor into effect
|
||||||
if factor != 0:
|
if factor != 0:
|
||||||
self.set_stroke(self.get_stroke_color(), family=family)
|
self.set_stroke(self.get_stroke_color(), family=family)
|
||||||
self.set_fill(self.get_fill_color(), family=family)
|
self.set_fill(self.get_fill_color(), family=family)
|
||||||
|
@ -323,8 +327,8 @@ class VMobject(Mobject):
|
||||||
def get_sheen_direction(self):
|
def get_sheen_direction(self):
|
||||||
return np.array(self.sheen_direction)
|
return np.array(self.sheen_direction)
|
||||||
|
|
||||||
def get_sheen(self):
|
def get_sheen_factor(self):
|
||||||
return self.sheen
|
return self.sheen_factor
|
||||||
|
|
||||||
def get_gradient_start_and_end_points(self):
|
def get_gradient_start_and_end_points(self):
|
||||||
if self.shade_in_3d:
|
if self.shade_in_3d:
|
||||||
|
@ -613,7 +617,7 @@ class VMobject(Mobject):
|
||||||
"stroke_width",
|
"stroke_width",
|
||||||
"background_stroke_width",
|
"background_stroke_width",
|
||||||
"sheen_direction",
|
"sheen_direction",
|
||||||
"sheen",
|
"sheen_factor",
|
||||||
]
|
]
|
||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
setattr(self, attr, interpolate(
|
setattr(self, attr, interpolate(
|
||||||
|
@ -694,7 +698,7 @@ class VectorizedPoint(VMobject):
|
||||||
return self.artificial_height
|
return self.artificial_height
|
||||||
|
|
||||||
def get_location(self):
|
def get_location(self):
|
||||||
return self.points[0]
|
return np.array(self.points[0])
|
||||||
|
|
||||||
def set_location(self, new_loc):
|
def set_location(self, new_loc):
|
||||||
self.set_points(np.array([new_loc]))
|
self.set_points(np.array([new_loc]))
|
||||||
|
|
|
@ -528,6 +528,7 @@ class Scene(Container):
|
||||||
@handle_play_like_call
|
@handle_play_like_call
|
||||||
def wait(self, duration=DEFAULT_WAIT_TIME, stop_condition=None):
|
def wait(self, duration=DEFAULT_WAIT_TIME, stop_condition=None):
|
||||||
dt = 1 / self.camera.frame_rate
|
dt = 1 / self.camera.frame_rate
|
||||||
|
self.continual_update(dt=0) # Any problems with this?
|
||||||
if self.should_continually_update():
|
if self.should_continually_update():
|
||||||
time_progression = self.get_wait_time_progression(duration, stop_condition)
|
time_progression = self.get_wait_time_progression(duration, stop_condition)
|
||||||
for t in time_progression:
|
for t in time_progression:
|
||||||
|
|
62
old_projects/clacks/all_s2_scenes.py
Normal file
62
old_projects/clacks/all_s2_scenes.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
from old_projects.clacks import question
|
||||||
|
from old_projects.clacks.solution2 import block_collision_scenes
|
||||||
|
from old_projects.clacks.solution2 import mirror_scenes
|
||||||
|
from old_projects.clacks.solution2 import pi_creature_scenes
|
||||||
|
from old_projects.clacks.solution2 import position_phase_space
|
||||||
|
from old_projects.clacks.solution2 import simple_scenes
|
||||||
|
from old_projects.clacks.solution2 import wordy_scenes
|
||||||
|
|
||||||
|
OUTPUT_DIRECTORY = "clacks_solution2"
|
||||||
|
ALL_SCENE_CLASSES = [
|
||||||
|
question.NameIntro,
|
||||||
|
block_collision_scenes.IntroducePreviousTwoVideos,
|
||||||
|
block_collision_scenes.PreviousTwoVideos,
|
||||||
|
simple_scenes.ComingUpWrapper,
|
||||||
|
wordy_scenes.ConnectionToOptics,
|
||||||
|
pi_creature_scenes.OnAnsweringTwice,
|
||||||
|
simple_scenes.LastVideoWrapper,
|
||||||
|
simple_scenes.Rectangle,
|
||||||
|
simple_scenes.ShowRectangleCreation,
|
||||||
|
simple_scenes.LeftEdge,
|
||||||
|
simple_scenes.RightEdge,
|
||||||
|
position_phase_space.IntroducePositionPhaseSpace,
|
||||||
|
position_phase_space.UnscaledPositionPhaseSpaceMass100,
|
||||||
|
simple_scenes.FourtyFiveDegreeLine,
|
||||||
|
position_phase_space.EqualMassCase,
|
||||||
|
pi_creature_scenes.AskAboutEqualMassMomentumTransfer,
|
||||||
|
position_phase_space.FailedAngleRelation,
|
||||||
|
position_phase_space.UnscaledPositionPhaseSpaceMass10,
|
||||||
|
pi_creature_scenes.ComplainAboutRelevanceOfAnalogy,
|
||||||
|
simple_scenes.LastVideoWrapper,
|
||||||
|
simple_scenes.NoteOnEnergyLostToSound,
|
||||||
|
position_phase_space.RescaleCoordinates,
|
||||||
|
wordy_scenes.ConnectionToOpticsTransparent,
|
||||||
|
position_phase_space.RescaleCoordinatesMass16,
|
||||||
|
position_phase_space.RescaleCoordinatesMass64,
|
||||||
|
position_phase_space.RescaleCoordinatesMass100,
|
||||||
|
position_phase_space.IntroduceVelocityVector,
|
||||||
|
position_phase_space.IntroduceVelocityVectorWithoutZoom,
|
||||||
|
position_phase_space.ShowMomentumConservation,
|
||||||
|
wordy_scenes.RearrangeMomentumEquation,
|
||||||
|
simple_scenes.DotProductVideoWrapper,
|
||||||
|
simple_scenes.ShowDotProductMeaning,
|
||||||
|
position_phase_space.JustTheProcessNew,
|
||||||
|
mirror_scenes.ShowTrajectoryWithChangingTheta,
|
||||||
|
pi_creature_scenes.ReplaceOneTrickySceneWithAnother,
|
||||||
|
mirror_scenes.MirrorAndWiresOverlay,
|
||||||
|
pi_creature_scenes.NowForTheGoodPart,
|
||||||
|
mirror_scenes.ReflectWorldThroughMirrorNew,
|
||||||
|
mirror_scenes.ReflectWorldThroughMirrorThetaPoint2,
|
||||||
|
mirror_scenes.ReflectWorldThroughMirrorThetaPoint1,
|
||||||
|
simple_scenes.AskAboutAddingThetaToItself,
|
||||||
|
simple_scenes.AskAboutAddingThetaToItselfThetaPoint1,
|
||||||
|
simple_scenes.AskAboutAddingThetaToItselfThetaPoint2,
|
||||||
|
simple_scenes.FinalFormula,
|
||||||
|
simple_scenes.ArctanSqrtPoint1Angle,
|
||||||
|
simple_scenes.ReviewWrapper,
|
||||||
|
simple_scenes.SurprisedRandy,
|
||||||
|
simple_scenes.TwoSolutionsWrapper,
|
||||||
|
simple_scenes.FinalQuote,
|
||||||
|
simple_scenes.EndScreen,
|
||||||
|
simple_scenes.ClacksSolution2Thumbnail,
|
||||||
|
]
|
|
@ -1,7 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
from big_ol_pile_of_manim_imports import *
|
from big_ol_pile_of_manim_imports import *
|
||||||
|
from old_projects.clacks.question import BlocksAndWallExample
|
||||||
from active_projects.clacks.question import BlocksAndWallExample
|
|
||||||
|
|
||||||
|
|
||||||
class NameBump(BlocksAndWallExample):
|
class NameBump(BlocksAndWallExample):
|
|
@ -13,7 +13,7 @@ class Block(Square):
|
||||||
"stroke_color": WHITE,
|
"stroke_color": WHITE,
|
||||||
"fill_color": None,
|
"fill_color": None,
|
||||||
"sheen_direction": UL,
|
"sheen_direction": UL,
|
||||||
"sheen": 0.5,
|
"sheen_factor": 0.5,
|
||||||
"sheen_direction": UL,
|
"sheen_direction": UL,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class Block(Square):
|
||||||
def mass_to_color(self, mass):
|
def mass_to_color(self, mass):
|
||||||
colors = [
|
colors = [
|
||||||
LIGHT_GREY,
|
LIGHT_GREY,
|
||||||
BLUE_B,
|
BLUE_D,
|
||||||
BLUE_D,
|
BLUE_D,
|
||||||
BLUE_E,
|
BLUE_E,
|
||||||
BLUE_E,
|
BLUE_E,
|
||||||
|
@ -225,7 +225,7 @@ class ClackFlashes(ContinualAnimation):
|
||||||
ContinualAnimation.__init__(self, group, **kwargs)
|
ContinualAnimation.__init__(self, group, **kwargs)
|
||||||
|
|
||||||
def update_mobject(self, dt):
|
def update_mobject(self, dt):
|
||||||
total_time = self.external_time
|
total_time = self.get_time()
|
||||||
group = self.mobject
|
group = self.mobject
|
||||||
for flash in self.flashes:
|
for flash in self.flashes:
|
||||||
if flash.start_time < total_time < flash.end_time:
|
if flash.start_time < total_time < flash.end_time:
|
||||||
|
@ -238,6 +238,9 @@ class ClackFlashes(ContinualAnimation):
|
||||||
if flash.mobject in group:
|
if flash.mobject in group:
|
||||||
group.remove(flash.mobject)
|
group.remove(flash.mobject)
|
||||||
|
|
||||||
|
def get_time(self):
|
||||||
|
return self.external_time
|
||||||
|
|
||||||
|
|
||||||
class Wall(Line):
|
class Wall(Line):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
|
@ -410,6 +413,10 @@ class NameIntro(Scene):
|
||||||
rate_func=None,
|
rate_func=None,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
self.play(
|
||||||
|
Flash(brown.get_right(), run_time=flash_time),
|
||||||
|
Restore(brown, rate_func=None)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MathAndPhysicsConspiring(Scene):
|
class MathAndPhysicsConspiring(Scene):
|
||||||
|
@ -1558,16 +1565,16 @@ class Thumbnail(BlocksAndWallExample, MovingCameraScene):
|
||||||
BlocksAndWallExample.setup(self)
|
BlocksAndWallExample.setup(self)
|
||||||
|
|
||||||
def construct(self):
|
def construct(self):
|
||||||
# self.camera_frame.shift(0.9 * UP)
|
self.camera_frame.shift(0.9 * UP)
|
||||||
self.mobjects.insert(
|
# self.mobjects.insert(
|
||||||
0,
|
# 0,
|
||||||
FullScreenFadeRectangle(
|
# FullScreenFadeRectangle(
|
||||||
color=DARK_GREY,
|
# color=DARK_GREY,
|
||||||
opacity=0.5,
|
# opacity=0.5,
|
||||||
sheen_direction=UL,
|
# sheen_direction=UL,
|
||||||
sheen=0.5,
|
# sheen=0.5,
|
||||||
),
|
# ),
|
||||||
)
|
# )
|
||||||
self.thicken_lines()
|
self.thicken_lines()
|
||||||
self.grow_labels()
|
self.grow_labels()
|
||||||
self.add_vector()
|
self.add_vector()
|
||||||
|
@ -1587,7 +1594,7 @@ class Thumbnail(BlocksAndWallExample, MovingCameraScene):
|
||||||
|
|
||||||
def add_vector(self):
|
def add_vector(self):
|
||||||
blocks = self.blocks
|
blocks = self.blocks
|
||||||
arrow = Vector(
|
arrow = self.arrow = Vector(
|
||||||
2.5 * LEFT,
|
2.5 * LEFT,
|
||||||
color=RED,
|
color=RED,
|
||||||
rectangular_stem_width=1.5,
|
rectangular_stem_width=1.5,
|
||||||
|
@ -1600,7 +1607,9 @@ class Thumbnail(BlocksAndWallExample, MovingCameraScene):
|
||||||
self.add(arrow)
|
self.add(arrow)
|
||||||
|
|
||||||
def add_text(self):
|
def add_text(self):
|
||||||
question = TextMobject("How many\\\\collisions?")
|
question = self.question = TextMobject(
|
||||||
|
"How many\\\\collisions?"
|
||||||
|
)
|
||||||
question.scale(2.5)
|
question.scale(2.5)
|
||||||
question.to_edge(UP)
|
question.to_edge(UP)
|
||||||
question.set_color(YELLOW)
|
question.set_color(YELLOW)
|
|
@ -1,5 +1,5 @@
|
||||||
from big_ol_pile_of_manim_imports import *
|
from big_ol_pile_of_manim_imports import *
|
||||||
from active_projects.clacks.question import *
|
from old_projects.clacks.question import *
|
||||||
from old_projects.div_curl import ShowTwoPopulations
|
from old_projects.div_curl import ShowTwoPopulations
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from big_ol_pile_of_manim_imports import *
|
from big_ol_pile_of_manim_imports import *
|
||||||
from active_projects.clacks.question import BlocksAndWallExample
|
from old_projects.clacks.question import BlocksAndWallExample
|
||||||
|
|
||||||
|
|
||||||
class PreviousTwoVideos(BlocksAndWallExample):
|
class PreviousTwoVideos(BlocksAndWallExample):
|
||||||
|
@ -7,7 +7,7 @@ class PreviousTwoVideos(BlocksAndWallExample):
|
||||||
"sliding_blocks_config": {
|
"sliding_blocks_config": {
|
||||||
"block1_config": {
|
"block1_config": {
|
||||||
"mass": 1e2,
|
"mass": 1e2,
|
||||||
"velocity": -1,
|
"velocity": -2,
|
||||||
"width": 4,
|
"width": 4,
|
||||||
"distance": 8,
|
"distance": 8,
|
||||||
},
|
},
|
1021
old_projects/clacks/solution2/mirror_scenes.py
Normal file
1021
old_projects/clacks/solution2/mirror_scenes.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -49,7 +49,16 @@ class OnAnsweringTwice(TeacherStudentsScene):
|
||||||
|
|
||||||
class AskAboutEqualMassMomentumTransfer(TeacherStudentsScene):
|
class AskAboutEqualMassMomentumTransfer(TeacherStudentsScene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
pass
|
self.student_says("Why?")
|
||||||
|
self.change_student_modes("confused", "confused")
|
||||||
|
self.wait()
|
||||||
|
self.play(
|
||||||
|
RemovePiCreatureBubble(self.students[2]),
|
||||||
|
self.teacher.change, "raise_right_hand"
|
||||||
|
)
|
||||||
|
self.change_all_student_modes("pondering")
|
||||||
|
self.look_at(self.hold_up_spot + 2 * UP)
|
||||||
|
self.wait(5)
|
||||||
|
|
||||||
|
|
||||||
class ComplainAboutRelevanceOfAnalogy(TeacherStudentsScene):
|
class ComplainAboutRelevanceOfAnalogy(TeacherStudentsScene):
|
||||||
|
@ -76,3 +85,34 @@ class ComplainAboutRelevanceOfAnalogy(TeacherStudentsScene):
|
||||||
self.hold_up_spot + UP,
|
self.hold_up_spot + UP,
|
||||||
)
|
)
|
||||||
self.wait(3)
|
self.wait(3)
|
||||||
|
|
||||||
|
|
||||||
|
class ReplaceOneTrickySceneWithAnother(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
self.student_says(
|
||||||
|
"This replaces one tricky\\\\problem with another",
|
||||||
|
student_index=1,
|
||||||
|
target_mode="sassy",
|
||||||
|
added_anims=[self.teacher.change, "happy"],
|
||||||
|
)
|
||||||
|
self.change_student_modes("erm", "sassy", "angry")
|
||||||
|
self.wait(4)
|
||||||
|
self.play(
|
||||||
|
RemovePiCreatureBubble(self.students[1]),
|
||||||
|
self.teacher.change, "raise_right_hand",
|
||||||
|
self.get_student_changes(*3 * ["pondering"])
|
||||||
|
)
|
||||||
|
self.look_at(self.hold_up_spot + 2 * UP)
|
||||||
|
self.wait(5)
|
||||||
|
|
||||||
|
|
||||||
|
class NowForTheGoodPart(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
self.teacher_says(
|
||||||
|
r"Now for the \\ good part!",
|
||||||
|
target_mode="hooray",
|
||||||
|
added_anims=[self.get_student_changes(
|
||||||
|
"hooray", "surprised", "happy"
|
||||||
|
)],
|
||||||
|
)
|
||||||
|
self.wait(2)
|
File diff suppressed because it is too large
Load diff
841
old_projects/clacks/solution2/simple_scenes.py
Normal file
841
old_projects/clacks/solution2/simple_scenes.py
Normal file
|
@ -0,0 +1,841 @@
|
||||||
|
from big_ol_pile_of_manim_imports import *
|
||||||
|
from old_projects.lost_lecture import ShowWord
|
||||||
|
from old_projects.clacks.solution2.mirror_scenes import ReflectWorldThroughMirrorNew
|
||||||
|
from old_projects.clacks.question import Thumbnail
|
||||||
|
|
||||||
|
|
||||||
|
class WrapperScene(Scene):
|
||||||
|
CONFIG = {
|
||||||
|
"title": "Title",
|
||||||
|
"shade_of_grey": "#333333"
|
||||||
|
}
|
||||||
|
|
||||||
|
def construct(self):
|
||||||
|
title = TextMobject(self.title)
|
||||||
|
title.scale(1.5)
|
||||||
|
title.to_edge(UP)
|
||||||
|
big_rect = self.get_big_rect()
|
||||||
|
screen_rect = self.get_screen_rect()
|
||||||
|
screen_rect.next_to(title, DOWN)
|
||||||
|
|
||||||
|
self.add(big_rect, screen_rect)
|
||||||
|
self.play(
|
||||||
|
FadeIn(big_rect),
|
||||||
|
FadeInFrom(title, DOWN),
|
||||||
|
FadeInFrom(screen_rect, UP),
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
def get_big_rect(self):
|
||||||
|
big_rect = FullScreenFadeRectangle()
|
||||||
|
big_rect.set_fill(self.shade_of_grey, 1)
|
||||||
|
return big_rect
|
||||||
|
|
||||||
|
def get_screen_rect(self, height=6):
|
||||||
|
screen_rect = ScreenRectangle(height=height)
|
||||||
|
screen_rect.set_fill(BLACK, 1)
|
||||||
|
return screen_rect
|
||||||
|
|
||||||
|
|
||||||
|
class ComingUpWrapper(WrapperScene):
|
||||||
|
CONFIG = {"title": "Coming up..."}
|
||||||
|
|
||||||
|
|
||||||
|
class LastVideoWrapper(WrapperScene):
|
||||||
|
CONFIG = {"title": "Last time..."}
|
||||||
|
|
||||||
|
|
||||||
|
class LeftEdge(Scene):
|
||||||
|
CONFIG = {
|
||||||
|
"text": "Left edge",
|
||||||
|
"vect": LEFT,
|
||||||
|
}
|
||||||
|
|
||||||
|
def construct(self):
|
||||||
|
words = TextMobject(self.text)
|
||||||
|
arrow = Vector(self.vect)
|
||||||
|
arrow.match_width(words)
|
||||||
|
arrow.next_to(words, DOWN)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FadeInFromDown(words),
|
||||||
|
GrowArrow(arrow)
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class RightEdge(LeftEdge):
|
||||||
|
CONFIG = {
|
||||||
|
"text": "Right edge",
|
||||||
|
"vect": RIGHT,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class NoteOnEnergyLostToSound(Scene):
|
||||||
|
def construct(self):
|
||||||
|
self.add(TextMobject(
|
||||||
|
"Yeah yeah, the clack sound\\\\"
|
||||||
|
"would require energy, but\\\\"
|
||||||
|
"don't let accuracy get in the\\\\"
|
||||||
|
"way of delight!",
|
||||||
|
alignment="",
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
class DotProductVideoWrapper(WrapperScene):
|
||||||
|
CONFIG = {"title": "Dot product"}
|
||||||
|
|
||||||
|
|
||||||
|
class Rectangle(Scene):
|
||||||
|
def construct(self):
|
||||||
|
rect = ScreenRectangle(height=FRAME_HEIGHT - 0.25)
|
||||||
|
rect.set_stroke(WHITE, 6)
|
||||||
|
self.add(rect)
|
||||||
|
|
||||||
|
|
||||||
|
class ShowRectangleCreation(Scene):
|
||||||
|
def construct(self):
|
||||||
|
rect = ScreenRectangle(height=2)
|
||||||
|
rect.set_stroke(YELLOW, 6)
|
||||||
|
self.play(ShowCreation(rect))
|
||||||
|
self.play(FadeOut(rect))
|
||||||
|
|
||||||
|
|
||||||
|
class ShowDotProductMeaning(Scene):
|
||||||
|
def construct(self):
|
||||||
|
v_vect = Vector(2 * RIGHT, color=YELLOW)
|
||||||
|
w_vect = Vector(3 * RIGHT, color=PINK)
|
||||||
|
dot = Dot(color=RED)
|
||||||
|
dot.shift(DOWN)
|
||||||
|
|
||||||
|
v_vect.angle_tracker = ValueTracker()
|
||||||
|
w_vect.angle_tracker = ValueTracker()
|
||||||
|
|
||||||
|
def update_vect(vect):
|
||||||
|
target = vect.angle_tracker.get_value()
|
||||||
|
vect.rotate(target - vect.get_angle())
|
||||||
|
vect.shift(dot.get_center() - vect.get_start())
|
||||||
|
|
||||||
|
v_vect.add_updater(update_vect)
|
||||||
|
w_vect.add_updater(update_vect)
|
||||||
|
|
||||||
|
v_label = TexMobject("\\vec{\\textbf{v}}")
|
||||||
|
v_label.vect = v_vect
|
||||||
|
w_label = TexMobject("\\vec{\\textbf{w}}")
|
||||||
|
w_label.vect = w_vect
|
||||||
|
for label in v_label, w_label:
|
||||||
|
label.match_color(label.vect)
|
||||||
|
label.set_stroke(BLACK, 5, background=True)
|
||||||
|
|
||||||
|
def update_label(label):
|
||||||
|
target = np.array(label.vect.get_end())
|
||||||
|
target += 0.25 * normalize(label.vect.get_vector())
|
||||||
|
label.move_to(target)
|
||||||
|
|
||||||
|
v_label.add_updater(update_label)
|
||||||
|
w_label.add_updater(update_label)
|
||||||
|
|
||||||
|
title = TexMobject(
|
||||||
|
"\\vec{\\textbf{w}}",
|
||||||
|
"\\cdot",
|
||||||
|
"\\vec{\\textbf{v}}",
|
||||||
|
"=",
|
||||||
|
"||", "\\vec{\\textbf{w}}", "||",
|
||||||
|
"\\cdot",
|
||||||
|
"||", "\\vec{\\textbf{v}}", "||",
|
||||||
|
"\\cdot",
|
||||||
|
"\\cos(\\theta)"
|
||||||
|
)
|
||||||
|
title.set_color_by_tex_to_color_map({
|
||||||
|
"textbf{v}": v_vect.get_color(),
|
||||||
|
"textbf{w}": w_vect.get_color(),
|
||||||
|
})
|
||||||
|
title.to_edge(UP)
|
||||||
|
|
||||||
|
def get_w_line():
|
||||||
|
center = dot.get_center()
|
||||||
|
direction = w_vect.get_vector()
|
||||||
|
return Line(
|
||||||
|
center - 3 * direction,
|
||||||
|
center + 3 * direction,
|
||||||
|
stroke_color=LIGHT_GREY,
|
||||||
|
stroke_width=1,
|
||||||
|
)
|
||||||
|
w_line = updating_mobject_from_func(get_w_line)
|
||||||
|
|
||||||
|
def get_proj_v():
|
||||||
|
center = dot.get_center()
|
||||||
|
v = v_vect.get_vector()
|
||||||
|
w = w_vect.get_vector()
|
||||||
|
w_unit = normalize(w)
|
||||||
|
result = Vector(np.dot(v, w_unit) * w_unit)
|
||||||
|
result.set_fill(v_vect.get_color(), 0.5)
|
||||||
|
result.shift(center - result.get_start())
|
||||||
|
return result
|
||||||
|
proj_v = updating_mobject_from_func(get_proj_v)
|
||||||
|
|
||||||
|
def get_proj_line():
|
||||||
|
return DashedLine(
|
||||||
|
v_vect.get_end(),
|
||||||
|
proj_v.get_end(),
|
||||||
|
stroke_width=1,
|
||||||
|
dashed_segment_length=0.025,
|
||||||
|
)
|
||||||
|
proj_line = updating_mobject_from_func(get_proj_line)
|
||||||
|
|
||||||
|
template_line = Line(LEFT, RIGHT)
|
||||||
|
|
||||||
|
def get_vect_brace(vect):
|
||||||
|
brace = Brace(template_line, UP, buff=SMALL_BUFF)
|
||||||
|
brace.set_width(vect.get_length(), stretch=True)
|
||||||
|
angle = vect.get_angle() % TAU
|
||||||
|
if angle < PI:
|
||||||
|
angle += PI
|
||||||
|
brace.rotate(angle, about_point=ORIGIN)
|
||||||
|
brace.shift(vect.get_center())
|
||||||
|
return brace
|
||||||
|
w_brace = updating_mobject_from_func(
|
||||||
|
lambda: get_vect_brace(w_vect)
|
||||||
|
)
|
||||||
|
proj_v_brace = updating_mobject_from_func(
|
||||||
|
lambda: get_vect_brace(proj_v)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_arc():
|
||||||
|
center = dot.get_center()
|
||||||
|
a1 = w_vect.get_angle()
|
||||||
|
a2 = v_vect.get_angle()
|
||||||
|
arc = Arc(
|
||||||
|
start_angle=a1,
|
||||||
|
angle=a2 - a1,
|
||||||
|
radius=0.5,
|
||||||
|
arc_center=center,
|
||||||
|
)
|
||||||
|
theta = TexMobject("\\theta")
|
||||||
|
p = arc.point_from_proportion(0.5)
|
||||||
|
theta.move_to(
|
||||||
|
center + 1.5 * (p - center)
|
||||||
|
)
|
||||||
|
return VGroup(arc, theta)
|
||||||
|
arc = updating_mobject_from_func(get_arc)
|
||||||
|
|
||||||
|
self.add(
|
||||||
|
title[:3],
|
||||||
|
w_vect, v_vect, dot,
|
||||||
|
w_label, v_label,
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
v_vect.angle_tracker.set_value, 170 * DEGREES,
|
||||||
|
w_vect.angle_tracker.set_value, 45 * DEGREES,
|
||||||
|
run_time=2,
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
w_brace.update()
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(w_brace),
|
||||||
|
Write(title[3:7])
|
||||||
|
)
|
||||||
|
|
||||||
|
self.add(w_line, w_vect, w_label, dot)
|
||||||
|
self.play(ShowCreation(w_line))
|
||||||
|
proj_v.update()
|
||||||
|
self.play(
|
||||||
|
ShowCreation(proj_line),
|
||||||
|
TransformFromCopy(v_vect, proj_v),
|
||||||
|
)
|
||||||
|
self.add(proj_v, proj_line, dot)
|
||||||
|
proj_v_brace.update()
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(proj_v_brace),
|
||||||
|
FadeInFromDown(title[7:])
|
||||||
|
)
|
||||||
|
arc.update()
|
||||||
|
self.play(Write(arc))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
for angle in [135, 225, 270, 90, 150]:
|
||||||
|
self.play(
|
||||||
|
v_vect.angle_tracker.set_value, angle * DEGREES,
|
||||||
|
run_time=2
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class FinalComment(Scene):
|
||||||
|
def construct(self):
|
||||||
|
self.add(TextMobject(
|
||||||
|
"Thoughts on what ending should go here?\\\\"
|
||||||
|
"See the Patreon post."
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
class FourtyFiveDegreeLine(Scene):
|
||||||
|
CONFIG = {
|
||||||
|
"angle": 45 * DEGREES,
|
||||||
|
"label_config": {
|
||||||
|
"num_decimal_places": 0,
|
||||||
|
"unit": "^\\circ",
|
||||||
|
"label_height": 0.3,
|
||||||
|
},
|
||||||
|
"degrees": True
|
||||||
|
}
|
||||||
|
|
||||||
|
def construct(self):
|
||||||
|
angle = self.angle
|
||||||
|
arc = Arc(angle, radius=1)
|
||||||
|
label = DecimalNumber(0, **self.label_config)
|
||||||
|
label.set_height(self.label_config["label_height"])
|
||||||
|
label.next_to(arc, RIGHT)
|
||||||
|
label.shift(0.5 * SMALL_BUFF * UP)
|
||||||
|
line1 = Line(ORIGIN, 3 * RIGHT)
|
||||||
|
line2 = line1.copy()
|
||||||
|
|
||||||
|
if self.degrees:
|
||||||
|
target_value = int(angle / DEGREES)
|
||||||
|
else:
|
||||||
|
target_value = angle
|
||||||
|
|
||||||
|
self.add(line1, label)
|
||||||
|
self.play(
|
||||||
|
ChangeDecimalToValue(label, target_value),
|
||||||
|
ShowCreation(arc),
|
||||||
|
Rotate(line2, angle, about_point=ORIGIN)
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class ArctanSqrtPoint1Angle(FourtyFiveDegreeLine):
|
||||||
|
CONFIG = {
|
||||||
|
"angle": np.arctan(np.sqrt(0.1)),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AskAboutAddingThetaToItself(Scene):
|
||||||
|
CONFIG = {
|
||||||
|
"theta": np.arctan(0.25),
|
||||||
|
"wait_time": 0.25,
|
||||||
|
"wedge_radius": 3,
|
||||||
|
"theta_symbol_scale_val": 0.5,
|
||||||
|
"number_height": 0.2,
|
||||||
|
}
|
||||||
|
|
||||||
|
def construct(self):
|
||||||
|
theta = self.theta
|
||||||
|
groups = self.get_groups(theta)
|
||||||
|
horizon = self.get_horizon()
|
||||||
|
counter = ValueTracker(0)
|
||||||
|
dynamic_ineq = self.get_dynamic_inequality(counter)
|
||||||
|
semicircle = self.get_semicircle()
|
||||||
|
|
||||||
|
self.add(horizon)
|
||||||
|
self.add(dynamic_ineq)
|
||||||
|
|
||||||
|
for n in range(len(groups)):
|
||||||
|
counter.set_value(n + 1)
|
||||||
|
if n < len(groups) - 1:
|
||||||
|
groups[n][-1].set_color(YELLOW)
|
||||||
|
if n > 0:
|
||||||
|
groups[n - 1][-1].set_color(WHITE)
|
||||||
|
self.add(groups[:n + 1])
|
||||||
|
self.add_sound("pen_click", gain=-20)
|
||||||
|
self.wait(self.wait_time)
|
||||||
|
self.wait(0.5)
|
||||||
|
|
||||||
|
counter.set_value(counter.get_value() - 1)
|
||||||
|
self.remove(groups[-1])
|
||||||
|
self.add_sound("pen_click", gain=-20)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
self.play(ShowCreation(semicircle))
|
||||||
|
self.play(FadeOut(semicircle))
|
||||||
|
|
||||||
|
self.wait(3)
|
||||||
|
|
||||||
|
def get_group(self, theta):
|
||||||
|
# Define group
|
||||||
|
wedge_radius = self.wedge_radius
|
||||||
|
wedge = VGroup(
|
||||||
|
Line(ORIGIN, wedge_radius * RIGHT),
|
||||||
|
Line(ORIGIN, wedge_radius * RIGHT).rotate(
|
||||||
|
theta, about_point=ORIGIN
|
||||||
|
),
|
||||||
|
)
|
||||||
|
wedge.set_stroke((WHITE, GREY), 2)
|
||||||
|
arc = Arc(theta, radius=1)
|
||||||
|
theta_symbol = TexMobject("\\theta")
|
||||||
|
tssv = self.theta_symbol_scale_val
|
||||||
|
theta_symbol.scale(tssv)
|
||||||
|
theta_symbol.next_to(arc, RIGHT, tssv / 2)
|
||||||
|
theta_symbol.shift(tssv * SMALL_BUFF * UP)
|
||||||
|
|
||||||
|
return VGroup(wedge, arc, theta_symbol)
|
||||||
|
|
||||||
|
def get_groups(self, theta):
|
||||||
|
group = self.get_group(theta)
|
||||||
|
angles = [k * theta for k in range(int(PI / theta) + 1)]
|
||||||
|
groups = VGroup(*[
|
||||||
|
group.copy().rotate(angle, about_point=ORIGIN)
|
||||||
|
for angle in angles
|
||||||
|
])
|
||||||
|
# colors = it.cycle([BLUE_D, BLUE_B, BLUE_C, GREY_BROWN])
|
||||||
|
colors = it.cycle([BLUE_D, GREY_BROWN])
|
||||||
|
for n, angle, group, color in zip(it.count(1), angles, groups, colors):
|
||||||
|
wedge, arc, symbol = group
|
||||||
|
symbol.rotate(-angle)
|
||||||
|
arc.set_color(color)
|
||||||
|
number = Integer(n)
|
||||||
|
number.set_height(self.number_height)
|
||||||
|
number.move_to(center_of_mass([
|
||||||
|
wedge[0].get_end(),
|
||||||
|
wedge[1].get_end(),
|
||||||
|
]))
|
||||||
|
group.add(number)
|
||||||
|
groups[-1][-1].set_color(RED)
|
||||||
|
|
||||||
|
return groups
|
||||||
|
|
||||||
|
def get_horizon(self):
|
||||||
|
horizon = DashedLine(5 * LEFT, 5 * RIGHT)
|
||||||
|
horizon.set_stroke(WHITE, 1)
|
||||||
|
return horizon
|
||||||
|
|
||||||
|
def get_semicircle(self):
|
||||||
|
return Arc(
|
||||||
|
start_angle=0,
|
||||||
|
angle=PI,
|
||||||
|
radius=self.wedge_radius / 2,
|
||||||
|
color=YELLOW,
|
||||||
|
stroke_width=4,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_inequality(self):
|
||||||
|
ineq = TexMobject(
|
||||||
|
"N", "\\cdot", "\\theta", "<",
|
||||||
|
"\\pi", "=", "3.1415926\\dots"
|
||||||
|
)
|
||||||
|
N = ineq.get_part_by_tex("N")
|
||||||
|
self.pi_symbol = ineq.get_part_by_tex("\\pi")
|
||||||
|
N.set_color(YELLOW)
|
||||||
|
# ineq[-3:].set_color(BLUE)
|
||||||
|
|
||||||
|
brace = Brace(N, UP, buff=SMALL_BUFF)
|
||||||
|
text = brace.get_text("Maximum", buff=SMALL_BUFF)
|
||||||
|
group = VGroup(ineq, brace, text)
|
||||||
|
group.next_to(ORIGIN, DOWN, MED_LARGE_BUFF)
|
||||||
|
return group
|
||||||
|
|
||||||
|
def get_dynamic_inequality(self, counter):
|
||||||
|
multiple = Integer(0)
|
||||||
|
dot = TexMobject("\\cdot")
|
||||||
|
theta_tex = TexMobject("({:.2f})".format(self.theta))
|
||||||
|
eq = TexMobject("=")
|
||||||
|
value = DecimalNumber(0)
|
||||||
|
ineq = TexMobject("<")
|
||||||
|
pi = TexMobject("\\pi", "=", "3.1415926\\dots")
|
||||||
|
# pi.set_color(BLUE)
|
||||||
|
group = VGroup(
|
||||||
|
multiple, dot, theta_tex,
|
||||||
|
eq, value,
|
||||||
|
ineq, pi
|
||||||
|
)
|
||||||
|
group.arrange_submobjects(RIGHT, buff=0.2)
|
||||||
|
group.next_to(ORIGIN, DOWN, buff=LARGE_BUFF)
|
||||||
|
theta_brace = Brace(group[2], DOWN, buff=SMALL_BUFF)
|
||||||
|
theta_symbol = theta_brace.get_tex("\\theta")
|
||||||
|
group.add(theta_brace, theta_symbol)
|
||||||
|
# group.align_to(self.pi_symbol, RIGHT)
|
||||||
|
|
||||||
|
def get_count():
|
||||||
|
return int(counter.get_value())
|
||||||
|
|
||||||
|
def get_product():
|
||||||
|
return get_count() * self.theta
|
||||||
|
|
||||||
|
def is_greater_than_pi():
|
||||||
|
return get_product() > PI
|
||||||
|
|
||||||
|
def get_color():
|
||||||
|
return RED if is_greater_than_pi() else YELLOW
|
||||||
|
|
||||||
|
def get_ineq():
|
||||||
|
result = TexMobject(
|
||||||
|
">" if is_greater_than_pi() else "<"
|
||||||
|
)
|
||||||
|
result.set_color(get_color())
|
||||||
|
result.move_to(ineq)
|
||||||
|
return result
|
||||||
|
dynamic_ineq = updating_mobject_from_func(get_ineq)
|
||||||
|
group.remove(ineq)
|
||||||
|
group.add(dynamic_ineq)
|
||||||
|
|
||||||
|
multiple.add_updater(lambda m: m.set_value(get_count()))
|
||||||
|
multiple.add_updater(lambda m: m.next_to(dot, LEFT, 0.2))
|
||||||
|
multiple.add_updater(lambda m: m.set_color(get_color()))
|
||||||
|
value.add_updater(lambda m: m.set_value(get_product()))
|
||||||
|
|
||||||
|
return group
|
||||||
|
|
||||||
|
|
||||||
|
class AskAboutAddingThetaToItselfThetaPoint1(AskAboutAddingThetaToItself):
|
||||||
|
CONFIG = {
|
||||||
|
"theta": 0.1,
|
||||||
|
"wait_time": 0.1,
|
||||||
|
"theta_symbol_scale_val": 0.25,
|
||||||
|
"number_height": 0.15,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AskAboutAddingThetaToItselfThetaPoint2(AskAboutAddingThetaToItself):
|
||||||
|
CONFIG = {
|
||||||
|
"theta": 0.2,
|
||||||
|
"wait_time": 0.1,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class FinalFormula(Scene):
|
||||||
|
def construct(self):
|
||||||
|
text = TextMobject("Final answer: ")
|
||||||
|
t2c_map = {
|
||||||
|
"\\theta": BLUE,
|
||||||
|
"m_1": GREEN,
|
||||||
|
"m_2": RED,
|
||||||
|
}
|
||||||
|
|
||||||
|
formula = TexMobject(
|
||||||
|
"\\left\\lfloor",
|
||||||
|
"{\\pi", "\\over", "\\theta}",
|
||||||
|
"\\right\\rfloor"
|
||||||
|
)
|
||||||
|
formula.set_color_by_tex_to_color_map(t2c_map)
|
||||||
|
group = VGroup(text, formula)
|
||||||
|
group.arrange_submobjects(RIGHT)
|
||||||
|
group.scale(1.5)
|
||||||
|
group.to_edge(UP)
|
||||||
|
|
||||||
|
self.play(Write(text))
|
||||||
|
self.play(FadeInFrom(formula))
|
||||||
|
self.play(ShowCreationThenFadeAround(formula))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
theta_eq = TexMobject(
|
||||||
|
"\\theta", "=", "\\arctan", "\\left(",
|
||||||
|
"\\sqrt",
|
||||||
|
"{{m_2", "\\over", "m_1}}",
|
||||||
|
"\\right)"
|
||||||
|
)
|
||||||
|
theta_eq.set_color_by_tex_to_color_map(t2c_map)
|
||||||
|
theta_eq.scale(1.5)
|
||||||
|
theta_eq.next_to(group, DOWN, MED_LARGE_BUFF)
|
||||||
|
|
||||||
|
self.play(TransformFromCopy(
|
||||||
|
formula.get_part_by_tex("\\theta"),
|
||||||
|
theta_eq.get_part_by_tex("\\theta"),
|
||||||
|
))
|
||||||
|
self.play(Write(theta_eq[1:]))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class ReviewWrapper(WrapperScene):
|
||||||
|
CONFIG = {"title": "To review:"}
|
||||||
|
|
||||||
|
|
||||||
|
class SurprisedRandy(Scene):
|
||||||
|
def construct(self):
|
||||||
|
randy = Randolph()
|
||||||
|
self.play(randy.change, "surprised", 3 * UR)
|
||||||
|
self.play(Blink(randy))
|
||||||
|
self.play(randy.change, "confused")
|
||||||
|
self.play(Blink(randy))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class TwoSolutionsWrapper(WrapperScene):
|
||||||
|
def construct(self):
|
||||||
|
big_rect = self.get_big_rect()
|
||||||
|
screen_rects = VGroup(*[
|
||||||
|
self.get_screen_rect(height=3)
|
||||||
|
for x in range(2)
|
||||||
|
])
|
||||||
|
screen_rects.arrange_submobjects(RIGHT, buff=LARGE_BUFF)
|
||||||
|
title = TextMobject("Two solutions")
|
||||||
|
title.scale(1.5)
|
||||||
|
title.to_edge(UP)
|
||||||
|
screen_rects.next_to(title, DOWN, LARGE_BUFF)
|
||||||
|
|
||||||
|
# pi creatures
|
||||||
|
pis = VGroup(
|
||||||
|
Randolph(color=BLUE_D),
|
||||||
|
Randolph(color=BLUE_E),
|
||||||
|
Randolph(color=BLUE_B),
|
||||||
|
Mortimer().scale(1.2)
|
||||||
|
)
|
||||||
|
pis.set_height(2)
|
||||||
|
pis.arrange_submobjects(RIGHT, buff=MED_LARGE_BUFF)
|
||||||
|
pis.to_edge(DOWN, buff=SMALL_BUFF)
|
||||||
|
|
||||||
|
self.add(big_rect, title, pis)
|
||||||
|
self.play(
|
||||||
|
LaggedStart(
|
||||||
|
ShowCreation, screen_rects.copy().set_fill(opacity=0),
|
||||||
|
lag_ratio=0.8
|
||||||
|
),
|
||||||
|
LaggedStart(
|
||||||
|
FadeIn, screen_rects,
|
||||||
|
lag_ratio=0.8
|
||||||
|
),
|
||||||
|
LaggedStart(
|
||||||
|
ApplyMethod, pis,
|
||||||
|
lambda pi: (pi.change, "pondering", screen_rects[0])
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.play(Blink(random.choice(pis)))
|
||||||
|
self.play(LaggedStart(
|
||||||
|
ApplyMethod, pis,
|
||||||
|
lambda pi: (pi.change, "thinking", screen_rects[1])
|
||||||
|
))
|
||||||
|
self.play(Blink(random.choice(pis)))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class FinalQuote(Scene):
|
||||||
|
def construct(self):
|
||||||
|
quote_text = """
|
||||||
|
A change of perspective\\\\
|
||||||
|
is worth 80 IQ points.
|
||||||
|
"""
|
||||||
|
quote_parts = [s for s in quote_text.split(" ") if s]
|
||||||
|
quote = TextMobject(
|
||||||
|
*quote_parts,
|
||||||
|
)
|
||||||
|
quote.scale(1.2)
|
||||||
|
quote.shift(2 * RIGHT + UP)
|
||||||
|
|
||||||
|
image = ImageMobject("AlanKay")
|
||||||
|
image.set_height(6)
|
||||||
|
image.to_corner(UL)
|
||||||
|
image.shift(2 * LEFT + 0.5 * UP)
|
||||||
|
name = TextMobject("Alan Kay")
|
||||||
|
name.scale(1.5)
|
||||||
|
name.next_to(image, DOWN)
|
||||||
|
name.shift_onto_screen()
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FadeInFromDown(image),
|
||||||
|
Write(name),
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
for word in quote:
|
||||||
|
self.play(ShowWord(word))
|
||||||
|
self.wait(0.005 * len(word)**1.5)
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class EndScreen(PatreonEndScreen):
|
||||||
|
CONFIG = {
|
||||||
|
"specific_patrons": [
|
||||||
|
"1stViewMaths",
|
||||||
|
"Adam Kozak",
|
||||||
|
"Adrian Robinson",
|
||||||
|
"Alexis Olson",
|
||||||
|
"Ali Yahya",
|
||||||
|
"Andreas Benjamin Brössel",
|
||||||
|
"Andrew Busey",
|
||||||
|
"Ankalagon",
|
||||||
|
"Antonio Juarez",
|
||||||
|
"Arjun Chakroborty",
|
||||||
|
"Art Ianuzzi",
|
||||||
|
"Arthur Zey",
|
||||||
|
"Awoo",
|
||||||
|
"Bernd Sing",
|
||||||
|
"Bob Sanderson",
|
||||||
|
"Boris Veselinovich",
|
||||||
|
"Brian Staroselsky",
|
||||||
|
"Britt Selvitelle",
|
||||||
|
"Burt Humburg",
|
||||||
|
"Chad Hurst",
|
||||||
|
"Charles Southerland",
|
||||||
|
"Chris Connett",
|
||||||
|
"Christian Kaiser",
|
||||||
|
"Clark Gaebel",
|
||||||
|
"Cooper Jones",
|
||||||
|
"D. Sivakumar",
|
||||||
|
"Danger Dai",
|
||||||
|
"Dave B",
|
||||||
|
"Dave Kester",
|
||||||
|
"dave nicponski",
|
||||||
|
"David Clark",
|
||||||
|
"David Gow",
|
||||||
|
"Delton Ding",
|
||||||
|
"Devarsh Desai",
|
||||||
|
"eaglle",
|
||||||
|
"emptymachine",
|
||||||
|
"Eric Younge",
|
||||||
|
"Eryq Ouithaqueue",
|
||||||
|
"Evan Phillips",
|
||||||
|
"Federico Lebron",
|
||||||
|
"Florian Chudigiewitsch",
|
||||||
|
"Giovanni Filippi",
|
||||||
|
"Graham",
|
||||||
|
"Hal Hildebrand",
|
||||||
|
"Hitoshi Yamauchi",
|
||||||
|
"J",
|
||||||
|
"j eduardo perez",
|
||||||
|
"Jacob Magnuson",
|
||||||
|
"Jameel Syed",
|
||||||
|
"James Hughes",
|
||||||
|
"Jan Pijpers",
|
||||||
|
"Jason Hise",
|
||||||
|
"Jeff Linse",
|
||||||
|
"Jeff Straathof",
|
||||||
|
"John Griffith",
|
||||||
|
"John Haley",
|
||||||
|
"John Shaughnessy",
|
||||||
|
"John V Wertheim",
|
||||||
|
"Jonathan Eppele",
|
||||||
|
"Jonathan Wilson",
|
||||||
|
"Jordan Scales",
|
||||||
|
"Joseph John Cox",
|
||||||
|
"Joseph Kelly",
|
||||||
|
"Juan Benet",
|
||||||
|
"Kai-Siang Ang",
|
||||||
|
"Kanan Gill",
|
||||||
|
"Kaustuv DeBiswas",
|
||||||
|
"L0j1k",
|
||||||
|
"Lee Redden",
|
||||||
|
"Linh Tran",
|
||||||
|
"Luc Ritchie",
|
||||||
|
"Ludwig Schubert",
|
||||||
|
"Lukas -krtek.net- Novy",
|
||||||
|
"Lukas Biewald",
|
||||||
|
"Magister Mugit",
|
||||||
|
"Magnus Dahlström",
|
||||||
|
"Magnus Lysfjord",
|
||||||
|
"Mark B Bahu",
|
||||||
|
"Mark Heising",
|
||||||
|
"Mathew Bramson",
|
||||||
|
"Mathias Jansson",
|
||||||
|
"Matt Langford",
|
||||||
|
"Matt Roveto",
|
||||||
|
"Matt Russell",
|
||||||
|
"Matthew Cocke",
|
||||||
|
"Mauricio Collares",
|
||||||
|
"Michael Faust",
|
||||||
|
"Michael Hardel",
|
||||||
|
"Mike Coleman",
|
||||||
|
"Mustafa Mahdi",
|
||||||
|
"Márton Vaitkus",
|
||||||
|
"Nathan Jessurun",
|
||||||
|
"Nero Li",
|
||||||
|
"Omar Zrien",
|
||||||
|
"Owen Campbell-Moore",
|
||||||
|
"Peter Ehrnstrom",
|
||||||
|
"Peter Mcinerney",
|
||||||
|
"Quantopian",
|
||||||
|
"Randy C. Will",
|
||||||
|
"Richard Barthel",
|
||||||
|
"Richard Burgmann",
|
||||||
|
"Richard Comish",
|
||||||
|
"Ripta Pasay",
|
||||||
|
"Rish Kundalia",
|
||||||
|
"Robert Teed",
|
||||||
|
"Roobie",
|
||||||
|
"Roy Larson",
|
||||||
|
"Ryan Atallah",
|
||||||
|
"Ryan Williams",
|
||||||
|
"Samuel D. Judge",
|
||||||
|
"Scott Gray",
|
||||||
|
"Scott Walter, Ph.D.",
|
||||||
|
"Sindre Reino Trosterud",
|
||||||
|
"soekul",
|
||||||
|
"Solara570",
|
||||||
|
"Song Gao",
|
||||||
|
"Stevie Metke",
|
||||||
|
"Ted Suzman",
|
||||||
|
"Tihan Seale",
|
||||||
|
"Valeriy Skobelev",
|
||||||
|
"Vassili Philippov",
|
||||||
|
"Xavier Bernard",
|
||||||
|
"Yana Chernobilsky",
|
||||||
|
"Yaw Etse",
|
||||||
|
"YinYangBalance.Asia",
|
||||||
|
"Yu Jun",
|
||||||
|
"Zach Cardwell",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ClacksSolution2Thumbnail(Scene):
|
||||||
|
def construct(self):
|
||||||
|
self.add_scene1()
|
||||||
|
self.add_scene2()
|
||||||
|
|
||||||
|
arrow = TexMobject("\\Updownarrow")
|
||||||
|
arrow.set_height(2)
|
||||||
|
arrow.set_color(YELLOW)
|
||||||
|
arrow.set_stroke(Color("red"), 2, background=True)
|
||||||
|
self.add(arrow)
|
||||||
|
|
||||||
|
def add_scene1(self):
|
||||||
|
scene1 = Thumbnail(
|
||||||
|
sliding_blocks_config={
|
||||||
|
"block1_config": {
|
||||||
|
"label_text": "$100^{d}$ kg",
|
||||||
|
"distance": 8,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
VGroup(*scene1.mobjects).shift(0.9 * DOWN)
|
||||||
|
scene1.remove(scene1.question)
|
||||||
|
self.add(*scene1.mobjects)
|
||||||
|
|
||||||
|
rect = FullScreenFadeRectangle(fill_opacity=1)
|
||||||
|
rect.shift(FRAME_HEIGHT * UP / 2)
|
||||||
|
self.add(rect)
|
||||||
|
|
||||||
|
def add_scene2(self):
|
||||||
|
scene2 = ReflectWorldThroughMirrorNew(
|
||||||
|
skip_animations=True,
|
||||||
|
file_writer_config={
|
||||||
|
"write_to_movie": False,
|
||||||
|
},
|
||||||
|
end_at_animation_number=18,
|
||||||
|
center=1.5 * UP,
|
||||||
|
)
|
||||||
|
worlds = VGroup(scene2.world, *scene2.reflected_worlds)
|
||||||
|
mirrors = VGroup(*[rw[1] for rw in worlds])
|
||||||
|
mirrors.set_stroke(width=5)
|
||||||
|
randys = VGroup(*[rw[-1] for rw in worlds])
|
||||||
|
triangles = VGroup(*[rw[0] for rw in worlds])
|
||||||
|
trajectories = VGroup(
|
||||||
|
scene2.trajectory,
|
||||||
|
*scene2.reflected_trajectories
|
||||||
|
)
|
||||||
|
trajectories.set_stroke(YELLOW, 1)
|
||||||
|
|
||||||
|
beams1, beams2 = [
|
||||||
|
scene2.get_shooting_beam_anims(
|
||||||
|
path,
|
||||||
|
max_stroke_width=20,
|
||||||
|
max_time_width=1,
|
||||||
|
num_flashes=50,
|
||||||
|
)
|
||||||
|
for path in [
|
||||||
|
scene2.trajectory,
|
||||||
|
scene2.ghost_trajectory,
|
||||||
|
]
|
||||||
|
]
|
||||||
|
beams = beams1 + beams2
|
||||||
|
beams = beams2
|
||||||
|
flashes = VGroup()
|
||||||
|
for beam in beams:
|
||||||
|
beam.update(0.5)
|
||||||
|
flashes.add(beam.mobject)
|
||||||
|
|
||||||
|
dot = Dot(color=YELLOW, radius=0.1)
|
||||||
|
dot.move_to(flashes[0].get_left())
|
||||||
|
flashes.add(dot)
|
||||||
|
|
||||||
|
self.add(mirrors, triangles, randys)
|
||||||
|
self.add(trajectories[0].set_stroke(width=3))
|
||||||
|
self.add(flashes)
|
|
@ -1,4 +1,5 @@
|
||||||
from big_ol_pile_of_manim_imports import *
|
from big_ol_pile_of_manim_imports import *
|
||||||
|
from old_projects.clacks.solution2.position_phase_space import ShowMomentumConservation
|
||||||
|
|
||||||
|
|
||||||
class ConnectionToOptics(Scene):
|
class ConnectionToOptics(Scene):
|
||||||
|
@ -145,7 +146,7 @@ class ConnectionToOptics(Scene):
|
||||||
title = VGroup(*map(TextMobject, [
|
title = VGroup(*map(TextMobject, [
|
||||||
"Angle of\\\\Incidence",
|
"Angle of\\\\Incidence",
|
||||||
"=",
|
"=",
|
||||||
"Angle of\\\\Refraction",
|
"Angle of\\\\Reflection",
|
||||||
])).arrange_submobjects(RIGHT)
|
])).arrange_submobjects(RIGHT)
|
||||||
title.set_color(YELLOW)
|
title.set_color(YELLOW)
|
||||||
h_line = Line(LEFT, RIGHT)
|
h_line = Line(LEFT, RIGHT)
|
||||||
|
@ -203,3 +204,115 @@ class ConnectionToOptics(Scene):
|
||||||
|
|
||||||
class ConnectionToOpticsTransparent(ConnectionToOptics):
|
class ConnectionToOpticsTransparent(ConnectionToOptics):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class RearrangeMomentumEquation(ShowMomentumConservation):
|
||||||
|
def setup(self):
|
||||||
|
pass # Don't build all the things
|
||||||
|
|
||||||
|
def construct(self):
|
||||||
|
self.add(FullScreenFadeRectangle(
|
||||||
|
fill_color=BLACK,
|
||||||
|
fill_opacity=0.95,
|
||||||
|
))
|
||||||
|
self.show_initial_dot_product()
|
||||||
|
self.show_with_x_and_y()
|
||||||
|
|
||||||
|
def show_initial_dot_product(self):
|
||||||
|
equation = self.get_momentum_equation()
|
||||||
|
dot_product = self.get_dot_product(
|
||||||
|
"m_1", "m_2", "v_1", "v_2"
|
||||||
|
)
|
||||||
|
dot_product.next_to(equation, DOWN, LARGE_BUFF)
|
||||||
|
m_array, dot, v_array, rhs = dot_product
|
||||||
|
m_array.get_entries().set_color(BLUE)
|
||||||
|
v_array.get_entries().set_color(RED)
|
||||||
|
|
||||||
|
self.add(equation)
|
||||||
|
self.play(FadeInFromDown(VGroup(
|
||||||
|
m_array.get_brackets(), dot,
|
||||||
|
v_array.get_brackets(), rhs,
|
||||||
|
)))
|
||||||
|
self.play(TransformFromCopy(
|
||||||
|
equation.get_parts_by_tex("m_"),
|
||||||
|
m_array.get_entries(),
|
||||||
|
))
|
||||||
|
self.play(TransformFromCopy(
|
||||||
|
equation.get_parts_by_tex("v_"),
|
||||||
|
v_array.get_entries(),
|
||||||
|
))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
self.simple_dot_product = dot_product
|
||||||
|
self.momentum_equation = equation
|
||||||
|
|
||||||
|
def show_with_x_and_y(self):
|
||||||
|
simple_dot_product = self.simple_dot_product
|
||||||
|
momentum_equation = self.momentum_equation
|
||||||
|
|
||||||
|
new_equation = TexMobject(
|
||||||
|
"\\sqrt{m_1}",
|
||||||
|
"\\left(", "\\sqrt{m_1}", "v_1", "\\right)",
|
||||||
|
"+", "\\sqrt{m_2}",
|
||||||
|
"\\left(", "\\sqrt{m_2}", "v_2", "\\right)",
|
||||||
|
"=", "\\text{const.}",
|
||||||
|
)
|
||||||
|
new_equation.set_color_by_tex_to_color_map({
|
||||||
|
"m_": BLUE,
|
||||||
|
"v_": RED,
|
||||||
|
})
|
||||||
|
new_equation.next_to(momentum_equation, DOWN, MED_LARGE_BUFF)
|
||||||
|
|
||||||
|
x_term = new_equation[1:5]
|
||||||
|
y_term = new_equation[7:11]
|
||||||
|
x_brace = Brace(x_term, DOWN)
|
||||||
|
y_brace = Brace(y_term, DOWN)
|
||||||
|
dx_dt = x_brace.get_tex("dx / dt")
|
||||||
|
dy_dt = y_brace.get_tex("dy / dt")
|
||||||
|
|
||||||
|
new_eq_group = VGroup(
|
||||||
|
new_equation, x_brace, y_brace, dx_dt, dy_dt
|
||||||
|
)
|
||||||
|
new_eq_group.generate_target()
|
||||||
|
|
||||||
|
new_dot_product = self.get_dot_product()
|
||||||
|
m_array, dot, d_array, rhs = new_dot_product
|
||||||
|
new_dot_product.next_to(momentum_equation, DOWN)
|
||||||
|
new_eq_group.target.next_to(new_dot_product, DOWN, LARGE_BUFF)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FadeInFrom(new_equation, UP),
|
||||||
|
simple_dot_product.to_edge, DOWN, LARGE_BUFF,
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(x_brace),
|
||||||
|
GrowFromCenter(y_brace),
|
||||||
|
FadeInFrom(dx_dt, UP),
|
||||||
|
FadeInFrom(dy_dt, UP),
|
||||||
|
)
|
||||||
|
self.wait()
|
||||||
|
self.play(
|
||||||
|
FadeIn(VGroup(
|
||||||
|
m_array.get_brackets(), dot,
|
||||||
|
d_array.get_brackets(), rhs
|
||||||
|
)),
|
||||||
|
MoveToTarget(new_eq_group)
|
||||||
|
)
|
||||||
|
self.play(TransformFromCopy(
|
||||||
|
VGroup(
|
||||||
|
VGroup(new_equation[0]),
|
||||||
|
VGroup(new_equation[6]),
|
||||||
|
),
|
||||||
|
m_array.get_entries(),
|
||||||
|
))
|
||||||
|
self.play(TransformFromCopy(
|
||||||
|
VGroup(dx_dt, dy_dt),
|
||||||
|
d_array.get_entries(),
|
||||||
|
))
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class NewSceneName(Scene):
|
||||||
|
def construct(self):
|
||||||
|
pass
|
|
@ -5,14 +5,17 @@ import sys
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
from manimlib.constants import PRODUCTION_QUALITY_CAMERA_CONFIG
|
from manimlib.constants import PRODUCTION_QUALITY_CAMERA_CONFIG
|
||||||
from manimlib.constants import PRODUCTION_QUALITY_FRAME_DURATION
|
from manimlib.constants import VIDEO_DIR
|
||||||
from manimlib.config import get_module
|
from manimlib.config import get_module
|
||||||
from manimlib.extract_scene import is_child_scene
|
from manimlib.extract_scene import is_child_scene
|
||||||
from manimlib.utils.file_ops import get_movie_output_directory
|
|
||||||
|
|
||||||
|
|
||||||
def get_sorted_scene_classes(module_name):
|
def get_sorted_scene_classes(module_name):
|
||||||
module = get_module(module_name)
|
module = get_module(module_name)
|
||||||
|
if hasattr(module, "ALL_SCENE_CLASSES"):
|
||||||
|
return module.ALL_SCENE_CLASSES
|
||||||
|
# Otherwise, deduce from the order in which
|
||||||
|
# they're defined in a file
|
||||||
importlib.import_module(module.__name__)
|
importlib.import_module(module.__name__)
|
||||||
line_to_scene = {}
|
line_to_scene = {}
|
||||||
name_scene_list = inspect.getmembers(
|
name_scene_list = inspect.getmembers(
|
||||||
|
@ -30,17 +33,19 @@ def get_sorted_scene_classes(module_name):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def stage_animations(module_name):
|
def stage_scenes(module_name):
|
||||||
scene_classes = get_sorted_scene_classes(module_name)
|
scene_classes = get_sorted_scene_classes(module_name)
|
||||||
if len(scene_classes) == 0:
|
if len(scene_classes) == 0:
|
||||||
print("There are no rendered animations from this module")
|
print("There are no rendered animations from this module")
|
||||||
return
|
return
|
||||||
output_directory_kwargs = {
|
# output_directory_kwargs = {
|
||||||
"camera_config": PRODUCTION_QUALITY_CAMERA_CONFIG,
|
# "camera_config": PRODUCTION_QUALITY_CAMERA_CONFIG,
|
||||||
}
|
# }
|
||||||
animation_dir = get_movie_output_directory(
|
# TODO, fix this
|
||||||
scene_classes[0], **output_directory_kwargs
|
animation_dir = os.path.join(
|
||||||
|
VIDEO_DIR, "clacks_solution2", "1440p60"
|
||||||
)
|
)
|
||||||
|
#
|
||||||
files = os.listdir(animation_dir)
|
files = os.listdir(animation_dir)
|
||||||
sorted_files = []
|
sorted_files = []
|
||||||
for scene_class in scene_classes:
|
for scene_class in scene_classes:
|
||||||
|
@ -92,4 +97,4 @@ if __name__ == "__main__":
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
raise Exception("No module given.")
|
raise Exception("No module given.")
|
||||||
module_name = sys.argv[1]
|
module_name = sys.argv[1]
|
||||||
stage_animations(module_name)
|
stage_scenes(module_name)
|
||||||
|
|
Loading…
Add table
Reference in a new issue