diff --git a/active_projects/basel.py b/active_projects/basel.py index 1854360a..4bc48b4f 100644 --- a/active_projects/basel.py +++ b/active_projects/basel.py @@ -103,7 +103,7 @@ class AngleUpdater(ContinualAnimation): -class LightIndicator(Mobject): +class LightIndicator(VMobject): CONFIG = { "radius": 0.5, "intensity": 0, @@ -2303,7 +2303,7 @@ class IPTScene2(Scene): -class PondScene(ThreeDScene): +class InscribedAngleScene(ThreeDScene): @@ -2329,11 +2329,14 @@ class PondScene(ThreeDScene): self.cumulated_zoom_factor = 1 - #self.force_skipping() + self.force_skipping() def zoom_out_scene(factor): + if self.mobjects.contains(self.ls0_dot): + self.play(FadeOut(self.ls0_dot)) + phi0 = self.camera.get_phi() # default is 0 degs theta0 = self.camera.get_theta() # default is -90 degs distance0 = self.camera.get_distance() @@ -2349,6 +2352,9 @@ class PondScene(ThreeDScene): self.cumulated_zoom_factor *= factor + if not self.mobjects.contains(self.ls0_dot): + self.play(FadeIn(self.ls0_dot)) + def shift_scene(v): self.play( @@ -2368,7 +2374,7 @@ class PondScene(ThreeDScene): self.obs_dot = Dot(OBSERVER_POINT, fill_color = DOT_COLOR) ls0_dot = Dot(OBSERVER_POINT + 2 * LAKE0_RADIUS * UP, fill_color = WHITE) - self.unzoomable_mobs.add(self.obs_dot, ls0_dot) + self.unzoomable_mobs.add(self.obs_dot) #, ls0_dot) # lake lake0 = Circle(radius = LAKE0_RADIUS, @@ -2752,6 +2758,852 @@ class PondScene(ThreeDScene): + self.revert_to_original_skipping_status() + + + ANGLE_COLOR1 = RED + ANGLE_COLOR2 = GREEN + + + for mob in self.mobjects: + mob.fade(1.0) + + for hyp in self.hypotenuses: + hyp.set_stroke(width = 0) + for alt in self.altitudes: + alt.set_stroke(width = 0) + for leg in self.legs: + leg.set_stroke(width = 0) + self.inner_lake.set_stroke(width = 0) + self.outer_lake.set_stroke(width = 0) + + self.wait() + + inner_lake_center = self.inner_lake.get_center() + inner_lake_radius = self.lake_radius * 0.25 + inner_ls = VGroup() + for i in range(4): + theta = -TAU/4 + (i+0.5) * TAU/4 + point = inner_lake_center + inner_lake_radius * np.array([np.cos(theta), np.sin(theta),0]) + dot = Dot(point, color = LAKE_STROKE_COLOR, radius = 0.3) + inner_ls.add(dot) + + self.add(inner_ls) + + inner_ls1 = inner_ls.submobjects[0] + inner_ls2 = inner_ls.submobjects[1] + inner_ls1_center = inner_ls1.get_center() + inner_ls2_center = inner_ls2.get_center() + + outer_lake_center = self.outer_lake.get_center() + outer_lake_radius = self.lake_radius * 0.5 + outer_ls = VGroup() + for i in range(8): + theta = -TAU/4 + (i+0.5) * TAU/8 + point = outer_lake_center + outer_lake_radius * np.array([np.cos(theta), np.sin(theta),0]) + dot = Dot(point, color = LAKE_STROKE_COLOR, radius = 0.3) + outer_ls.add(dot) + + self.add(outer_ls) + + outer_ls1 = outer_ls.submobjects[0] + outer_ls2 = outer_ls.submobjects[1] + outer_ls1_center = outer_ls1.get_center() + outer_ls2_center = outer_ls2.get_center() + + self.wait() + + arc_radius = 2.0 + + line1 = Line(inner_lake_center, inner_ls1_center, color = WHITE) + line2 = Line(inner_lake_center, inner_ls2_center, color = WHITE) + + + #arc_point1 = interpolate(inner_lake_center, inner_ls1_center, 0.2) + #arc_point2 = interpolate(inner_lake_center, inner_ls2_center, 0.2) + #inner_angle_arc = ArcBetweenPoints(arc_point1, arc_point2, angle = TAU/4) + inner_angle_arc = Arc(angle = TAU/4, start_angle = -TAU/8, radius = arc_radius, + stroke_color = ANGLE_COLOR1) + inner_angle_arc.move_arc_center_to(inner_lake_center) + + inner_label = TexMobject("\\theta", fill_color = ANGLE_COLOR1).scale(3).next_to(inner_angle_arc, LEFT, buff = -0.1) + + self.play( + ShowCreation(line1), + ShowCreation(line2), + ) + self.play( + ShowCreation(inner_angle_arc), + FadeIn(inner_label) + ) + + + + + self.wait() + + + + line3 = Line(outer_lake_center, inner_ls1_center, color = WHITE) + line4 = Line(outer_lake_center, inner_ls2_center, color = WHITE) + outer_angle_arc = Arc(angle = TAU/8, start_angle = -3*TAU/16, radius = arc_radius, + stroke_color = ANGLE_COLOR2) + outer_angle_arc.move_arc_center_to(outer_lake_center) + + outer_label = TexMobject("{\\theta \over 2}", color = ANGLE_COLOR2).scale(2.5).move_to(outer_angle_arc) + outer_label.shift([-2,-1,0]) + + self.play( + ShowCreation(line3), + ShowCreation(line4), + ) + self.play( + ShowCreation(outer_angle_arc), + FadeIn(outer_label) + ) + + + + self.wait() + + + + line5 = Line(outer_lake_center, outer_ls1_center, color = WHITE) + line6 = Line(outer_lake_center, outer_ls2_center, color = WHITE) + + self.play( + ShowCreation(line5), + ShowCreation(line6) + ) + + + self.wait() + + self.play( + FadeOut(line1), + FadeOut(line2), + FadeOut(line3), + FadeOut(line4), + FadeOut(line5), + FadeOut(line6), + FadeOut(inner_angle_arc), + FadeOut(outer_angle_arc), + FadeOut(inner_label), + FadeOut(outer_label), + ) + + + self.wait() + + inner_lines = VGroup() + inner_arcs = VGroup() + + for i in range(-2,2): + + theta = -TAU/4 + (i+0.5)*TAU/4 + ls_point = inner_lake_center + inner_lake_radius * np.array([ + np.cos(theta), np.sin(theta),0]) + line = Line(inner_lake_center, ls_point, color = WHITE) + inner_lines.add(line) + + arc = Arc(angle = TAU/4, start_angle = theta, radius = arc_radius, + stroke_color = ANGLE_COLOR1) + arc.move_arc_center_to(inner_lake_center) + inner_arcs.add(arc) + + if i == 1: + arc.set_stroke(width = 0) + + for line in inner_lines.submobjects: + self.play( + ShowCreation(line), + ) + self.add_foreground_mobject(inner_lines) + for arc in inner_arcs.submobjects: + self.play( + ShowCreation(arc) + ) + + self.wait() + + outer_lines = VGroup() + outer_arcs = VGroup() + + for i in range(-2,2): + + theta = -TAU/4 + (i+0.5)*TAU/4 + + ls_point = inner_lake_center + inner_lake_radius * np.array([ + np.cos(theta), np.sin(theta),0]) + line = Line(outer_lake_center, ls_point, color = WHITE) + outer_lines.add(line) + + theta = -TAU/4 + (i+0.5)*TAU/8 + arc = Arc(angle = TAU/8, start_angle = theta, radius = arc_radius, + stroke_color = ANGLE_COLOR2) + arc.move_arc_center_to(outer_lake_center) + outer_arcs.add(arc) + + if i == 1: + arc.set_stroke(width = 0) + + + for line in outer_lines.submobjects: + self.play( + ShowCreation(line), + ) + self.add_foreground_mobject(outer_lines) + for arc in outer_arcs.submobjects: + self.play( + ShowCreation(arc) + ) + + self.wait() + + self.play( + FadeOut(inner_lines), + FadeOut(inner_arcs) + ) + + + outer_lines2 = VGroup() + + for i in range(-2,2): + + theta = -TAU/4 + (i+0.5)*TAU/8 + ls_point = outer_lake_center + outer_lake_radius * np.array([ + np.cos(theta), np.sin(theta),0]) + line = Line(outer_lake_center, ls_point, color = WHITE) + outer_lines2.add(line) + + self.play( + ShowCreation(outer_lines2), + ) + + self.wait() + + outer_lines3 = outer_lines2.copy().rotate(TAU/2, about_point = outer_lake_center) + outer_arcs3 = outer_arcs.copy().rotate(TAU/2, about_point = outer_lake_center) + + self.play( + ShowCreation(outer_lines3), + ) + self.add_foreground_mobject(outer_lines3) + for arc in outer_arcs3.submobjects: + self.play( + ShowCreation(arc) + ) + + last_arc = outer_arcs3.submobjects[0].copy() + last_arc.rotate(-TAU/8, about_point = outer_lake_center) + last_arc2 = last_arc.copy() + last_arc2.rotate(TAU/2, about_point = outer_lake_center) + + self.play( + ShowCreation(last_arc), + ShowCreation(last_arc2), + ) + + self.wait() + + self.play( + FadeOut(outer_lines2), + FadeOut(outer_lines3), + FadeOut(outer_arcs), + FadeOut(outer_arcs3), + FadeOut(last_arc), + FadeOut(last_arc2), + ) + + self.play( + FadeOut(inner_ls), + FadeOut(outer_ls), + ) + + + self.wait() + + +class PondScene(ThreeDScene): + + + + + + def construct(self): + + BASELINE_YPOS = -2.5 + OBSERVER_POINT = np.array([0,BASELINE_YPOS,0]) + LAKE0_RADIUS = 1.5 + INDICATOR_RADIUS = 0.6 + TICK_SIZE = 0.5 + LIGHTHOUSE_HEIGHT = 0.2 + LAKE_COLOR = BLUE + LAKE_OPACITY = 0.15 + LAKE_STROKE_WIDTH = 5.0 + LAKE_STROKE_COLOR = BLUE + TEX_SCALE = 0.8 + DOT_COLOR = BLUE + + LIGHT_MAX_INT = 1 + LIGHT_SCALE = 5 + LIGHT_CUTOFF = 1 + + RIGHT_ANGLE_SIZE = 0.3 + + + self.cumulated_zoom_factor = 1 + + #self.force_skipping() + + + def right_angle(pointA, pointB, pointC): + + v1 = pointA - pointB + v1 = RIGHT_ANGLE_SIZE * v1/np.linalg.norm(v1) + v2 = pointC - pointB + v2 = RIGHT_ANGLE_SIZE * v2/np.linalg.norm(v2) + + P = pointB + Q = pointB + v1 + R = Q + v2 + S = R - v1 + angle_sign = VMobject() + angle_sign.set_points_as_corners([P,Q,R,S,P]) + angle_sign.mark_paths_closed = True + angle_sign.set_fill(color = WHITE, opacity = 1) + angle_sign.set_stroke(width = 0) + return angle_sign + + + def triangle(pointA, pointB, pointC): + + mob = VMobject() + mob.set_points_as_corners([pointA, pointB, pointC, pointA]) + mob.mark_paths_closed = True + mob.set_fill(color = WHITE, opacity = 0.5) + mob.set_stroke(width = 0) + return mob + + + def zoom_out_scene(factor): + + phi0 = self.camera.get_phi() # default is 0 degs + theta0 = self.camera.get_theta() # default is -90 degs + distance0 = self.camera.get_distance() + + distance1 = 2 * distance0 + camera_target_point = self.camera.get_spherical_coords(phi0, theta0, distance1) + + self.play( + ApplyMethod(self.camera.rotation_mobject.move_to, camera_target_point), + self.zoomable_mobs.shift, self.obs_dot.get_center(), + self.unzoomable_mobs.scale,2,{"about_point" : ORIGIN}, + ) + + self.cumulated_zoom_factor *= factor + + + def shift_scene(v): + self.play( + self.zoomable_mobs.shift,v, + self.unzoomable_mobs.shift,v + ) + + + self.zoomable_mobs = VMobject() + self.unzoomable_mobs = VMobject() + + + baseline = VMobject() + baseline.set_points_as_corners([[-8,BASELINE_YPOS,0],[8,BASELINE_YPOS,0]]) + baseline.set_stroke(width = 0) # in case it gets accidentally added to the scene + self.zoomable_mobs.add(baseline) # prob not necessary + + self.obs_dot = Dot(OBSERVER_POINT, fill_color = DOT_COLOR) + ls0_dot = Dot(OBSERVER_POINT + 2 * LAKE0_RADIUS * UP, fill_color = WHITE) + self.unzoomable_mobs.add(self.obs_dot, ls0_dot) + + # lake + lake0 = Circle(radius = LAKE0_RADIUS, + stroke_width = 0, + fill_color = LAKE_COLOR, + fill_opacity = LAKE_OPACITY + ) + lake0.move_to(OBSERVER_POINT + LAKE0_RADIUS * UP) + self.zoomable_mobs.add(lake0) + + # Morty and indicator + morty = Mortimer().scale(0.3) + morty.next_to(OBSERVER_POINT,DOWN) + indicator = LightIndicator(precision = 2, + radius = INDICATOR_RADIUS, + show_reading = False, + color = LIGHT_COLOR + ) + indicator.next_to(morty,LEFT) + self.unzoomable_mobs.add(morty, indicator) + + # first lighthouse + original_op_func = inverse_quadratic(LIGHT_MAX_INT,LIGHT_SCALE,LIGHT_CUTOFF) + ls0 = LightSource(opacity_function = original_op_func) + ls0.move_source_to(OBSERVER_POINT + LAKE0_RADIUS * 2 * UP) + self.zoomable_mobs.add(ls0, ls0.lighthouse, ls0.ambient_light) + + self.add(lake0,morty,self.obs_dot,ls0_dot, ls0.lighthouse) + self.add_foreground_mobject(morty) + self.add_foreground_mobject(self.obs_dot) + self.add_foreground_mobject(ls0_dot) + self.wait() + + + # shore arcs + arc_left = Arc(-TAU/2, + radius = LAKE0_RADIUS, + start_angle = -TAU/4, + stroke_width = LAKE_STROKE_WIDTH, + stroke_color = LAKE_STROKE_COLOR + ) + arc_left.move_arc_center_to(OBSERVER_POINT + LAKE0_RADIUS * UP) + + one_left = TexMobject("1", color = LAKE_COLOR).scale(TEX_SCALE) + one_left.next_to(arc_left,LEFT) + + + arc_right = Arc(TAU/2, + radius = LAKE0_RADIUS, + start_angle = -TAU/4, + stroke_width = LAKE_STROKE_WIDTH, + stroke_color = LAKE_STROKE_COLOR + ) + arc_right.move_arc_center_to(OBSERVER_POINT + LAKE0_RADIUS * UP) + + one_right = TexMobject("1", color = LAKE_COLOR).scale(TEX_SCALE) + one_right.next_to(arc_right,RIGHT) + + self.play( + ShowCreation(arc_left), + Write(one_left), + ShowCreation(arc_right), + Write(one_right), + ) + + + self.play( + SwitchOn(ls0.ambient_light), + lake0.set_stroke,{"color": LAKE_STROKE_COLOR, "width" : LAKE_STROKE_WIDTH}, + ) + + self.play(FadeIn(indicator)) + self.add_foreground_mobject(indicator) + + self.play( + indicator.set_intensity,0.5 + ) + + diameter_start = interpolate(OBSERVER_POINT,ls0.get_source_point(),0.05) + diameter_stop = interpolate(OBSERVER_POINT,ls0.get_source_point(),0.95) + + # diameter + diameter = DoubleArrow(diameter_start, + diameter_stop, + buff = 0, + color = WHITE, + ) + diameter_text = TexMobject("d").scale(TEX_SCALE) + diameter_text.next_to(diameter,RIGHT) + + self.play( + ShowCreation(diameter), + Write(diameter_text), + #FadeOut(self.obs_dot), + FadeOut(ls0_dot) + ) + + indicator_reading = TexMobject("{1\over d^2}").scale(TEX_SCALE) + indicator_reading.move_to(indicator) + self.unzoomable_mobs.add(indicator_reading) + + self.play( + FadeIn(indicator_reading) + ) + self.add_foreground_mobject(indicator_reading) + + # replace d with its value + new_diameter_text = TexMobject("{2\over \pi}").scale(TEX_SCALE) + new_diameter_text.color = LAKE_COLOR + new_diameter_text.move_to(diameter_text) + self.play( + Transform(diameter_text,new_diameter_text) + ) + + # insert into indicator reading + new_reading = TexMobject("{\pi^2 \over 4}").scale(TEX_SCALE) + new_reading.move_to(indicator) + + self.play( + Transform(indicator_reading,new_reading) + ) + + self.wait() + + self.play( + FadeOut(one_left), + FadeOut(one_right), + FadeOut(diameter_text), + FadeOut(arc_left), + FadeOut(arc_right) + ) + + + + + def indicator_wiggle(): + INDICATOR_WIGGLE_FACTOR = 1.3 + + self.play( + ScaleInPlace(indicator, INDICATOR_WIGGLE_FACTOR, rate_func = wiggle), + ScaleInPlace(indicator_reading, INDICATOR_WIGGLE_FACTOR, rate_func = wiggle) + ) + + + def angle_for_index(i,step): + return -TAU/4 + TAU/2**step * (i + 0.5) + + + def position_for_index(i, step, scaled_down = False): + + theta = angle_for_index(i,step) + radial_vector = np.array([np.cos(theta),np.sin(theta),0]) + position = self.lake_center + self.lake_radius * radial_vector + + if scaled_down: + return position.scale_about_point(self.obs_dot.get_center(),0.5) + else: + return position + + + def split_light_source(i, step, show_steps = True, run_time = 1): + + ls_new_loc1 = position_for_index(i,step + 1) + ls_new_loc2 = position_for_index(i + 2**step,step + 1) + + hyp = VMobject() + hyp1 = Line(self.lake_center,ls_new_loc1) + hyp2 = Line(self.lake_center,ls_new_loc2) + hyp.add(hyp2,hyp1) + self.new_hypotenuses.append(hyp) + + if show_steps == True: + self.play( + ShowCreation(hyp, run_time = run_time) + ) + + leg1 = Line(self.obs_dot.get_center(),ls_new_loc1) + leg2 = Line(self.obs_dot.get_center(),ls_new_loc2) + self.new_legs_1.append(leg1) + self.new_legs_2.append(leg2) + + if show_steps == True: + self.play( + ShowCreation(leg1, run_time = run_time), + ShowCreation(leg2, run_time = run_time), + ) + + ls1 = self.light_sources_array[i] + + + ls2 = ls1.copy() + self.add(ls2) + self.additional_light_sources.append(ls2) + + # check if the light sources are on screen + ls_old_loc = np.array(ls1.get_source_point()) + onscreen_old = np.any(np.abs(ls_old_loc) < 10) + onscreen_1 = np.any(np.abs(ls_new_loc1) < 10) + onscreen_2 = np.any(np.abs(ls_new_loc2) < 10) + show_animation = (onscreen_old or onscreen_1 or onscreen_2) + + if show_animation: + self.play( + ApplyMethod(ls1.move_source_to,ls_new_loc1, run_time = run_time), + ApplyMethod(ls2.move_source_to,ls_new_loc2, run_time = run_time), + ) + else: + ls1.move_source_to(ls_new_loc1) + ls2.move_source_to(ls_new_loc1) + + + + + + def construction_step(n, show_steps = True, run_time = 1, + simultaneous_splitting = False): + + # we assume that the scene contains: + # an inner lake, self.inner_lake + # an outer lake, self.outer_lake + # light sources, self.light_sources + # legs from the observer point to each light source + # self.legs + # altitudes from the observer point to the + # locations of the light sources in the previous step + # self.altitudes + # hypotenuses connecting antipodal light sources + # self.hypotenuses + + # these are mobjects! + + + # first, fade out all of the hypotenuses and altitudes + + if show_steps == True: + self.zoomable_mobs.remove(self.hypotenuses, self.altitudes, self.inner_lake) + self.play( + FadeOut(self.hypotenuses), + FadeOut(self.altitudes), + FadeOut(self.inner_lake) + ) + else: + self.zoomable_mobs.remove(self.inner_lake) + self.play( + FadeOut(self.inner_lake) + ) + + # create a new, outer lake + self.lake_center = self.obs_dot.get_center() + self.lake_radius * UP + + new_outer_lake = Circle(radius = self.lake_radius, + stroke_width = LAKE_STROKE_WIDTH, + fill_color = LAKE_COLOR, + fill_opacity = LAKE_OPACITY, + stroke_color = LAKE_STROKE_COLOR + ) + new_outer_lake.move_to(self.lake_center) + + if show_steps == True: + self.play( + FadeIn(new_outer_lake, run_time = run_time), + FadeIn(ls0_dot) + ) + else: + self.play( + FadeIn(new_outer_lake, run_time = run_time), + ) + + self.wait() + + self.inner_lake = self.outer_lake + self.outer_lake = new_outer_lake + self.altitudes = self.legs + #self.lake_center = self.outer_lake.get_center() + + self.additional_light_sources = [] + self.new_legs_1 = [] + self.new_legs_2 = [] + self.new_hypotenuses = [] + + for i in range(2**n): + + split_light_source(i, + step = n, + show_steps = show_steps, + run_time = run_time + ) + + if n == 1 and i == 0: + # show again where the right angles are + A = self.light_sources[0].get_center() + B = self.additional_light_sources[0].get_center() + C = self.obs_dot.get_center() + + triangle1 = triangle( + A, C, B + ) + right_angle1 = right_angle( + A, C, B + ) + + self.play( + FadeIn(triangle1), + FadeIn(right_angle1) + ) + + self.wait() + + self.play( + FadeOut(triangle1), + FadeOut(right_angle1) + ) + + self.wait() + + H = self.inner_lake.get_center() + self.lake_radius/2 * RIGHT + triangle2 = triangle( + B, H, C + ) + + right_angle2 = right_angle( + B, H, C + ) + + self.play( + FadeIn(triangle2), + FadeIn(right_angle2) + ) + + self.wait() + + self.play( + FadeOut(triangle2), + FadeOut(right_angle2) + ) + + self.wait() + + + # collect the newly created mobs (in arrays) + # into the appropriate Mobject containers + + self.legs = VMobject() + for leg in self.new_legs_1: + self.legs.add(leg) + self.zoomable_mobs.add(leg) + for leg in self.new_legs_2: + self.legs.add(leg) + self.zoomable_mobs.add(leg) + + for hyp in self.hypotenuses.submobjects: + self.zoomable_mobs.remove(hyp) + + self.hypotenuses = VMobject() + for hyp in self.new_hypotenuses: + self.hypotenuses.add(hyp) + self.zoomable_mobs.add(hyp) + + for ls in self.additional_light_sources: + self.light_sources.add(ls) + self.light_sources_array.append(ls) + self.zoomable_mobs.add(ls) + + # update scene + self.add( + self.light_sources, + self.inner_lake, + self.outer_lake, + ) + self.zoomable_mobs.add(self.light_sources, self.inner_lake, self.outer_lake) + + if show_steps == True: + self.add( + self.legs, + self.hypotenuses, + self.altitudes, + ) + self.zoomable_mobs.add(self.legs, self.hypotenuses, self.altitudes) + + + self.wait() + + if show_steps == True: + self.play(FadeOut(ls0_dot)) + + #self.lake_center = ls0_loc = self.obs_dot.get_center() + self.lake_radius * UP + self.lake_radius *= 2 + + + + + + + + + self.lake_center = ls0_loc = ls0.get_source_point() + + self.inner_lake = VMobject() + self.outer_lake = lake0 + self.legs = VMobject() + self.legs.add(Line(OBSERVER_POINT,self.lake_center)) + self.altitudes = VMobject() + self.hypotenuses = VMobject() + self.light_sources_array = [ls0] + self.light_sources = VMobject() + self.light_sources.add(ls0) + + self.lake_radius = 2 * LAKE0_RADIUS # don't ask... + + self.zoomable_mobs.add(self.inner_lake, self.outer_lake, self.altitudes, self.light_sources) + + self.add(self.inner_lake, + self.outer_lake, + self.legs, + self.altitudes, + self.hypotenuses + ) + + self.play(FadeOut(diameter)) + + self.additional_light_sources = [] + self.new_legs_1 = [] + self.new_legs_2 = [] + self.new_hypotenuses = [] + + + construction_step(0) + + my_triangle = triangle( + self.light_sources[0].get_source_point(), + OBSERVER_POINT, + self.light_sources[1].get_source_point() + ) + + angle_sign1 = right_angle( + self.light_sources[0].get_source_point(), + OBSERVER_POINT, + self.light_sources[1].get_source_point(), + ) + + self.play( + FadeIn(angle_sign1), + FadeIn(my_triangle) + ) + + angle_sign2 = right_angle( + self.light_sources[1].get_source_point(), + self.lake_center, + OBSERVER_POINT, + ) + + self.play( + FadeIn(angle_sign2) + ) + + self.wait() + + self.play( + FadeOut(angle_sign1), + FadeOut(angle_sign2), + FadeOut(my_triangle) + ) + + indicator_wiggle() + self.play(FadeOut(ls0_dot)) + zoom_out_scene(2) + self.play(FadeIn(ls0_dot)) + + construction_step(1) + indicator_wiggle() + #self.play(FadeOut(ls0_dot)) + zoom_out_scene(2) + + return + + construction_step(2) + indicator_wiggle() + self.play(FadeOut(ls0_dot)) + + + self.play( FadeOut(self.altitudes), @@ -2839,6 +3691,7 @@ class PondScene(ThreeDScene): indicator.shift,v, indicator_reading.shift,v, open_sea.shift,v, + self.obs_dot.shift,v, ) self.number_line_labels.shift(v) @@ -2869,6 +3722,13 @@ class PondScene(ThreeDScene): self.play(Write(two_sided_sum)) + for i in range(0, MAX_N): + self.play(SwitchOff(nl_sources.submobjects[i].ambient_light) + ) + for i in range(MAX_N, 2 * MAX_N - 1): + self.play(SwitchOn(nl_sources.submobjects[i].ambient_light) + ) + covering_rectangle = Rectangle( width = SPACE_WIDTH * scale, height = 2 * SPACE_HEIGHT * scale, @@ -2883,6 +3743,7 @@ class PondScene(ThreeDScene): self.add_foreground_mobject(indicator) self.add_foreground_mobject(indicator_reading) + half_indicator_reading = TexMobject("{\pi^2 \over 8}").scale(TEX_SCALE) half_indicator_reading.move_to(indicator) @@ -2890,18 +3751,19 @@ class PondScene(ThreeDScene): self.play( FadeIn(covering_rectangle), - ReplacementTransform(indicator_reading, half_indicator_reading), + Transform(indicator_reading, half_indicator_reading), FadeOut(central_plus_sign) ) + equals_sign = TexMobject("=").scale(TEX_SCALE) equals_sign.move_to(central_plus_sign) - p = 2 * scale * LEFT + p = 2 * scale * LEFT + 0.3 * UP self.play( indicator.move_to,p, - half_indicator_reading.move_to,p, - FadeIn(equals_sign) + indicator_reading.move_to,p, + FadeIn(equals_sign), ) # show Randy admiring the result @@ -2911,6 +3773,11 @@ class PondScene(ThreeDScene): + + + + + class WaitScene(TeacherStudentsScene): def construct(self): diff --git a/topics/light.py b/topics/light.py index 5b95f63e..144f998a 100644 --- a/topics/light.py +++ b/topics/light.py @@ -353,7 +353,9 @@ class SwitchOff(LaggedStart): class Lighthouse(SVGMobject): CONFIG = { "file_name" : "lighthouse", - "height" : LIGHTHOUSE_HEIGHT + "height" : LIGHTHOUSE_HEIGHT, + "fill_color" : WHITE, + "fill_opacity" : 1.0, } def move_to(self,point):