diff --git a/active_projects/clacks/all_questions_scenes.py b/active_projects/clacks/all_questions_scenes.py deleted file mode 100644 index c29d03ce..00000000 --- a/active_projects/clacks/all_questions_scenes.py +++ /dev/null @@ -1,8 +0,0 @@ -from active_projects import clacks - -output_directory = "clacks_question" -all_scenes = [ - clacks.NameIntro, - clacks.MathAndPhysicsConspiring, - clacks.LightBouncing, -] diff --git a/active_projects/clacks/name_bump.py b/active_projects/clacks/name_bump.py index e7972b53..cd79392d 100644 --- a/active_projects/clacks/name_bump.py +++ b/active_projects/clacks/name_bump.py @@ -6,7 +6,7 @@ from active_projects.clacks.question import BlocksAndWallExample class NameBump(BlocksAndWallExample): CONFIG = { - "name": "Magnus Lysfjord", + "name": "Grant Sanderson", "sliding_blocks_config": { "block1_config": { "mass": 1e6, diff --git a/active_projects/clacks/question.py b/active_projects/clacks/question.py index 17dab588..acefc690 100644 --- a/active_projects/clacks/question.py +++ b/active_projects/clacks/question.py @@ -266,6 +266,7 @@ class Wall(Line): class BlocksAndWallScene(Scene): CONFIG = { "include_sound": True, + "collision_sound": "clack.wav", "count_clacks": True, "counter_group_shift_vect": LEFT, "sliding_blocks_config": {}, @@ -273,7 +274,6 @@ class BlocksAndWallScene(Scene): "wall_x": -6, "n_wall_ticks": 15, "counter_label": "\\# Collisions: ", - "collision_sound": "clack.wav", "show_flash_animations": True, "min_time_between_sounds": 0.004, } @@ -345,35 +345,30 @@ class BlocksAndWallScene(Scene): return self.counter_mob.set_value(n_clacks) - def create_sound_file(self, clack_data): - clack_file = os.path.join(SOUND_DIR, self.collision_sound) - output_file = self.get_movie_file_path(extension='.wav') + def add_clack_sounds(self, clack_data): + clack_file = self.collision_sound + total_time = self.get_time() times = [ time for location, time in clack_data - if time < 300 # In case of any extremes + if time < total_time ] - - 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) + last_time = 0 for time in times: - position = int(1000 * time) - d_position = position - last_position - if d_position < min_diff: + d_time = time - last_time + if d_time < self.min_time_between_sounds: continue - if time > self.get_time(): - break - last_position = position - clacks = clacks.fade(-50, start=position, end=position + 10) - clacks = clacks.overlay( - clack, - position=position + last_time = time + self.add_sound( + clack_file, + time_offset=(time - total_time), + gain=-20, ) - clacks.export(output_file, format="wav") - return output_file + return self + + def tear_down(self): + if self.include_sound: + self.add_clack_sounds(self.clack_data) # TODO, this no longer works # should use Scene.add_sound instead @@ -1573,6 +1568,7 @@ class Thumbnail(BlocksAndWallExample, MovingCameraScene): "count_clacks": False, "show_flash_animations": False, "floor_y": -3.0, + "include_sound": False, } def setup(self): @@ -1580,7 +1576,16 @@ class Thumbnail(BlocksAndWallExample, MovingCameraScene): BlocksAndWallExample.setup(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.grow_labels() self.add_vector() diff --git a/active_projects/clacks/solution2.py b/active_projects/clacks/solution2.py new file mode 100644 index 00000000..0e586de6 --- /dev/null +++ b/active_projects/clacks/solution2.py @@ -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, +] diff --git a/active_projects/clacks/solution2/block_collision_scenes.py b/active_projects/clacks/solution2/block_collision_scenes.py index 3a54fed5..b300087f 100644 --- a/active_projects/clacks/solution2/block_collision_scenes.py +++ b/active_projects/clacks/solution2/block_collision_scenes.py @@ -6,58 +6,71 @@ class PreviousTwoVideos(BlocksAndWallExample): CONFIG = { "sliding_blocks_config": { "block1_config": { - "mass": 1e4, - "velocity": -2, - "width": 3, + "mass": 1e2, + "velocity": -1, + "width": 4, + "distance": 8, }, "block2_config": { - "width": 3, + "width": 4, + "distance": 3, }, }, + "floor_y": -3, "wait_time": 15, } 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() - - def add_blocks(self): - super().add_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): - for name_mob, block in zip(name_mobs, self.blocks): - name_mob.move_to(block) - target_y = block.get_bottom()[1] + SMALL_BUFF - curr_y = name_mob[0].get_bottom()[1] - name_mob.shift((target_y - curr_y) * UP) + def update_videos(videos): + for video, block in zip(videos, blocks): + video.move_to(block, DOWN) + video.shift(0.04 * UP) - name_mobs.add_updater(update_name_mobs) - self.add(name_mobs) + videos.add_updater(update_videos) + 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): - block.label.next_to(name_mob, UP) - block.label.set_fill(YELLOW, opacity=1) +class IntroducePreviousTwoVideos(PreviousTwoVideos): + CONFIG = { + "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() diff --git a/active_projects/clacks/solution2/simple_scenes.py b/active_projects/clacks/solution2/simple_scenes.py index 955f5503..a4b6ef3b 100644 --- a/active_projects/clacks/solution2/simple_scenes.py +++ b/active_projects/clacks/solution2/simple_scenes.py @@ -1,17 +1,48 @@ from big_ol_pile_of_manim_imports import * -from active_projects.clacks.question import BlocksAndWallExample -class PreviousTwoVideos(BlocksAndWallExample): +class TwoSolutionsWrapper(Scene): CONFIG = { - "sliding_blocks_config": { - "block1_config": { - "mass": 1e0, - "velocity": -2, - } - }, - "wait_time": 15, } def construct(self): 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 diff --git a/active_projects/clacks_solution2.py b/active_projects/clacks_solution2.py deleted file mode 100644 index 6840c08d..00000000 --- a/active_projects/clacks_solution2.py +++ /dev/null @@ -1,6 +0,0 @@ -from active_projects.clacks.solution2 import block_collision_scenes - -OUTPUT_DIRECTORY = "clacks_solution2" -ALL_SCENE_CLASSES = [ - block_collision_scenes.PreviousTwoVideos -]