def setup_electrons(self, add_electrons=True): bezier_func_bot = bezier(self.wire_bot.get_points()) bezier_func_top = bezier(self.wire_top.get_points()) points = [] for i in range(self.bezier_approx_samples): points += [ bezier_func_bot(float(i) / float(self.bezier_approx_samples)) ] for i in range(self.bezier_approx_samples): points += [ bezier_func_top(1. - (float(i) / float(self.bezier_approx_samples))) ] self.electron_vect_inter = VectorInterpolator(points) self.electrons_flowing = True self.electron_disps = [0] * self.num_of_electrons self.electrons = [] self.electron_loc = ValueTracker(0) for i in range(self.num_of_electrons): self.electrons += [Electron().scale(0.2)] self.electrons[-1].add_updater(partial(self.electron_updater, i=i), call_updater=True) if not add_electrons: return self.add(*self.electrons, self.top_rect, self.bot_rect, self.outer_rect, self.plus_sign, self.horz_line, self.lightning_bolt, self.minus_sign, self.block_rect, self.base_big, self.base_small)
def setup_electrons(self): bezier_func_bot = bezier(self.wire_bot.get_points()) bezier_func_top = bezier(self.wire_top.get_points()) points = [] for i in range(self.bezier_approx_samples): points += [ bezier_func_bot(float(i) / float(self.bezier_approx_samples)) ] points.insert(0, points[0] + LEFT) for i in range(self.bezier_approx_samples): points += [ bezier_func_top(1. - (float(i) / float(self.bezier_approx_samples))) ] points.append(points[-1] + LEFT) self.electron_vect_inter = VectorInterpolator(points) self.electrons_flowing = True self.electron_disps = [0] * self.num_of_electrons self.electrons = [] self.electron_loc = ValueTracker(0) for i in range(self.num_of_electrons): self.electrons += [Electron()] self.electrons[-1].add_updater(partial(self.electron_updater, i=i), call_updater=True) self.add(*self.electrons, self.rect, self.bot_sine, self.top_sine, self.generator_text, self.block_rect, self.base_big, self.base_small)
def setup_electrons(self, add_electrons=True): bezier_func_bot = bezier(self.wire_bot.get_points()) bezier_func_top = bezier(self.wire_top.get_points()) points = [] for i in range(self.bezier_approx_samples): points += [ bezier_func_bot(float(i) / float(self.bezier_approx_samples)) ] for i in range(self.bezier_approx_samples): points += [ bezier_func_top(1. - (float(i) / float(self.bezier_approx_samples))) ] self.electron_vect_inter = VectorInterpolator(points) self.electrons_flowing = True self.electron_disps = [0] * self.num_of_electrons self.electrons = [] self.electron_time = ValueTracker(0) for i in range(self.num_of_electrons): self.electrons += [Electron().scale(0.2)] self.electrons[-1].add_updater(partial(self.electron_updater, i=i), call_updater=True) if add_electrons: self.add(*self.electrons, self.battery_rect, self.outer_rect, self.block_rect, self.base_big, self.base_small, self.sine_wave, self.circle) self.electron_phase = -np.pi / 2 # radians
def setup_electrons(self): self.electron_vect_inter = VectorInterpolator([ self.wires[0].get_top(), self.wires[1].get_right(), self.wires[3].get_bottom(), self.wires[4].get_left() ]) self.electons_flowing = True self.electron_disps = [0] * self.num_of_electrons self.electrons = [] self.electron_loc = ValueTracker(0) for i in range(self.num_of_electrons): self.electrons += [Electron()] self.electrons[-1].add_updater(partial(self.electron_updater, i=i), call_updater=True) # voltage source copy self.blocking_rect = Rectangle(fill_color=BLACK, fill_opacity=1, stroke_color=BLACK, stroke_opacity=1, width=self.voltage_source.get_width(), height=self.voltage_source.get_width()) self.blocking_rect.move_to(self.voltage_source.get_center()) self.voltage_source_cp = VoltageSource().scale(1.25) self.voltage_source_cp.move_to(self.voltage_source.get_center()) self.voltage_source_cp.bottom_wire.set_stroke(WHITE, opacity=0) self.voltage_source_cp.top_wire.set_stroke(WHITE, opacity=0)
def construct(self): # add circuit circuit = BatteryLampCircuit( electron_freq=self.electron_freq_0 ) \ .shift(UP) self.add(circuit) self.wait(2.09) # label elements elements_label = VGroup() elements_label.add( SurroundingRectangle( circuit.outer_rect ), SurroundingRectangle( VGroup( circuit.base_big, circuit.base_small, circuit.light_bulb ) ) ) self.play( AnimationGroup( *[ Write(mob) for mob in elements_label ], lag_ratio=1 ) ) self.play( FadeOut(elements_label), ) # add electrons circuit.setup_electrons() self.add(*circuit.electrons) self.add(circuit.battery, circuit.block_rect, circuit.base_big, circuit.base_small) self.play( circuit.get_electron_anim(2.43) ) arrow = CurvedArrow( circuit.outer_rect.get_bottom() + 1.0 * RIGHT + 0 * DOWN, circuit.outer_rect.get_top() + 1.0 * RIGHT + 0 * UP, color=GREEN, angle=np.pi * 0.8 ) self.play( ShowCreationThenFadeOut( arrow, run_time=5 ), circuit.get_electron_anim(5) ) self.play( circuit.get_electron_anim(1.48) ) # fade in current label point1 = circuit.electron_vect_inter.interpolate(0.55) point2 = circuit.electron_vect_inter.interpolate(0.5) angle = np.arccos((point2[0] - point1[0]) / np.linalg.norm(point2 - point1)) current_arrow = ArrowTip( start_angle=-1 * angle, color=self.current_color ) \ .scale(2.5) \ .move_to(point1 + 0.05 * UR) current_text = TextMobject( "current", "=", color=self.current_color) \ .next_to(current_arrow, direction=UR) \ .shift(0.5 * RIGHT) \ .scale(1.5) current_value = DecimalNumber( 1, unit="A", color=self.current_color, num_decimal_places=2 ) \ .scale(1.5) \ .next_to(current_text, direction=RIGHT, buff=0.3) current_tracker = ValueTracker(1) self.play( FadeInFrom(current_arrow, direction=UP), FadeInFrom(current_text, direction=UP), FadeInFrom(current_value, direction=UP), circuit.get_electron_anim() ) self.play( circuit.get_electron_anim(5.66) ) # draw square around amp / self.play( ShowCreationThenDestructionAround( current_value.submobjects[-1], surrounding_rectangle_config={"stroke_width": 7}, run_time=1 ), circuit.get_electron_anim(1) ) current_value.add_updater( lambda x: x.set_value(current_tracker.get_value()) ) # label equivalent electrons per second current_1 = DecimalNumber( 1, num_decimal_places=0, color=self.current_color, edge_to_fix=RIGHT, unit="A" ) \ .scale(1.5) \ .to_corner(DL, buff=1.7)\ .shift(1.9*RIGHT)\ .add_updater(lambda x: x.set_value(current_tracker.get_value())) current_1_eq = TexMobject( "=", color=self.current_color ) \ .scale(1.5) \ .next_to(current_1, direction=RIGHT, buff=0.2) elec_per_sec = DecimalNumber( 6246000000000000, num_decimal_places=0, color=self.current_color, edge_to_fix=RIGHT ) \ .scale(1.5) \ .next_to(current_1_eq, direction=RIGHT, buff=1) elec_per_sec.add_updater( lambda x: x.set_value(6242000000000000*current_tracker.get_value()), call_updater=True ) elec_per_sec_unit_tex = TexMobject( "{1", "\\over", "\\text{second}}" ) \ .scale(1.15) \ .next_to(elec_per_sec, direction=RIGHT) elec_per_sec_unit_elec = Electron() \ .scale(0.3) \ .move_to(elec_per_sec_unit_tex[0]) elec_per_sec_unit = VGroup( elec_per_sec_unit_tex, elec_per_sec_unit_elec ) self.play( FadeInFrom( VGroup(current_1, current_1_eq, elec_per_sec), direction=DOWN ), FadeInFrom( elec_per_sec_unit, direction=DOWN ), circuit.get_electron_anim(5.31) ) # set current to 2 A self.play( ApplyMethod( current_tracker.set_value, 2 ), circuit.get_electron_acceleration_anim(self.electron_freq_0 * 3) ) self.play( circuit.get_electron_anim(7.53) ) # set current to 40 A self.play( ApplyMethod( current_tracker.set_value, 40 ), circuit.get_electron_acceleration_anim(self.electron_freq_0 * 10) ) self.play( circuit.get_electron_anim(7.8) ) # remove battery circuit.electrons_flowing = False circuit.set_light_bulb_state(False) for i in range(len(circuit.electrons)): cur = (circuit.electron_loc.get_value() + i / circuit.num_of_electrons + circuit.electron_disps[i]) % 1 if 0.755 < cur < 1: circuit.electrons[i].set_opacity(0) # stop electrons circuit.set_electron_freq(0) self.play( FadeOutAndShift( circuit.battery, direction=LEFT, run_time=1 ), ApplyMethod( current_tracker.set_value, 0 ), circuit.get_electron_anim(13.65) ) circuit.electrons_flowing = True circuit.set_light_bulb_state(True) circuit.set_electron_freq(self.electron_freq_0) for i in range(len(circuit.electrons)): cur = (circuit.electron_loc.get_value() + i / circuit.num_of_electrons + circuit.electron_disps[i]) % 1 if 0.755 < cur < 1: circuit.electrons[i].set_opacity(1) circuit.electrons[i].set_stroke(BLUE, opacity=0) definition = TextMobject( "current - measure of flow of electrons in a circuit", color=YELLOW ) \ .scale(1) \ .to_corner(DOWN) self.play( FadeInFrom( circuit.battery, direction=LEFT, run_time=1 ), ApplyMethod( current_tracker.set_value, 1 ), Write( definition, run_time=2 ), circuit.get_electron_anim(2.15) ) # wait for scene to end self.play( circuit.get_electron_anim(14.7) )
def construct(self): # fade in dc circuit dc_circuit = BatteryLampCircuit( electron_freq=self.electron_freq_0 )\ .scale(self.circuit_scale)\ .to_corner(UL, buff=0)\ .shift(2.5 * DOWN+0.2*RIGHT) dc_circuit.setup_electrons() block_rect = Rectangle( fill_opacity=1, fill_color=BLACK, stroke_opacity=0 )\ .match_width(dc_circuit)\ .match_height(dc_circuit)\ .move_to(dc_circuit.get_center()) # show current label point1 = dc_circuit.electron_vect_inter.interpolate(0.55) point2 = dc_circuit.electron_vect_inter.interpolate(0.5) angle = np.arccos( (point2[0] - point1[0]) / np.linalg.norm(point2 - point1)) current_arrow = ArrowTip( start_angle=-1 * angle, color=self.current_color ) \ .scale(2.5) \ .move_to(point1 + 0.05 * UR) current_text = TextMobject( "current", "=", color=self.current_color) \ .next_to(current_arrow, direction=UR) \ .shift(0 * RIGHT) \ .scale(1.5) current_value = DecimalNumber( 1, unit="A", color=self.current_color, num_decimal_places=2 ) \ .scale(1.5) \ .next_to(current_text, direction=RIGHT, buff=0.3) current_tracker = ValueTracker(1) current_value.add_updater( lambda x: x.set_value(current_tracker.get_value())) self.add(dc_circuit, current_arrow, current_text, block_rect) self.play(FadeOut(block_rect), dc_circuit.get_electron_anim(2)) self.play(FadeInFrom(current_value, direction=UP), dc_circuit.get_electron_anim(2)) # label equivalent electrons per second elec_per_sec = DecimalNumber( 6246000000000000, num_decimal_places=0, color=self.current_color, edge_to_fix=RIGHT ) \ .scale(self.eps_scale)\ .to_corner(DL)\ .shift(0.3*LEFT) elec_per_sec_tracker = ValueTracker(6246000000000000) elec_per_sec.add_updater( lambda x: x.set_value(elec_per_sec_tracker.get_value())) elec_per_sec_unit_tex = TexMobject( "{1", "\\over", "\\text{second}}" ) \ .scale(1.15) \ .next_to(elec_per_sec, direction=RIGHT) elec_per_sec_unit_elec = Electron() \ .scale(0.3) \ .move_to(elec_per_sec_unit_tex[0]) elec_per_sec_unit = VGroup(elec_per_sec_unit_tex, elec_per_sec_unit_elec) self.play(FadeInFrom(elec_per_sec, direction=DOWN), FadeInFrom(elec_per_sec_unit, direction=DOWN), dc_circuit.get_electron_anim(2)) # add dividing line dividing_line = DashedLine(start=FRAME_HEIGHT * 0.5 * DOWN, end=FRAME_HEIGHT * 0.5 * UP, dash_length=0.25) self.play(ShowCreation(dividing_line), dc_circuit.get_electron_anim()) # fade in dc circuit ac_circuit = BatteryLampCircuitAC( electron_freq=self.ac_electron_freq ) \ .scale(self.circuit_scale) \ .to_corner(UR, buff=0) \ .shift(2.5 * DOWN + 1.0 * LEFT) ac_circuit.setup_electrons() block_rect_ac = Rectangle( fill_opacity=1, fill_color=BLACK, stroke_opacity=0, width=7.7, height=6 ) \ .move_to(ac_circuit.get_center()) # show current label point1 = ac_circuit.electron_vect_inter.interpolate(0.55) point2 = ac_circuit.electron_vect_inter.interpolate(0.5) angle = np.arccos( (point2[0] - point1[0]) / np.linalg.norm(point2 - point1)) current_arrow_ac = ArrowTip( start_angle=-1 * angle, color=self.current_color ) \ .scale(2.5) \ .move_to(point1 + 0.05 * UR) current_text_ac = TextMobject( "current", "=", color=self.current_color) \ .next_to(current_arrow_ac, direction=UR) \ .shift(0.5*LEFT) \ .scale(1.5) current_value_ac = DecimalNumber( 1, unit="A", color=self.current_color, num_decimal_places=2 ) \ .scale(1.5) \ .next_to(current_text_ac, direction=RIGHT, buff=0.3) phase_tracker_ac = ValueTracker(0) current_value_ac.add_updater( lambda x: x.set_value(np.sin(phase_tracker_ac.get_value()))) self.add(ac_circuit, current_arrow_ac, current_text_ac, current_value_ac, block_rect_ac) self.play( FadeOut(block_rect_ac), ApplyMethod(phase_tracker_ac.increment_value, 4 * self.ac_electron_freq, run_time=4, rate_func=linear), ac_circuit.get_electron_anim(4), dc_circuit.get_electron_anim(4)) # label equivalent electrons per second elec_per_sec_ac = DecimalNumber( 6246000000000000, num_decimal_places=0, color=self.current_color, edge_to_fix=RIGHT ) \ .scale(self.eps_scale) \ .to_corner(DR) \ .shift(1.5 * LEFT) elec_per_sec_ac.add_updater(lambda x: x.set_value( 6246000000000000 * np.sin(phase_tracker_ac.get_value()))) elec_per_sec_unit_tex_ac = TexMobject( "{1", "\\over", "\\text{second}}" ) \ .scale(1.15) \ .next_to(elec_per_sec_ac, direction=RIGHT) elec_per_sec_unit_elec_ac = Electron() \ .scale(0.3) \ .move_to(elec_per_sec_unit_tex_ac[0]) elec_per_sec_unit_ac = VGroup(elec_per_sec_unit_tex_ac, elec_per_sec_unit_elec_ac) block_rect_2 = Rectangle( fill_opacity=1, fill_color=BLACK, stroke_opacity=0, width=8.5, height=3 )\ .move_to(VGroup(elec_per_sec_ac, elec_per_sec_unit_ac).get_center()) self.add(elec_per_sec_ac, elec_per_sec_unit_ac, block_rect_2) self.play( FadeOut(block_rect_2), ac_circuit.get_electron_anim(2), dc_circuit.get_electron_anim(2), ApplyMethod(phase_tracker_ac.increment_value, 2 * self.ac_electron_freq, run_time=2, rate_func=linear), ) # dc title dc_title = TextMobject("Direct Current", "(DC)") \ .scale(1.25) dc_title.move_to(FRAME_WIDTH * 0.25 * LEFT + FRAME_HEIGHT * 0.5 * UP + dc_title.get_height() * 0.5 * DOWN + 0.2 * DOWN) dc_underline = Line(LEFT, RIGHT) \ .match_width(dc_title) \ .scale(1) \ .next_to(dc_title, DOWN, SMALL_BUFF) self.play( Write(dc_title[0]), ac_circuit.get_electron_anim(2), dc_circuit.get_electron_anim(2), ApplyMethod(phase_tracker_ac.increment_value, 2 * self.ac_electron_freq, run_time=2, rate_func=linear), ) self.play( Write(dc_title[1]), ShowCreation(dc_underline), ac_circuit.get_electron_anim(2), dc_circuit.get_electron_anim(2), ApplyMethod(phase_tracker_ac.increment_value, 2 * self.ac_electron_freq, run_time=2, rate_func=linear), ) # ac title ac_title = TextMobject("Alternating Current", "(AC)") \ .scale(1.25) ac_title.move_to(FRAME_WIDTH * 0.25 * RIGHT + FRAME_HEIGHT * 0.5 * UP + ac_title.get_height() * 0.5 * DOWN + 0.2 * DOWN) ac_underline = Line(LEFT, RIGHT) \ .match_width(ac_title) \ .scale(1) \ .next_to(ac_title, DOWN, SMALL_BUFF) self.play(Write(ac_title[0], run_time=1)) self.play(Write(ac_title[1]), ShowCreation(ac_underline)) self.wait(5.97)
def construct(self): # add circuit circuit = BatteryLampCircuit( electron_freq=self.electron_freq_0 )\ .shift(UP) self.add(circuit) self.wait(2.98) # label elements elements_label = VGroup() elements_label.add( SurroundingRectangle(circuit.outer_rect), SurroundingRectangle( VGroup(circuit.base_big, circuit.base_small, circuit.light_bulb))) self.play( AnimationGroup( *[Write(mob, run_time=1.36) for mob in elements_label], lag_ratio=1)) self.play(FadeOut(elements_label, run_time=0.91), ) self.wait(0.24) # remove battery circuit.set_light_bulb_state(False) self.play(FadeOutAndShift(circuit.battery, direction=LEFT, run_time=1), ) self.wait(4.47) # add battery circuit.set_light_bulb_state(True) self.play(FadeInFrom(circuit.battery, direction=LEFT, run_time=1), ) # add electrons circuit.setup_electrons() self.add(*circuit.electrons) self.add(circuit.battery, circuit.block_rect, circuit.base_big, circuit.base_small) self.play(circuit.get_electron_anim(run_time=4.02)) arrow = CurvedArrow( circuit.outer_rect.get_bottom() + 1.0 * RIGHT + 0 * DOWN, circuit.outer_rect.get_top() + 1.0 * RIGHT + 0 * UP, color=GREEN, angle=np.pi * 0.8) self.play(ShowCreationThenFadeOut(arrow, run_time=4.83), circuit.get_electron_anim(4.83)) self.play(circuit.get_electron_anim(2.43)) # fade in current label point1 = circuit.electron_vect_inter.interpolate(0.55) point2 = circuit.electron_vect_inter.interpolate(0.5) angle = np.arccos( (point2[0] - point1[0]) / np.linalg.norm(point2 - point1)) current_arrow = ArrowTip( start_angle=-1 * angle, color=self.current_color ) \ .scale(2.5) \ .move_to(point1 + 0.05 * UR) current_text = TextMobject( "current", "=", color=self.current_color) \ .next_to(current_arrow, direction=UR) \ .shift(0.5 * RIGHT) \ .scale(1.5) current_value = DecimalNumber( 2, unit="A", color=self.current_color, num_decimal_places=2 ) \ .scale(1.5) \ .next_to(current_text, direction=RIGHT, buff=0.3) current_tracker = ValueTracker(2) current_value.add_updater( lambda x: x.set_value(current_tracker.get_value())) self.play(FadeInFrom(current_arrow, direction=UP), FadeInFrom(current_text, direction=UP), circuit.get_electron_anim()) self.play(circuit.get_electron_anim(run_time=1.01)) # show definition definition = TextMobject( "current - measure of ", "electrons", " per second passing through a circuit", color=YELLOW ) \ .scale(1) \ .to_corner(DOWN) self.play(Write(definition, run_time=2), circuit.get_electron_anim(5.91)) # add 2 Amps label self.play(FadeInFrom(current_value, direction=UP), circuit.get_electron_anim(11.57)) # remove battery circuit.electrons_flowing = False circuit.set_light_bulb_state(False) for i in range(len(circuit.electrons)): cur = (circuit.electron_loc.get_value() + i / circuit.num_of_electrons + circuit.electron_disps[i]) % 1 if 0.755 < cur < 1: circuit.electrons[i].set_opacity(0) # stop electrons circuit.set_electron_freq(0) self.play(ApplyMethod(current_tracker.set_value, 0, run_time=1), FadeOutAndShift(circuit.battery, direction=LEFT, run_time=1), circuit.get_electron_anim(run_time=12.47)) circuit.electrons_flowing = True circuit.set_light_bulb_state(True) circuit.set_electron_freq(self.electron_freq_0) for i in range(len(circuit.electrons)): cur = (circuit.electron_loc.get_value() + i / circuit.num_of_electrons + circuit.electron_disps[i]) % 1 if 0.755 < cur < 1: circuit.electrons[i].set_opacity(1) circuit.electrons[i].set_stroke(BLUE, opacity=0) self.play(ApplyMethod(current_tracker.set_value, 2, run_time=1), FadeInFrom(circuit.battery, direction=LEFT, run_time=1), circuit.get_electron_anim(22.21)) # add question mark next to Amp not_eps = TextMobject( "???", color="#FF0000" )\ .scale(1.75)\ .next_to(current_value, direction=DR, buff=0.5)\ .shift(0.2*RIGHT) arrow_not_eps = CurvedArrow( start_point=not_eps.get_edge_center(UP) + 0.25 * UP + 0.25 * RIGHT, end_point=current_value.get_right() + 0.4 * RIGHT, color="#FF0000") self.play( AnimationGroup(FadeInFrom(not_eps, direction=RIGHT), ShowCreation(arrow_not_eps), lag_ratio=1), circuit.get_electron_anim(6.42)) # increase current to 40 Amps self.play( ApplyMethod(current_tracker.increment_value, 38, run_time=2, rate_func=linear), circuit.get_electron_acceleration_anim(self.electron_freq_1, run_time=2)) self.play(circuit.get_electron_anim(1.13)) # increase current to 40 Amps self.play( ApplyMethod(current_tracker.set_value, 90, run_time=2, rate_func=linear), circuit.get_electron_acceleration_anim(self.electron_freq_1 * 1.8, run_time=2)) self.play(circuit.get_electron_anim()) # fadeout definition self.play(circuit.get_electron_anim(), FadeOut(definition), FadeOut(not_eps), FadeOut(arrow_not_eps)) # reduce current to 1 Amps self.play( ApplyMethod(current_tracker.set_value, 1, run_time=1, rate_func=linear), circuit.get_electron_acceleration_anim(self.electron_freq_0 / 2, run_time=1)) # label equivalent electrons per second elec_per_sec = DecimalNumber( 6246000000000000, num_decimal_places=0, color=self.current_color, edge_to_fix=RIGHT ) \ .scale(1.5) \ .to_edge(DOWN, buff=1.7) elec_per_sec_tracker = ValueTracker(6246000000000000) elec_per_sec.add_updater( lambda x: x.set_value(elec_per_sec_tracker.get_value())) elec_per_sec_unit_tex = TexMobject( "{1", "\\over", "\\text{second}}" ) \ .scale(1.15) \ .next_to(elec_per_sec, direction=RIGHT) elec_per_sec_unit_elec = Electron() \ .scale(0.3) \ .move_to(elec_per_sec_unit_tex[0]) elec_per_sec_unit = VGroup(elec_per_sec_unit_tex, elec_per_sec_unit_elec) self.play(FadeInFrom(elec_per_sec, direction=DOWN), FadeInFrom(elec_per_sec_unit, direction=DOWN), circuit.get_electron_anim(7.2)) # increase to 2 amps def digit_exp_decay(alpha, start): return exponential_decay(alpha, half_life=np.log10(2) / np.floor(np.log10(start))) self.play( circuit.get_electron_acceleration_anim(self.electron_freq_0, run_time=2), ApplyMethod(current_tracker.set_value, 2, run_time=2, rate_func=linear), ApplyMethod( elec_per_sec_tracker.set_value, 12492000000000000, run_time=2, # will not work for any great half life values rate_func=partial(exponential_decay, half_life=0.025))) self.play(circuit.get_electron_anim(9.38)) # increase to 40 amps self.play( circuit.get_electron_acceleration_anim(self.electron_freq_0 * 20, run_time=2), ApplyMethod(current_tracker.set_value, 40, run_time=2, rate_func=linear), ApplyMethod( elec_per_sec_tracker.set_value, 249840000000000000, run_time=2, # will not work for any great half life values rate_func=partial(exponential_decay, half_life=0.025))) self.play(circuit.get_electron_anim(10.16)) # remove battery circuit.electrons_flowing = False circuit.set_light_bulb_state(False) for i in range(len(circuit.electrons)): cur = (circuit.electron_loc.get_value() + i / circuit.num_of_electrons + circuit.electron_disps[i]) % 1 if 0.755 < cur < 1: circuit.electrons[i].set_opacity(0) # stop electrons circuit.set_electron_freq(0) self.play( ApplyMethod(current_tracker.set_value, 0, run_time=1), FadeOutAndShift(circuit.battery, direction=LEFT, run_time=1), ApplyMethod( elec_per_sec_tracker.set_value, 0, run_time=2, # will not work for any great half life values rate_func=partial(digit_exp_decay, start=249840000000000000)), circuit.get_electron_anim(3), ) self.play(circuit.get_electron_anim(6.78)) circuit.electrons_flowing = True circuit.set_light_bulb_state(True) for i in range(len(circuit.electrons)): cur = (circuit.electron_loc.get_value() + i / circuit.num_of_electrons + circuit.electron_disps[i]) % 1 if 0.755 < cur < 1: circuit.electrons[i].set_opacity(1) circuit.electrons[i].set_stroke(BLUE, opacity=0) self.play( ApplyMethod(current_tracker.set_value, 2, run_time=1), FadeInFrom(circuit.battery, direction=LEFT, run_time=1), ApplyMethod( elec_per_sec_tracker.set_value, 12492000000000000, run_time=2, # will not work for any great half life values rate_func=rush_into), circuit.get_electron_anim(3))