from manimlib.imports import * from old_projects.clacks.solution2.position_phase_space import ShowMomentumConservation class ConnectionToOptics(Scene): def construct(self): e_group, m_group = k_groups = self.get_kinematics_groups() c_group, a_group = o_groups = self.get_optics_groups() arrows = VGroup() for g1, g2 in zip(k_groups, o_groups): g2.align_to(g1, UP) g2.to_edge(RIGHT) arrow = TexMobject("\\Rightarrow") arrow.scale(1.5) arrow.move_to(interpolate( g1[0].get_right(), g2[0].get_left(), 0.5 )) arrows.add(arrow) everything = VGroup(k_groups, arrows, o_groups) everything.to_edge(UP) everything.generate_target() everything.target.scale(0.9) everything.target.to_edge(DOWN) width = max([m.get_width() for m in everything.target]) width += 2 * MED_SMALL_BUFF rects = VGroup() for k in [0, 2]: rect = DashedVMobject(Rectangle( height=FRAME_HEIGHT - 1.5, width=width ), num_dashes=100) rect.move_to(everything.target[k]) rect.to_edge(DOWN, buff=SMALL_BUFF) rects.add(rect) titles = VGroup( TextMobject("Kinematics"), TextMobject("Optics"), ) titles.scale(1.5) for title, rect in zip(titles, rects): title.next_to(rect, UP) titles[0].align_to(titles[1], UP) self.play(FadeInFromDown(e_group)) self.play( Write(arrows[0]), FadeInFrom(c_group, LEFT) ) self.wait() self.play(FadeInFromDown(m_group)) self.play( Write(arrows[1]), FadeInFrom(a_group, LEFT) ) self.wait(4) for k in range(2): anims = [ ShowCreation(rects[k]), FadeInFromDown(titles[k]), ] if k == 0: anims.append(MoveToTarget(everything)) self.play(*anims) self.wait() self.wait() self.wait(4) 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 ) energy_eq.scale(0.8) 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_label, energy_eq) momentum_group = VGroup(momentum_label, momentum_eq) groups = VGroup(energy_group, momentum_group) for group in groups: group.arrange(DOWN, buff=MED_LARGE_BUFF) group[0].set_color(GREEN) groups.arrange(DOWN, buff=2) groups.to_edge(LEFT) return groups def get_optics_groups(self): self.time_tracker = ValueTracker(0) self.time_tracker.add_updater( lambda m, dt: m.increment_value(dt) ) self.add(self.time_tracker) return VGroup( self.get_speed_group(), self.get_angle_group() ) def get_speed_group(self): speed_label = TextMobject("Constant speed of light") speed_label.set_color(YELLOW) speed_light_template = Line(LEFT, RIGHT) speed_light_template.fade(1) speed_light_template.match_width(speed_label) speed_light_template.next_to(speed_label, DOWN, MED_LARGE_BUFF) speed_light = speed_light_template.deepcopy() def update_speed_light(light, period=2, time_width=0.05): time = self.time_tracker.get_value() alpha = (time / period) % 1 # alpha = 1 - 2 * abs(alpha - 0.5) alpha *= 1.5 a = alpha - time_width / 2 b = alpha + time_width / 2 light.pointwise_become_partial( speed_light_template, max(a, 0), min(b, 1) ) opacity = speed_label.family_members_with_points()[0].get_fill_opacity() light.set_stroke(YELLOW, width=3, opacity=opacity) # light.stretch(0.5, 0) # point = speed_light_template.point_from_proportion(0.25) # light.stretch(2, 0, about_point=point) speed_light.add_updater(update_speed_light) result = VGroup( speed_label, speed_light_template, speed_light ) return result def get_angle_group(self): title = VGroup(*map(TextMobject, [ "Angle of\\\\Incidence", "=", "Angle of\\\\Reflection", ])).arrange(RIGHT) title.set_color(YELLOW) h_line = Line(LEFT, RIGHT) h_line.match_width(title) h_line.set_stroke(LIGHT_GREY) h_line.set_sheen(1, UL) points = [ h_line.get_left() + UP, h_line.get_center(), h_line.get_right() + UP, ] dashed_lines = VGroup( DashedLine(*points[0:2]), DashedLine(*points[1:3]) ) dashed_lines.set_stroke(WHITE, 2) v_shape = VMobject() v_shape.set_points_as_corners(points) v_shape.fade(1) theta = dashed_lines[1].get_angle() arcs = VGroup( Arc(start_angle=0, angle=theta), Arc(start_angle=PI, angle=-theta), ) arcs.set_stroke(WHITE, 2) thetas = VGroup() for v in LEFT, RIGHT: theta = TexMobject("\\theta") theta.next_to(arcs, v, aligned_edge=DOWN) theta.shift(SMALL_BUFF * UP) thetas.add(theta) beam = VMobject() def update_beam(beam, period=2, time_width=0.05): time = self.time_tracker.get_value() alpha = (time / period) % 1 alpha *= 1.5 a = alpha - time_width / 2 b = alpha + time_width / 2 beam.pointwise_become_partial( v_shape, max(a, 0), min(b, 1) ) opacity = title.family_members_with_points()[0].get_fill_opacity() beam.set_stroke(YELLOW, width=3, opacity=opacity) beam.add_updater(update_beam) title.next_to(v_shape, UP, MED_LARGE_BUFF) return VGroup( title, h_line, arcs, thetas, dashed_lines, v_shape, beam ) 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