mirror of
https://github.com/3b1b/manim.git
synced 2025-08-21 05:44:04 +00:00
Setup for clacks solution2
This commit is contained in:
parent
3aadc1fb78
commit
acb5b2cfea
7 changed files with 138 additions and 88 deletions
|
@ -1,8 +0,0 @@
|
||||||
from active_projects import clacks
|
|
||||||
|
|
||||||
output_directory = "clacks_question"
|
|
||||||
all_scenes = [
|
|
||||||
clacks.NameIntro,
|
|
||||||
clacks.MathAndPhysicsConspiring,
|
|
||||||
clacks.LightBouncing,
|
|
||||||
]
|
|
|
@ -6,7 +6,7 @@ from active_projects.clacks.question import BlocksAndWallExample
|
||||||
|
|
||||||
class NameBump(BlocksAndWallExample):
|
class NameBump(BlocksAndWallExample):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"name": "Magnus Lysfjord",
|
"name": "Grant Sanderson",
|
||||||
"sliding_blocks_config": {
|
"sliding_blocks_config": {
|
||||||
"block1_config": {
|
"block1_config": {
|
||||||
"mass": 1e6,
|
"mass": 1e6,
|
||||||
|
|
|
@ -266,6 +266,7 @@ class Wall(Line):
|
||||||
class BlocksAndWallScene(Scene):
|
class BlocksAndWallScene(Scene):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"include_sound": True,
|
"include_sound": True,
|
||||||
|
"collision_sound": "clack.wav",
|
||||||
"count_clacks": True,
|
"count_clacks": True,
|
||||||
"counter_group_shift_vect": LEFT,
|
"counter_group_shift_vect": LEFT,
|
||||||
"sliding_blocks_config": {},
|
"sliding_blocks_config": {},
|
||||||
|
@ -273,7 +274,6 @@ class BlocksAndWallScene(Scene):
|
||||||
"wall_x": -6,
|
"wall_x": -6,
|
||||||
"n_wall_ticks": 15,
|
"n_wall_ticks": 15,
|
||||||
"counter_label": "\\# Collisions: ",
|
"counter_label": "\\# Collisions: ",
|
||||||
"collision_sound": "clack.wav",
|
|
||||||
"show_flash_animations": True,
|
"show_flash_animations": True,
|
||||||
"min_time_between_sounds": 0.004,
|
"min_time_between_sounds": 0.004,
|
||||||
}
|
}
|
||||||
|
@ -345,35 +345,30 @@ class BlocksAndWallScene(Scene):
|
||||||
return
|
return
|
||||||
self.counter_mob.set_value(n_clacks)
|
self.counter_mob.set_value(n_clacks)
|
||||||
|
|
||||||
def create_sound_file(self, clack_data):
|
def add_clack_sounds(self, clack_data):
|
||||||
clack_file = os.path.join(SOUND_DIR, self.collision_sound)
|
clack_file = self.collision_sound
|
||||||
output_file = self.get_movie_file_path(extension='.wav')
|
total_time = self.get_time()
|
||||||
times = [
|
times = [
|
||||||
time
|
time
|
||||||
for location, time in clack_data
|
for location, time in clack_data
|
||||||
if time < 300 # In case of any extremes
|
if time < total_time
|
||||||
]
|
]
|
||||||
|
last_time = 0
|
||||||
clack = AudioSegment.from_wav(clack_file)
|
|
||||||
total_time = max(times) + 1
|
|
||||||
clacks = AudioSegment.silent(int(1000 * total_time))
|
|
||||||
last_position = 0
|
|
||||||
min_diff = int(1000 * self.min_time_between_sounds)
|
|
||||||
for time in times:
|
for time in times:
|
||||||
position = int(1000 * time)
|
d_time = time - last_time
|
||||||
d_position = position - last_position
|
if d_time < self.min_time_between_sounds:
|
||||||
if d_position < min_diff:
|
|
||||||
continue
|
continue
|
||||||
if time > self.get_time():
|
last_time = time
|
||||||
break
|
self.add_sound(
|
||||||
last_position = position
|
clack_file,
|
||||||
clacks = clacks.fade(-50, start=position, end=position + 10)
|
time_offset=(time - total_time),
|
||||||
clacks = clacks.overlay(
|
gain=-20,
|
||||||
clack,
|
|
||||||
position=position
|
|
||||||
)
|
)
|
||||||
clacks.export(output_file, format="wav")
|
return self
|
||||||
return output_file
|
|
||||||
|
def tear_down(self):
|
||||||
|
if self.include_sound:
|
||||||
|
self.add_clack_sounds(self.clack_data)
|
||||||
|
|
||||||
# TODO, this no longer works
|
# TODO, this no longer works
|
||||||
# should use Scene.add_sound instead
|
# should use Scene.add_sound instead
|
||||||
|
@ -1573,6 +1568,7 @@ class Thumbnail(BlocksAndWallExample, MovingCameraScene):
|
||||||
"count_clacks": False,
|
"count_clacks": False,
|
||||||
"show_flash_animations": False,
|
"show_flash_animations": False,
|
||||||
"floor_y": -3.0,
|
"floor_y": -3.0,
|
||||||
|
"include_sound": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
|
@ -1580,7 +1576,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(
|
||||||
|
0,
|
||||||
|
FullScreenFadeRectangle(
|
||||||
|
color=DARK_GREY,
|
||||||
|
opacity=0.5,
|
||||||
|
sheen_direction=UL,
|
||||||
|
sheen=0.5,
|
||||||
|
),
|
||||||
|
)
|
||||||
self.thicken_lines()
|
self.thicken_lines()
|
||||||
self.grow_labels()
|
self.grow_labels()
|
||||||
self.add_vector()
|
self.add_vector()
|
||||||
|
|
15
active_projects/clacks/solution2.py
Normal file
15
active_projects/clacks/solution2.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
OUTPUT_DIRECTORY = "clacks_solution2"
|
||||||
|
ALL_SCENE_CLASSES = [
|
||||||
|
# question.Thumbnail,
|
||||||
|
# solution1.SolutionThumbnail,
|
||||||
|
# question.BlocksAndWallExampleMass1e2,
|
||||||
|
# question.BlocksAndWallExampleMass1e4,
|
||||||
|
block_collision_scenes.IntroducePreviousTwoVideos,
|
||||||
|
block_collision_scenes.PreviousTwoVideos,
|
||||||
|
simple_scenes.TwoSolutionsWrapper,
|
||||||
|
]
|
|
@ -6,58 +6,71 @@ class PreviousTwoVideos(BlocksAndWallExample):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"sliding_blocks_config": {
|
"sliding_blocks_config": {
|
||||||
"block1_config": {
|
"block1_config": {
|
||||||
"mass": 1e4,
|
"mass": 1e2,
|
||||||
"velocity": -2,
|
"velocity": -1,
|
||||||
"width": 3,
|
"width": 4,
|
||||||
|
"distance": 8,
|
||||||
},
|
},
|
||||||
"block2_config": {
|
"block2_config": {
|
||||||
"width": 3,
|
"width": 4,
|
||||||
|
"distance": 3,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"floor_y": -3,
|
||||||
"wait_time": 15,
|
"wait_time": 15,
|
||||||
}
|
}
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
videos = Group(
|
|
||||||
ImageMobject
|
|
||||||
)
|
|
||||||
|
|
||||||
name_mobs = VGroup(*map(TextMobject, names))
|
|
||||||
name_mobs.set_stroke(BLACK, 3, background=True)
|
|
||||||
name_mobs.set_fill(LIGHT_GREY, 1)
|
|
||||||
name_mobs.set_sheen(3, UL)
|
|
||||||
name_mobs.scale(2)
|
|
||||||
configs = [
|
|
||||||
self.sliding_blocks_config["block1_config"],
|
|
||||||
self.sliding_blocks_config["block2_config"],
|
|
||||||
]
|
|
||||||
for name_mob, config in zip(name_mobs, configs):
|
|
||||||
config["width"] = name_mob.get_width()
|
|
||||||
self.name_mobs = name_mobs
|
|
||||||
|
|
||||||
super().setup()
|
super().setup()
|
||||||
|
|
||||||
def add_blocks(self):
|
|
||||||
super().add_blocks()
|
|
||||||
blocks = self.blocks
|
blocks = self.blocks
|
||||||
name_mobs = self.name_mobs
|
videos = Group(
|
||||||
|
ImageMobject("ClacksSolution1Thumbnail"),
|
||||||
|
ImageMobject("ClacksQuestionThumbnail"),
|
||||||
|
)
|
||||||
|
for n, video, block in zip([2, 1], videos, blocks):
|
||||||
|
block.fade(1)
|
||||||
|
video.add(SurroundingRectangle(
|
||||||
|
video, buff=0,
|
||||||
|
color=BLUE,
|
||||||
|
stroke_width=3,
|
||||||
|
))
|
||||||
|
video.replace(block)
|
||||||
|
|
||||||
blocks.fade(1)
|
title = TextMobject("Part {}".format(n))
|
||||||
|
title.scale(1.5)
|
||||||
|
title.next_to(video, UP, MED_SMALL_BUFF)
|
||||||
|
video.add(title)
|
||||||
|
|
||||||
def update_name_mobs(name_mobs):
|
def update_videos(videos):
|
||||||
for name_mob, block in zip(name_mobs, self.blocks):
|
for video, block in zip(videos, blocks):
|
||||||
name_mob.move_to(block)
|
video.move_to(block, DOWN)
|
||||||
target_y = block.get_bottom()[1] + SMALL_BUFF
|
video.shift(0.04 * UP)
|
||||||
curr_y = name_mob[0].get_bottom()[1]
|
|
||||||
name_mob.shift((target_y - curr_y) * UP)
|
|
||||||
|
|
||||||
name_mobs.add_updater(update_name_mobs)
|
videos.add_updater(update_videos)
|
||||||
self.add(name_mobs)
|
self.add(videos)
|
||||||
|
if self.show_flash_animations:
|
||||||
|
self.add(self.clack_flashes.mobject)
|
||||||
|
self.videos = videos
|
||||||
|
|
||||||
clack_y = self.name_mobs[1].get_center()[1]
|
|
||||||
for location, time in self.clack_data:
|
|
||||||
location[1] = clack_y
|
|
||||||
|
|
||||||
for block, name_mob in zip(blocks, name_mobs):
|
class IntroducePreviousTwoVideos(PreviousTwoVideos):
|
||||||
block.label.next_to(name_mob, UP)
|
CONFIG = {
|
||||||
block.label.set_fill(YELLOW, opacity=1)
|
"show_flash_animations": False,
|
||||||
|
"include_sound": False,
|
||||||
|
}
|
||||||
|
|
||||||
|
def construct(self):
|
||||||
|
blocks = self.blocks
|
||||||
|
videos = self.videos
|
||||||
|
|
||||||
|
self.remove(blocks)
|
||||||
|
videos.clear_updaters()
|
||||||
|
self.remove(videos)
|
||||||
|
|
||||||
|
self.play(FadeInFromLarge(videos[1]))
|
||||||
|
self.play(TransformFromCopy(
|
||||||
|
videos[0].copy().fade(1).shift(2 * RIGHT),
|
||||||
|
videos[0],
|
||||||
|
rate_func=lambda t: rush_into(t, 3),
|
||||||
|
))
|
||||||
|
# self.wait()
|
||||||
|
|
|
@ -1,17 +1,48 @@
|
||||||
from big_ol_pile_of_manim_imports import *
|
from big_ol_pile_of_manim_imports import *
|
||||||
from active_projects.clacks.question import BlocksAndWallExample
|
|
||||||
|
|
||||||
|
|
||||||
class PreviousTwoVideos(BlocksAndWallExample):
|
class TwoSolutionsWrapper(Scene):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"sliding_blocks_config": {
|
|
||||||
"block1_config": {
|
|
||||||
"mass": 1e0,
|
|
||||||
"velocity": -2,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"wait_time": 15,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def construct(self):
|
def construct(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectionToOptics(Scene):
|
||||||
|
def construct(self):
|
||||||
|
e_group, m_group = k_groups = self.get_kinematics_groups()
|
||||||
|
|
||||||
|
self.add(k_groups)
|
||||||
|
|
||||||
|
def get_kinematics_groups(self):
|
||||||
|
tex_to_color_map = {
|
||||||
|
"m_1": BLUE,
|
||||||
|
"m_2": BLUE,
|
||||||
|
"v_1": RED,
|
||||||
|
"v_2": RED,
|
||||||
|
}
|
||||||
|
energy_eq = TexMobject(
|
||||||
|
"\\frac{1}{2} m_1 (v_1)^2 + "
|
||||||
|
"\\frac{1}{2} m_2 (v_2)^2 = "
|
||||||
|
"\\text{const.}",
|
||||||
|
tex_to_color_map=tex_to_color_map
|
||||||
|
)
|
||||||
|
momentum_eq = TexMobject(
|
||||||
|
"m_1 v_1 + m_2 v_2 = \\text{const.}",
|
||||||
|
tex_to_color_map=tex_to_color_map
|
||||||
|
)
|
||||||
|
energy_label = TextMobject(
|
||||||
|
"Conservation of energy"
|
||||||
|
)
|
||||||
|
momentum_label = TextMobject(
|
||||||
|
"Conservation of momentum"
|
||||||
|
)
|
||||||
|
energy_group = VGroup(energy_eq, energy_label)
|
||||||
|
momentum_group = VGroup(momentum_eq, momentum_label)
|
||||||
|
groups = VGroup(energy_group, momentum_group)
|
||||||
|
for group in groups:
|
||||||
|
group.arrange_submobjects(DOWN)
|
||||||
|
groups.arrange_submobjects(DOWN, LARGE_BUFF)
|
||||||
|
groups.to_edge(LEFT)
|
||||||
|
return groups
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
from active_projects.clacks.solution2 import block_collision_scenes
|
|
||||||
|
|
||||||
OUTPUT_DIRECTORY = "clacks_solution2"
|
|
||||||
ALL_SCENE_CLASSES = [
|
|
||||||
block_collision_scenes.PreviousTwoVideos
|
|
||||||
]
|
|
Loading…
Add table
Reference in a new issue