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)
|
||||
assert(isinstance(mobject, Mobject))
|
||||
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()
|
||||
if self.rate_func is None:
|
||||
self.rate_func = (lambda x: x)
|
||||
|
|
|
@ -5,7 +5,6 @@ from manimlib.animation.transform import Transform
|
|||
from manimlib.constants import *
|
||||
from manimlib.mobject.svg.tex_mobject import TextMobject
|
||||
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.config_ops import digest_config
|
||||
from manimlib.utils.paths import counterclockwise_path
|
||||
|
|
|
@ -44,7 +44,7 @@ class Rotate(Transform):
|
|||
if "path_arc_axis" not in kwargs:
|
||||
kwargs["path_arc_axis"] = axis
|
||||
digest_config(self, kwargs, locals())
|
||||
target = mobject.copy()
|
||||
target = mobject.deepcopy()
|
||||
if self.in_place:
|
||||
self.about_point = mobject.get_center()
|
||||
target.rotate(
|
||||
|
|
|
@ -29,8 +29,10 @@ class Transform(Animation):
|
|||
# Copy target_mobject so as to not mess with caller
|
||||
self.original_target_mobject = target_mobject
|
||||
target_mobject = target_mobject.copy()
|
||||
mobject.align_data(target_mobject)
|
||||
target_mobject.update()
|
||||
self.target_mobject = target_mobject
|
||||
|
||||
mobject.align_data(target_mobject)
|
||||
digest_config(self, kwargs)
|
||||
self.init_path_func()
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class Camera(object):
|
|||
"background_image": None,
|
||||
"pixel_height": DEFAULT_PIXEL_HEIGHT,
|
||||
"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
|
||||
# the pixel aspect ratio
|
||||
"frame_height": FRAME_HEIGHT,
|
||||
|
|
|
@ -109,7 +109,7 @@ LOW_QUALITY_CAMERA_CONFIG = {
|
|||
|
||||
DEFAULT_PIXEL_HEIGHT = PRODUCTION_QUALITY_CAMERA_CONFIG["pixel_height"]
|
||||
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_1D = 250
|
||||
|
|
|
@ -307,6 +307,7 @@ class Banner(Scene):
|
|||
"date": "Sunday, February 3rd",
|
||||
"message_scale_val": 0.9,
|
||||
"add_supporter_note": False,
|
||||
"pre_date_text": "Next video on ",
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
@ -363,7 +364,8 @@ class Banner(Scene):
|
|||
|
||||
def get_date_message(self):
|
||||
return TextMobject(
|
||||
"Next video on ", self.date,
|
||||
self.pre_date_text,
|
||||
self.date,
|
||||
tex_to_color_map={self.date: YELLOW},
|
||||
)
|
||||
|
||||
|
|
|
@ -403,10 +403,11 @@ class Line(VMobject):
|
|||
start, end = self.get_start_and_end()
|
||||
return angle_of_vector(end - start)
|
||||
|
||||
# def put_start_and_end_on(self, new_start, new_end):
|
||||
# self.set_start_and_end(new_start, new_end)
|
||||
# self.buff = 0
|
||||
# self.generate_points()
|
||||
def set_angle(self, angle):
|
||||
self.rotate(
|
||||
angle - self.get_angle(),
|
||||
about_point=self.get_start(),
|
||||
)
|
||||
|
||||
def put_start_and_end_on(self, new_start, new_end):
|
||||
self.start = new_start
|
||||
|
|
|
@ -125,6 +125,7 @@ class Mobject(Container):
|
|||
copy_mobject.submobjects = [
|
||||
submob.copy() for submob in self.submobjects
|
||||
]
|
||||
copy_mobject.updaters = list(self.updaters)
|
||||
family = self.get_family()
|
||||
for attr, value in list(self.__dict__.items()):
|
||||
if isinstance(value, Mobject) and value in family and value is not self:
|
||||
|
@ -147,13 +148,14 @@ class Mobject(Container):
|
|||
# Updating
|
||||
|
||||
def update(self, dt=0, recursive=True):
|
||||
if not self.updating_suspended:
|
||||
for updater in self.updaters:
|
||||
parameters = get_parameters(updater)
|
||||
if "dt" in parameters:
|
||||
updater(self, dt)
|
||||
else:
|
||||
updater(self)
|
||||
if self.updating_suspended:
|
||||
return self
|
||||
for updater in self.updaters:
|
||||
parameters = get_parameters(updater)
|
||||
if "dt" in parameters:
|
||||
updater(self, dt)
|
||||
else:
|
||||
updater(self)
|
||||
if recursive:
|
||||
for submob in self.submobjects:
|
||||
submob.update(dt, recursive)
|
||||
|
@ -182,8 +184,11 @@ class Mobject(Container):
|
|||
self.updaters.remove(update_function)
|
||||
return self
|
||||
|
||||
def clear_updaters(self):
|
||||
def clear_updaters(self, recursive=True):
|
||||
self.updaters = []
|
||||
if recursive:
|
||||
for submob in self.submobjects:
|
||||
submob.clear_updaters()
|
||||
return self
|
||||
|
||||
def suspend_updating(self, recursive=True):
|
||||
|
|
|
@ -32,9 +32,9 @@ class VMobject(Mobject):
|
|||
"background_stroke_width": 0,
|
||||
# When a color c is set, there will be a second color
|
||||
# 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.
|
||||
"sheen": 0.0,
|
||||
"sheen_factor": 0.0,
|
||||
"sheen_direction": UL,
|
||||
# Indicates that it will not be displayed, but
|
||||
# that it should count in parent mobject's path
|
||||
|
@ -71,7 +71,7 @@ class VMobject(Mobject):
|
|||
family=self.propagate_style_to_family,
|
||||
)
|
||||
self.set_sheen(
|
||||
factor=self.sheen,
|
||||
factor=self.sheen_factor,
|
||||
direction=self.sheen_direction,
|
||||
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.
|
||||
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
|
||||
will automatically be added for the gradient
|
||||
"""
|
||||
|
@ -92,10 +92,10 @@ class VMobject(Mobject):
|
|||
for c, o in zip(*make_even(colors, opacities))
|
||||
])
|
||||
|
||||
sheen = self.get_sheen()
|
||||
if sheen != 0 and len(rgbas) == 1:
|
||||
sheen_factor = self.get_sheen_factor()
|
||||
if sheen_factor != 0 and len(rgbas) == 1:
|
||||
light_rgbas = np.array(rgbas)
|
||||
light_rgbas[:, :3] += sheen
|
||||
light_rgbas[:, :3] += sheen_factor
|
||||
clip_in_place(light_rgbas, 0, 1)
|
||||
rgbas = np.append(rgbas, light_rgbas, axis=0)
|
||||
return rgbas
|
||||
|
@ -160,8 +160,10 @@ class VMobject(Mobject):
|
|||
fill_opacity=None,
|
||||
stroke_color=None,
|
||||
stroke_width=None,
|
||||
stroke_opacity=None,
|
||||
background_stroke_color=None,
|
||||
background_stroke_width=None,
|
||||
background_stroke_opacity=None,
|
||||
sheen_factor=None,
|
||||
sheen_direction=None,
|
||||
background_image_file=None,
|
||||
|
@ -174,11 +176,13 @@ class VMobject(Mobject):
|
|||
self.set_stroke(
|
||||
color=stroke_color,
|
||||
width=stroke_width,
|
||||
opacity=stroke_opacity,
|
||||
family=family,
|
||||
)
|
||||
self.set_background_stroke(
|
||||
color=background_stroke_color,
|
||||
width=background_stroke_width,
|
||||
opacity=background_stroke_opacity,
|
||||
family=family,
|
||||
)
|
||||
if sheen_factor:
|
||||
|
@ -198,7 +202,7 @@ class VMobject(Mobject):
|
|||
"stroke_width": self.get_stroke_width(),
|
||||
"background_stroke_color": self.get_stroke_colors(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(),
|
||||
"background_image_file": self.get_background_image_file(),
|
||||
}
|
||||
|
@ -309,12 +313,12 @@ class VMobject(Mobject):
|
|||
if family:
|
||||
for submob in self.submobjects:
|
||||
submob.set_sheen(factor, direction, family)
|
||||
self.sheen = factor
|
||||
self.sheen_factor = factor
|
||||
if direction is not None:
|
||||
# family set to false because recursion will
|
||||
# already be handled above
|
||||
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:
|
||||
self.set_stroke(self.get_stroke_color(), family=family)
|
||||
self.set_fill(self.get_fill_color(), family=family)
|
||||
|
@ -323,8 +327,8 @@ class VMobject(Mobject):
|
|||
def get_sheen_direction(self):
|
||||
return np.array(self.sheen_direction)
|
||||
|
||||
def get_sheen(self):
|
||||
return self.sheen
|
||||
def get_sheen_factor(self):
|
||||
return self.sheen_factor
|
||||
|
||||
def get_gradient_start_and_end_points(self):
|
||||
if self.shade_in_3d:
|
||||
|
@ -613,7 +617,7 @@ class VMobject(Mobject):
|
|||
"stroke_width",
|
||||
"background_stroke_width",
|
||||
"sheen_direction",
|
||||
"sheen",
|
||||
"sheen_factor",
|
||||
]
|
||||
for attr in attrs:
|
||||
setattr(self, attr, interpolate(
|
||||
|
@ -694,7 +698,7 @@ class VectorizedPoint(VMobject):
|
|||
return self.artificial_height
|
||||
|
||||
def get_location(self):
|
||||
return self.points[0]
|
||||
return np.array(self.points[0])
|
||||
|
||||
def set_location(self, new_loc):
|
||||
self.set_points(np.array([new_loc]))
|
||||
|
|
|
@ -528,6 +528,7 @@ class Scene(Container):
|
|||
@handle_play_like_call
|
||||
def wait(self, duration=DEFAULT_WAIT_TIME, stop_condition=None):
|
||||
dt = 1 / self.camera.frame_rate
|
||||
self.continual_update(dt=0) # Any problems with this?
|
||||
if self.should_continually_update():
|
||||
time_progression = self.get_wait_time_progression(duration, stop_condition)
|
||||
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
|
||||
from big_ol_pile_of_manim_imports import *
|
||||
|
||||
from active_projects.clacks.question import BlocksAndWallExample
|
||||
from old_projects.clacks.question import BlocksAndWallExample
|
||||
|
||||
|
||||
class NameBump(BlocksAndWallExample):
|
|
@ -13,7 +13,7 @@ class Block(Square):
|
|||
"stroke_color": WHITE,
|
||||
"fill_color": None,
|
||||
"sheen_direction": UL,
|
||||
"sheen": 0.5,
|
||||
"sheen_factor": 0.5,
|
||||
"sheen_direction": UL,
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ class Block(Square):
|
|||
def mass_to_color(self, mass):
|
||||
colors = [
|
||||
LIGHT_GREY,
|
||||
BLUE_B,
|
||||
BLUE_D,
|
||||
BLUE_D,
|
||||
BLUE_E,
|
||||
BLUE_E,
|
||||
|
@ -225,7 +225,7 @@ class ClackFlashes(ContinualAnimation):
|
|||
ContinualAnimation.__init__(self, group, **kwargs)
|
||||
|
||||
def update_mobject(self, dt):
|
||||
total_time = self.external_time
|
||||
total_time = self.get_time()
|
||||
group = self.mobject
|
||||
for flash in self.flashes:
|
||||
if flash.start_time < total_time < flash.end_time:
|
||||
|
@ -238,6 +238,9 @@ class ClackFlashes(ContinualAnimation):
|
|||
if flash.mobject in group:
|
||||
group.remove(flash.mobject)
|
||||
|
||||
def get_time(self):
|
||||
return self.external_time
|
||||
|
||||
|
||||
class Wall(Line):
|
||||
CONFIG = {
|
||||
|
@ -410,6 +413,10 @@ class NameIntro(Scene):
|
|||
rate_func=None,
|
||||
)
|
||||
)
|
||||
self.play(
|
||||
Flash(brown.get_right(), run_time=flash_time),
|
||||
Restore(brown, rate_func=None)
|
||||
)
|
||||
|
||||
|
||||
class MathAndPhysicsConspiring(Scene):
|
||||
|
@ -1558,16 +1565,16 @@ class Thumbnail(BlocksAndWallExample, MovingCameraScene):
|
|||
BlocksAndWallExample.setup(self)
|
||||
|
||||
def construct(self):
|
||||
# self.camera_frame.shift(0.9 * UP)
|
||||
self.mobjects.insert(
|
||||
0,
|
||||
FullScreenFadeRectangle(
|
||||
color=DARK_GREY,
|
||||
opacity=0.5,
|
||||
sheen_direction=UL,
|
||||
sheen=0.5,
|
||||
),
|
||||
)
|
||||
self.camera_frame.shift(0.9 * UP)
|
||||
# self.mobjects.insert(
|
||||
# 0,
|
||||
# FullScreenFadeRectangle(
|
||||
# color=DARK_GREY,
|
||||
# opacity=0.5,
|
||||
# sheen_direction=UL,
|
||||
# sheen=0.5,
|
||||
# ),
|
||||
# )
|
||||
self.thicken_lines()
|
||||
self.grow_labels()
|
||||
self.add_vector()
|
||||
|
@ -1587,7 +1594,7 @@ class Thumbnail(BlocksAndWallExample, MovingCameraScene):
|
|||
|
||||
def add_vector(self):
|
||||
blocks = self.blocks
|
||||
arrow = Vector(
|
||||
arrow = self.arrow = Vector(
|
||||
2.5 * LEFT,
|
||||
color=RED,
|
||||
rectangular_stem_width=1.5,
|
||||
|
@ -1600,7 +1607,9 @@ class Thumbnail(BlocksAndWallExample, MovingCameraScene):
|
|||
self.add(arrow)
|
||||
|
||||
def add_text(self):
|
||||
question = TextMobject("How many\\\\collisions?")
|
||||
question = self.question = TextMobject(
|
||||
"How many\\\\collisions?"
|
||||
)
|
||||
question.scale(2.5)
|
||||
question.to_edge(UP)
|
||||
question.set_color(YELLOW)
|
|
@ -1,5 +1,5 @@
|
|||
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
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
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):
|
||||
|
@ -7,7 +7,7 @@ class PreviousTwoVideos(BlocksAndWallExample):
|
|||
"sliding_blocks_config": {
|
||||
"block1_config": {
|
||||
"mass": 1e2,
|
||||
"velocity": -1,
|
||||
"velocity": -2,
|
||||
"width": 4,
|
||||
"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):
|
||||
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):
|
||||
|
@ -76,3 +85,34 @@ class ComplainAboutRelevanceOfAnalogy(TeacherStudentsScene):
|
|||
self.hold_up_spot + UP,
|
||||
)
|
||||
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 old_projects.clacks.solution2.position_phase_space import ShowMomentumConservation
|
||||
|
||||
|
||||
class ConnectionToOptics(Scene):
|
||||
|
@ -145,7 +146,7 @@ class ConnectionToOptics(Scene):
|
|||
title = VGroup(*map(TextMobject, [
|
||||
"Angle of\\\\Incidence",
|
||||
"=",
|
||||
"Angle of\\\\Refraction",
|
||||
"Angle of\\\\Reflection",
|
||||
])).arrange_submobjects(RIGHT)
|
||||
title.set_color(YELLOW)
|
||||
h_line = Line(LEFT, RIGHT)
|
||||
|
@ -203,3 +204,115 @@ class ConnectionToOptics(Scene):
|
|||
|
||||
class ConnectionToOpticsTransparent(ConnectionToOptics):
|
||||
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
|
||||
|
||||
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.extract_scene import is_child_scene
|
||||
from manimlib.utils.file_ops import get_movie_output_directory
|
||||
|
||||
|
||||
def get_sorted_scene_classes(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__)
|
||||
line_to_scene = {}
|
||||
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)
|
||||
if len(scene_classes) == 0:
|
||||
print("There are no rendered animations from this module")
|
||||
return
|
||||
output_directory_kwargs = {
|
||||
"camera_config": PRODUCTION_QUALITY_CAMERA_CONFIG,
|
||||
}
|
||||
animation_dir = get_movie_output_directory(
|
||||
scene_classes[0], **output_directory_kwargs
|
||||
# output_directory_kwargs = {
|
||||
# "camera_config": PRODUCTION_QUALITY_CAMERA_CONFIG,
|
||||
# }
|
||||
# TODO, fix this
|
||||
animation_dir = os.path.join(
|
||||
VIDEO_DIR, "clacks_solution2", "1440p60"
|
||||
)
|
||||
#
|
||||
files = os.listdir(animation_dir)
|
||||
sorted_files = []
|
||||
for scene_class in scene_classes:
|
||||
|
@ -92,4 +97,4 @@ if __name__ == "__main__":
|
|||
if len(sys.argv) < 2:
|
||||
raise Exception("No module given.")
|
||||
module_name = sys.argv[1]
|
||||
stage_animations(module_name)
|
||||
stage_scenes(module_name)
|
||||
|
|
Loading…
Add table
Reference in a new issue