def snells_law_at_every_point(self, cycloid, chopped_cycloid): square = Square(side_length = 0.2, color = WHITE) words = TextMobject(["Snell's law ", "everywhere"]) snells, rest = words.split() colon = TextMobject(":") words.next_to(square) words.shift(0.3*UP) combo = Mobject(square, words) combo.get_center = lambda : square.get_center() new_snells = snells.copy().center().to_edge(UP, buff = 1.5) colon.next_to(new_snells) colon.shift(0.05*DOWN) self.play(MoveAlongPath( combo, cycloid, run_time = 5 )) self.play(MoveAlongPath( combo, chopped_cycloid, run_time = 4 )) dot = Dot(combo.get_center()) self.play(Transform(square, dot)) self.play( Transform(snells, new_snells), Transform(rest, colon) ) self.dither() return colon
def solve_energy(self): loss_in_potential = TextMobject("Loss in potential: ") loss_in_potential.shift(2 * UP) potential = TexMobject("m g y".split()) potential.next_to(loss_in_potential) kinetic = TexMobject(["\\dfrac{1}{2}", "m", "v", "^2", "="]) kinetic.next_to(potential, LEFT) nudge = 0.1 * UP kinetic.shift(nudge) loss_in_potential.shift(nudge) ms = Mobject(kinetic.split()[1], potential.split()[0]) two = TexMobject("2") two.shift(ms.split()[1].get_center()) half = kinetic.split()[0] sqrt = TexMobject("\\sqrt{\\phantom{2mg}}") sqrt.shift(potential.get_center()) nudge = 0.2 * LEFT sqrt.shift(nudge) squared = kinetic.split()[3] equals = kinetic.split()[-1] new_eq = equals.copy().next_to(kinetic.split()[2]) self.play( Transform(Point(loss_in_potential.get_left()), loss_in_potential), *map(GrowFromCenter, potential.split())) self.dither(2) self.play(FadeOut(loss_in_potential), GrowFromCenter(kinetic)) self.dither(2) self.play(ApplyMethod(ms.shift, 5 * UP)) self.dither() self.play(Transform(half, two, path_func=counterclockwise_path())) self.dither() self.play(Transform(squared, sqrt, path_func=clockwise_path()), Transform(equals, new_eq)) self.dither(2)
def construct(self): glass = Region(lambda x, y: y < 0, color=BLUE_E) kwargs = {"density": self.zoom_factor * DEFAULT_POINT_DENSITY_1D} top_line = Line(SPACE_HEIGHT * UP + 2 * LEFT, ORIGIN, **kwargs) extension = Line(ORIGIN, SPACE_HEIGHT * DOWN + 2 * RIGHT, **kwargs) bottom_line = Line(ORIGIN, SPACE_HEIGHT * DOWN + RIGHT, **kwargs) path1 = Mobject(top_line, extension) path2 = Mobject(top_line, bottom_line) for mob in path1, path2: mob.ingest_submobjects() extension.highlight(RED) theta1 = np.arctan(bottom_line.get_slope()) theta2 = np.arctan(extension.get_slope()) arc = Arc(theta2 - theta1, start_angle=theta1, radius=2) question_mark = TextMobject("$\\theta$?") question_mark.shift(arc.get_center() + 0.5 * DOWN + 0.25 * RIGHT) wave = self.wavify(path2) wave.highlight(YELLOW) wave.scale(0.5) self.add(glass) self.play(ShowCreation(path1)) self.play(Transform(path1, path2)) self.wait() # self.activate_zooming() self.wait() self.play(ShowPassingFlash(wave, run_time=3, rate_func=None)) self.wait() self.play(ShowCreation(extension)) self.play(ShowCreation(arc), ShimmerIn(question_mark))
def construct(self): logo = ImageMobject("LogoGeneration", invert = False) name_mob = TextMobject("3Blue1Brown").center() name_mob.highlight("grey") name_mob.shift(2*DOWN) self.add(name_mob, logo) new_text = TextMobject(["with ", "Steven Strogatz"]) new_text.next_to(name_mob, DOWN) self.play(*[ ShimmerIn(part) for part in new_text.split() ]) self.dither() with_word, steve = new_text.split() steve_copy = steve.copy().center().to_edge(UP) # logo.sort_points(lambda p : -np.linalg.norm(p)) sort_by_color(logo) self.play( Transform(steve, steve_copy), DelayByOrder(Transform(logo, Point())), FadeOut(with_word), FadeOut(name_mob), run_time = 3 )
def construct(self): self.add_cycloid_end_points() start = self.point_a.get_center() end = self.point_b.get_center() angle = 2 * np.pi / 3 path = Arc(angle, radius=3) path.gradient_highlight(RED_D, WHITE) radius = Line(ORIGIN, path.points[0]) randy = Randolph() randy.scale(RANDY_SCALE_FACTOR) randy.shift(-randy.get_bottom()) randy_copy = randy.copy() words = TextMobject( "Circular paths are good, \\\\ but still not the best") words.shift(UP) self.play( ShowCreation(path), ApplyMethod(radius.rotate, angle, path_func=path_along_arc(angle))) self.play(FadeOut(radius)) self.play(ApplyMethod(path.position_endpoints_on, start, end, path_func=path_along_arc(-angle)), run_time=3) self.adjust_mobject_to_index(randy_copy, 1, path.points) self.play(FadeIn(randy_copy)) self.remove(randy_copy) self.slide(randy, path) self.play(ShimmerIn(words)) self.dither()
class LogoGeneration(Scene): CONFIG = { "radius" : 1.5, "inner_radius_ratio" : 0.55, "circle_density" : 100, "circle_blue" : "skyblue", "circle_brown" : DARK_BROWN, "circle_repeats" : 5, "sphere_density" : 50, "sphere_blue" : DARK_BLUE, "sphere_brown" : LIGHT_BROWN, "interpolation_factor" : 0.3, "frame_duration" : 0.03, "run_time" : 3, } def construct(self): digest_config(self, {}) ## Usually shouldn't need this... self.frame_duration = self.CONFIG["frame_duration"] ## digest_config(self, {}) circle = Circle( density = self.circle_density, color = self.circle_blue ) circle.repeat(self.circle_repeats) circle.scale(self.radius) sphere = Sphere( density = self.sphere_density, color = self.sphere_blue ) sphere.scale(self.radius) sphere.rotate(-np.pi / 7, [1, 0, 0]) sphere.rotate(-np.pi / 7) iris = Mobject() iris.interpolate( circle, sphere, self.interpolation_factor ) for mob, color in [(iris, self.sphere_brown), (circle, self.circle_brown)]: mob.highlight(color, lambda (x, y, z) : x < 0 and y > 0) mob.highlight( "black", lambda point: np.linalg.norm(point) < \ self.inner_radius_ratio*self.radius ) self.name_mob = TextMobject("3Blue1Brown").center() self.name_mob.highlight("grey") self.name_mob.shift(2*DOWN) self.play(Transform( circle, iris, run_time = self.run_time )) self.frames = drag_pixels(self.frames) self.save_image(IMAGE_DIR) self.logo = MobjectFromPixelArray(self.frames[-1]) self.add(self.name_mob) self.wait()
def show_equation(self): equation = TexMobject([ "\\left(\\dfrac{1}{\\phantom{v_air}}\\right)", "\\sin(\\theta_1)", "=", "\\left(\\dfrac{1}{\\phantom{v_water}}\\right)", "\\sin(\\theta_2)" ]) equation.to_corner(UP + RIGHT) frac1, sin1, equals, frac2, sin2 = equation.split() v_air, v_water = [ TexMobject("v_{\\text{%s}}" % s, size="\\Large") for s in "air", "water" ] v_air.next_to(Point(frac1.get_center()), DOWN) v_water.next_to(Point(frac2.get_center()), DOWN) frac1.add(v_air) frac2.add(v_water) f1, f2 = [TexMobject("F_%d" % d, size="\\Large") for d in 1, 2] f1.next_to(sin1, LEFT) f2.next_to(equals, RIGHT) sin2_start = sin2.copy().next_to(f2, RIGHT) bar1 = TexMobject("\\dfrac{\\qquad}{\\qquad}") bar2 = bar1.copy() bar1.next_to(sin1, DOWN) bar2.next_to(sin2, DOWN) v_air_copy = v_air.copy().next_to(bar1, DOWN) v_water_copy = v_water.copy().next_to(bar2, DOWN) bars = Mobject(bar1, bar2) new_eq = equals.copy().center().shift(bars.get_center()) snells = TextMobject("Snell's Law") snells.highlight(YELLOW) snells.shift(new_eq.get_center()[0] * RIGHT) snells.shift(UP) anims = [] for mob in f1, sin1, equals, f2, sin2_start: anims.append(ShimmerIn(mob)) self.play(*anims) self.wait() for f, frac in (f1, frac1), (f2, frac2): target = frac.copy().ingest_submobjects() also = [] if f is f2: also.append(Transform(sin2_start, sin2)) sin2 = sin2_start self.play(Transform(f, target), *also) self.remove(f) self.add(frac) self.wait() self.play(FadeOut(frac1), FadeOut(frac2), Transform(v_air, v_air_copy), Transform(v_water, v_water_copy), ShowCreation(bars), Transform(equals, new_eq)) self.wait() frac1 = Mobject(sin1, bar1, v_air) frac2 = Mobject(sin2, bar2, v_water) for frac, vect in (frac1, LEFT), (frac2, RIGHT): self.play(ApplyMethod(frac.next_to, equals, vect)) self.wait() self.play(ShimmerIn(snells)) self.wait()
def construct(self): dated_events = [ { "date" : 1696, "text": "Johann Bernoulli poses Brachistochrone problem", "picture" : "Johann_Bernoulli2" }, { "date" : 1662, "text" : "Fermat states his principle of least time", "picture" : "Pierre_de_Fermat" } ] speical_dates = [2016] + [ obj["date"] for obj in dated_events ] centuries = range(1600, 2100, 100) timeline = NumberLine( numerical_radius = 300, number_at_center = 1800, unit_length_to_spatial_width = SPACE_WIDTH/100, tick_frequency = 10, numbers_with_elongated_ticks = centuries ) timeline.add_numbers(*centuries) centers = [ Point(timeline.number_to_point(year)) for year in speical_dates ] timeline.add(*centers) timeline.shift(-centers[0].get_center()) self.add(timeline) self.dither() run_times = iter([3, 1]) for point, event in zip(centers[1:], dated_events): self.play(ApplyMethod( timeline.shift, -point.get_center(), run_time = run_times.next() )) picture = ImageMobject(event["picture"], invert = False) picture.scale_to_fit_width(2) picture.to_corner(UP+RIGHT) event_mob = TextMobject(event["text"]) event_mob.shift(2*LEFT+2*UP) date_mob = TexMobject(str(event["date"])) date_mob.scale(0.5) date_mob.shift(0.6*UP) line = Line(event_mob.get_bottom(), 0.2*UP) self.play( ShimmerIn(event_mob), ShowCreation(line), ShimmerIn(date_mob) ) self.play(FadeIn(picture)) self.dither(3) self.play(*map(FadeOut, [event_mob, date_mob, line, picture]))
def construct(self, order): if order == 2: result_tex = "(0.125, 0.75)" elif order == 3: result_tex = "(0.0758, 0.6875)" phc, arg, result = TexMobject([ "\\text{PHC}_%d"%order, "(0.3)", "= %s"%result_tex ]).to_edge(UP).split() function = TextMobject("Function", size = "\\normal") function.shift(phc.get_center()+DOWN+2*LEFT) function_arrow = Arrow(function, phc) line = Line(5*LEFT, 5*RIGHT) curve = HilbertCurve(order = order) line.match_colors(curve) grid = Grid(2**order, 2**order) grid.fade() for mob in curve, grid: mob.scale(0.7) index = int(0.3*line.get_num_points()) dot1 = Dot(line.points[index]) arrow1 = Arrow(arg, dot1, buff = 0.1) dot2 = Dot(curve.points[index]) arrow2 = Arrow(result.get_bottom(), dot2, buff = 0.1) self.add(phc) self.play( ShimmerIn(function), ShowCreation(function_arrow) ) self.wait() self.remove(function_arrow, function) self.play(ShowCreation(line)) self.wait() self.play( ShimmerIn(arg), ShowCreation(arrow1), ShowCreation(dot1) ) self.wait() self.remove(arrow1) self.play( FadeIn(grid), Transform(line, curve), Transform(dot1, dot2), run_time = 2 ) self.wait() self.play( ShimmerIn(result), ShowCreation(arrow2) ) self.wait()
def draw_circles(self): input_value = 0.45 input_radius = 0.04 for dot in self.input_dot, self.output_dot: dot.center() kwargs = { "rate_func" : lambda t : interpolate(1, input_value, smooth(t)) } self.play( Homotopy(self.input_homotopy, self.input_dot, **kwargs), Homotopy(self.output_homotopy, self.output_dot, **kwargs) ) A, B = map(Mobject.get_center, [self.input_dot, self.output_dot]) A_text = TextMobject("A") A_text.shift(A+2*(LEFT+UP)) A_arrow = Arrow( A_text, self.input_dot, color = self.input_color ) B_text = TextMobject("B") B_text.shift(B+2*RIGHT+DOWN) B_arrow = Arrow( B_text, self.output_dot, color = self.output_color ) tup = self.get_circles_and_points( input_value-input_radius, input_value+input_radius ) input_circle, input_points, output_circle, output_points = tup for text, arrow in [(A_text, A_arrow), (B_text, B_arrow)]: self.play( ShimmerIn(text), ShowCreation(arrow) ) self.wait() self.remove(A_text, A_arrow, B_text, B_arrow) self.play(ShowCreation(input_circle)) self.wait() self.play(ShowCreation(input_points)) self.wait() input_points_copy = input_points.copy() self.play( Transform(input_points_copy, output_points), run_time = 2 ) self.wait() self.play(ShowCreation(output_circle)) self.wait() self.wait() self.remove(*[ input_circle, input_points, output_circle, input_points_copy ])
def draw_circles(self): input_value = 0.45 input_radius = 0.04 for dot in self.input_dot, self.output_dot: dot.center() kwargs = { "rate_func" : lambda t : interpolate(1, input_value, smooth(t)) } self.play( Homotopy(self.input_homotopy, self.input_dot, **kwargs), Homotopy(self.output_homotopy, self.output_dot, **kwargs) ) A, B = map(Mobject.get_center, [self.input_dot, self.output_dot]) A_text = TextMobject("A") A_text.shift(A+2*(LEFT+UP)) A_arrow = Arrow( A_text, self.input_dot, color = self.input_color ) B_text = TextMobject("B") B_text.shift(B+2*RIGHT+DOWN) B_arrow = Arrow( B_text, self.output_dot, color = self.output_color ) tup = self.get_circles_and_points( input_value-input_radius, input_value+input_radius ) input_circle, input_points, output_circle, output_points = tup for text, arrow in [(A_text, A_arrow), (B_text, B_arrow)]: self.play( ShimmerIn(text), ShowCreation(arrow) ) self.dither() self.remove(A_text, A_arrow, B_text, B_arrow) self.play(ShowCreation(input_circle)) self.dither() self.play(ShowCreation(input_points)) self.dither() input_points_copy = input_points.copy() self.play( Transform(input_points_copy, output_points), run_time = 2 ) self.dither() self.play(ShowCreation(output_circle)) self.dither() self.dither() self.remove(*[ input_circle, input_points, output_circle, input_points_copy ])
def construct(self, order): if order == 2: result_tex = "(0.125, 0.75)" elif order == 3: result_tex = "(0.0758, 0.6875)" phc, arg, result = TexMobject([ "\\text{PHC}_%d"%order, "(0.3)", "= %s"%result_tex ]).to_edge(UP).split() function = TextMobject("Function", size = "\\normal") function.shift(phc.get_center()+DOWN+2*LEFT) function_arrow = Arrow(function, phc) line = Line(5*LEFT, 5*RIGHT) curve = HilbertCurve(order = order) line.match_colors(curve) grid = Grid(2**order, 2**order) grid.fade() for mob in curve, grid: mob.scale(0.7) index = int(0.3*line.get_num_points()) dot1 = Dot(line.points[index]) arrow1 = Arrow(arg, dot1, buff = 0.1) dot2 = Dot(curve.points[index]) arrow2 = Arrow(result.get_bottom(), dot2, buff = 0.1) self.add(phc) self.play( ShimmerIn(function), ShowCreation(function_arrow) ) self.dither() self.remove(function_arrow, function) self.play(ShowCreation(line)) self.dither() self.play( ShimmerIn(arg), ShowCreation(arrow1), ShowCreation(dot1) ) self.dither() self.remove(arrow1) self.play( FadeIn(grid), Transform(line, curve), Transform(dot1, dot2), run_time = 2 ) self.dither() self.play( ShimmerIn(result), ShowCreation(arrow2) ) self.dither()
def show_change_side_by_side(self): seed = TextMobject("Seed") seed.shift(3 * LEFT + 2 * DOWN) fractal = TextMobject("Fractal") fractal.shift(3 * RIGHT + 2 * DOWN) words = map(TextMobject, [ "A sharper angle results in a richer curve", "A more obtuse angle gives a sparser curve", "And as the angle approaches 0\\dots", "We have a new space-filling curve." ]) for text in words: text.to_edge(UP) sharper, duller, space_filling = [ CurveClass(order=1).shift(3 * LEFT) for CurveClass in SharperKoch, DullerKoch, SpaceFillingKoch ] shaper_f, duller_f, space_filling_f = [ CurveClass(order=self.max_order).shift(3 * RIGHT) for CurveClass in SharperKoch, DullerKoch, SpaceFillingKoch ] self.add(words[0]) left_curve = SharperKoch(order=1) right_curve = SharperKoch(order=1) self.play( Transform(left_curve, sharper), ApplyMethod(right_curve.shift, 3 * RIGHT), ) self.play( Transform(right_curve, SharperKoch(order=2).shift(3 * RIGHT)), ShimmerIn(seed), ShimmerIn(fractal)) for order in range(3, self.max_order): self.play( Transform(right_curve, SharperKoch(order=order).shift(3 * RIGHT))) self.remove(words[0]) self.add(words[1]) kwargs = { "run_time": 4, } self.play(Transform(left_curve, duller, **kwargs), Transform(right_curve, duller_f, **kwargs)) self.wait() kwargs["run_time"] = 7 kwargs["rate_func"] = None self.remove(words[1]) self.add(words[2]) self.play(Transform(left_curve, space_filling, **kwargs), Transform(right_curve, space_filling_f, **kwargs)) self.remove(words[2]) self.add(words[3]) self.wait()
def construct(self): all_points = TextMobject("$f$ is continuous at every input point") continuous = TextMobject("$f$ is continuous") all_points.shift(UP) continuous.shift(DOWN) arrow = Arrow(all_points, continuous) self.play(ShimmerIn(all_points)) self.play(ShowCreation(arrow)) self.play(ShimmerIn(continuous)) self.dither()
def construct(self): all_points = TextMobject("$f$ is continuous at every input point") continuous = TextMobject("$f$ is continuous") all_points.shift(UP) continuous.shift(DOWN) arrow = Arrow(all_points, continuous) self.play(ShimmerIn(all_points)) self.play(ShowCreation(arrow)) self.play(ShimmerIn(continuous)) self.wait()
def construct(self): freq_line = get_freq_line() self.add(freq_line) self.dither() for tex, vect in zip(["20 Hz", "20{,}000 Hz"], [LEFT, RIGHT]): tex_mob = TextMobject(tex) tex_mob.to_edge(vect) tex_mob.shift(UP) arrow = Arrow(tex_mob, freq_line.get_edge_center(vect)) self.play(ShimmerIn(tex_mob), ShowCreation(arrow)) self.dither()
def construct(self): top_words = TextMobject("Different pixel-frequency association") bottom_words = TextMobject("Need to relearn sight-via-sound") top_words.shift(UP) bottom_words.shift(DOWN) arrow = Arrow(top_words, bottom_words) self.play(ShimmerIn(top_words)) self.dither() self.play(ShowCreation(arrow)) self.play(ShimmerIn(bottom_words)) self.dither()
def solve_energy(self): loss_in_potential = TextMobject("Loss in potential: ") loss_in_potential.shift(2*UP) potential = TexMobject("m g y".split()) potential.next_to(loss_in_potential) kinetic = TexMobject([ "\\dfrac{1}{2}","m","v","^2","=" ]) kinetic.next_to(potential, LEFT) nudge = 0.1*UP kinetic.shift(nudge) loss_in_potential.shift(nudge) ms = Mobject(kinetic.split()[1], potential.split()[0]) two = TexMobject("2") two.shift(ms.split()[1].get_center()) half = kinetic.split()[0] sqrt = TexMobject("\\sqrt{\\phantom{2mg}}") sqrt.shift(potential.get_center()) nudge = 0.2*LEFT sqrt.shift(nudge) squared = kinetic.split()[3] equals = kinetic.split()[-1] new_eq = equals.copy().next_to(kinetic.split()[2]) self.play( Transform( Point(loss_in_potential.get_left()), loss_in_potential ), *map(GrowFromCenter, potential.split()) ) self.dither(2) self.play( FadeOut(loss_in_potential), GrowFromCenter(kinetic) ) self.dither(2) self.play(ApplyMethod(ms.shift, 5*UP)) self.dither() self.play(Transform( half, two, path_func = counterclockwise_path() )) self.dither() self.play( Transform( squared, sqrt, path_func = clockwise_path() ), Transform(equals, new_eq) ) self.dither(2)
def construct(self): snells = TextMobject("Snell's") snells.shift(-snells.get_left()) snells.to_edge(UP) for vect in [RIGHT, RIGHT, LEFT, DOWN, DOWN, DOWN]: snells.add(snells.copy().next_to(snells, vect)) snells.ingest_submobjects() snells.show() condensed = TextMobject("condensed") self.add(snells) self.dither() self.play(DelayByOrder(Transform(snells, condensed, run_time=2))) self.dither()
def construct(self): horiz_radius = 5 vert_radius = 3 vert_axis = NumberLine(numerical_radius=vert_radius) vert_axis.rotate(np.pi / 2) vert_axis.shift(horiz_radius * LEFT) horiz_axis = NumberLine(numerical_radius=5, numbers_with_elongated_ticks=[]) axes = Mobject(horiz_axis, vert_axis) graph = FunctionGraph(lambda x: 0.4 * (x - 2) * (x + 2) + 3, x_min=-2, x_max=2, density=3 * DEFAULT_POINT_DENSITY_1D) graph.stretch_to_fit_width(2 * horiz_radius) graph.highlight(YELLOW) min_point = Dot(graph.get_bottom()) nature_finds = TextMobject("Nature finds this point") nature_finds.scale(0.5) nature_finds.highlight(GREEN) nature_finds.shift(2 * RIGHT + 3 * UP) arrow = Arrow(nature_finds.get_bottom(), min_point, color=GREEN) side_words_start = TextMobject("Parameter describing") top_words, last_side_words = [ map(TextMobject, pair) for pair in [("Light's travel time", "Potential energy"), ("path", "mechanical state")] ] for word in top_words + last_side_words + [side_words_start]: word.scale(0.7) side_words_start.next_to(horiz_axis, DOWN) side_words_start.to_edge(RIGHT) for words in top_words: words.next_to(vert_axis, UP) words.to_edge(LEFT) for words in last_side_words: words.next_to(side_words_start, DOWN) for words in top_words[1], last_side_words[1]: words.highlight(RED) self.add(axes, top_words[0], side_words_start, last_side_words[0]) self.play(ShowCreation(graph)) self.play(ShimmerIn(nature_finds), ShowCreation(arrow), ShowCreation(min_point)) self.dither() self.play(FadeOut(top_words[0]), FadeOut(last_side_words[0]), GrowFromCenter(top_words[1]), GrowFromCenter(last_side_words[1])) self.dither(3)
def label_spaces(self): input_space = TextMobject("Input Space") input_space.to_edge(UP) input_space.shift(LEFT * SPACE_WIDTH / 2) output_space = TextMobject("Output Space") output_space.to_edge(UP) output_space.shift(RIGHT * SPACE_WIDTH / 2) line = Line(UP * SPACE_HEIGHT, DOWN * SPACE_HEIGHT, color=WHITE) self.play( ShimmerIn(input_space), ShimmerIn(output_space), ShowCreation(line), ShowCreation(self.interval), ) self.dither()
def construct(self): freq_line = get_freq_line() self.add(freq_line) self.dither() for tex, vect in zip(["20 Hz", "20{,}000 Hz"], [LEFT, RIGHT]): tex_mob = TextMobject(tex) tex_mob.to_edge(vect) tex_mob.shift(UP) arrow = Arrow(tex_mob, freq_line.get_edge_center(vect)) self.play( ShimmerIn(tex_mob), ShowCreation(arrow) ) self.dither()
def construct(self): r_range = np.arange(0.5, 2, 0.25) cycloids = Mobject(*[ Cycloid(radius = r, end_theta=2*np.pi) for r in r_range ]) lower_left = 2*DOWN+6*LEFT lines = Mobject(*[ Line( lower_left, lower_left+5*r*np.cos(np.arctan(r))*RIGHT+2*r*np.sin(np.arctan(r))*UP ) for r in r_range ]) nl = NumberLine(numbers_with_elongated_ticks = []) x_axis = nl.copy().shift(3*UP) y_axis = nl.copy().rotate(np.pi/2).shift(6*LEFT) t_axis = nl.copy().shift(2*DOWN) x_label = TexMobject("x") x_label.next_to(x_axis, DOWN) x_label.to_edge(RIGHT) y_label = TexMobject("y") y_label.next_to(y_axis, RIGHT) y_label.shift(2*DOWN) t_label = TexMobject("t") t_label.next_to(t_axis, UP) t_label.to_edge(RIGHT) theta_label = TexMobject("\\theta") theta_label.next_to(y_axis, RIGHT) theta_label.to_edge(UP) words = TextMobject("Boundary conditions?") words.next_to(lines, RIGHT) words.shift(2*UP) self.play(ShowCreation(x_axis), ShimmerIn(x_label)) self.play(ShowCreation(y_axis), ShimmerIn(y_label)) self.play(ShowCreation(cycloids)) self.dither() self.play( Transform(cycloids, lines), Transform(x_axis, t_axis), Transform(x_label, t_label), Transform(y_label, theta_label), run_time = 2 ) self.dither() self.play(ShimmerIn(words)) self.dither()
def construct(self): snells = TextMobject("Snell's") snells.shift(-snells.get_left()) snells.to_edge(UP) for vect in [RIGHT, RIGHT, LEFT, DOWN, DOWN, DOWN]: snells.add(snells.copy().next_to(snells, vect)) snells.ingest_submobjects() snells.show() condensed = TextMobject("condensed") self.add(snells) self.dither() self.play(DelayByOrder( Transform(snells, condensed, run_time = 2) )) self.dither()
def construct(self): start_words = TextMobject([ "``", "Space Filling", "Curve ''", ]).to_edge(TOP, buff = 0.25) quote, space_filling, curve_quote = start_words.copy().split() curve_quote.shift( space_filling.get_left()-\ curve_quote.get_left() ) space_filling = Point(space_filling.get_center()) end_words = Mobject(*[ quote, space_filling, curve_quote ]).center().to_edge(TOP, buff = 0.25) space_filling_fractal = TextMobject(""" ``Space Filling Fractal'' """).to_edge(UP) curve = HilbertCurve(order = 2).shift(DOWN) fine_curve = HilbertCurve(order = 8) fine_curve.replace(curve) dots = Mobject(*[ Dot( curve.points[n*curve.get_num_points()/15], color = YELLOW_C ) for n in range(1, 15) if n not in [4, 11] ]) start_words.shift(2*(UP+LEFT)) self.play( ApplyMethod(start_words.shift, 2*(DOWN+RIGHT)) ) self.dither() self.play(Transform(start_words, end_words)) self.dither() self.play(ShowCreation(curve)) self.dither() self.play(ShowCreation( dots, run_time = 3, )) self.dither() self.clear() self.play(ShowCreation(fine_curve, run_time = 5)) self.dither() self.play(ShimmerIn(space_filling_fractal)) self.dither()
def construct(self): start_words = TextMobject([ "``", "Space Filling", "Curve ''", ]).to_edge(TOP, buff = 0.25) quote, space_filling, curve_quote = start_words.copy().split() curve_quote.shift( space_filling.get_left()-\ curve_quote.get_left() ) space_filling = Point(space_filling.get_center()) end_words = Mobject(*[ quote, space_filling, curve_quote ]).center().to_edge(TOP, buff = 0.25) space_filling_fractal = TextMobject(""" ``Space Filling Fractal'' """).to_edge(UP) curve = HilbertCurve(order = 2).shift(DOWN) fine_curve = HilbertCurve(order = 8) fine_curve.replace(curve) dots = Mobject(*[ Dot( curve.points[n*curve.get_num_points()/15], color = YELLOW_C ) for n in range(1, 15) if n not in [4, 11] ]) start_words.shift(2*(UP+LEFT)) self.play( ApplyMethod(start_words.shift, 2*(DOWN+RIGHT)) ) self.wait() self.play(Transform(start_words, end_words)) self.wait() self.play(ShowCreation(curve)) self.wait() self.play(ShowCreation( dots, run_time = 3, )) self.wait() self.clear() self.play(ShowCreation(fine_curve, run_time = 5)) self.wait() self.play(ShimmerIn(space_filling_fractal)) self.wait()
def vary_circle_sizes(self): input_value = 0.45 radius = 0.04 vary_circles = VaryCircles( self, input_value, radius, run_time=5, ) self.play(vary_circles) self.dither() text = TextMobject("Function is ``Continuous at A''") text.shift(2 * UP).to_edge(LEFT) arrow = Arrow(text, self.input_dot) self.play(ShimmerIn(text), ShowCreation(arrow)) self.dither() self.remove(vary_circles.mobject, text, arrow)
def construct(self): digest_config(self, {}) ## Usually shouldn't need this... self.frame_duration = self.DEFAULT_CONFIG["frame_duration"] ## digest_config(self, {}) circle = Circle( density = self.circle_density, color = self.circle_blue ) circle.repeat(self.circle_repeats) circle.scale(self.radius) sphere = Sphere( density = self.sphere_density, color = self.sphere_blue ) sphere.scale(self.radius) sphere.rotate(-np.pi / 7, [1, 0, 0]) sphere.rotate(-np.pi / 7) iris = Mobject() iris.interpolate( circle, sphere, self.interpolation_factor ) for mob, color in [(iris, self.sphere_brown), (circle, self.circle_brown)]: mob.highlight(color, lambda (x, y, z) : x < 0 and y > 0) mob.highlight( "black", lambda point: np.linalg.norm(point) < \ self.inner_radius_ratio*self.radius ) name = TextMobject("3Blue1Brown").center() name.highlight("grey") name.shift(2*DOWN) self.play(Transform( circle, iris, run_time = self.run_time )) self.frames = drag_pixels(self.frames) self.save_image(IMAGE_DIR) self.show_frame() self.add(name) self.dither() print "Dragging pixels..."
def vary_circle_sizes(self): input_value = 0.45 radius = 0.04 vary_circles = VaryCircles( self, input_value, radius, run_time = 5, ) self.play(vary_circles) self.dither() text = TextMobject("Function is ``Continuous at A''") text.shift(2*UP).to_edge(LEFT) arrow = Arrow(text, self.input_dot) self.play( ShimmerIn(text), ShowCreation(arrow) ) self.dither() self.remove(vary_circles.mobject, text, arrow)
def label_spaces(self): input_space = TextMobject("Input Space") input_space.to_edge(UP) input_space.shift(LEFT*SPACE_WIDTH/2) output_space = TextMobject("Output Space") output_space.to_edge(UP) output_space.shift(RIGHT*SPACE_WIDTH/2) line = Line( UP*SPACE_HEIGHT, DOWN*SPACE_HEIGHT, color = WHITE ) self.play( ShimmerIn(input_space), ShimmerIn(output_space), ShowCreation(line), ShowCreation(self.interval), ) self.dither()
def snells_law_at_every_point(self, cycloid, chopped_cycloid): square = Square(side_length=0.2, color=WHITE) words = TextMobject(["Snell's law ", "everywhere"]) snells, rest = words.split() colon = TextMobject(":") words.next_to(square) words.shift(0.3 * UP) combo = Mobject(square, words) combo.get_center = lambda: square.get_center() new_snells = snells.copy().center().to_edge(UP, buff=1.5) colon.next_to(new_snells) colon.shift(0.05 * DOWN) self.play(MoveAlongPath(combo, cycloid, run_time=5)) self.play(MoveAlongPath(combo, chopped_cycloid, run_time=4)) dot = Dot(combo.get_center()) self.play(Transform(square, dot)) self.play(Transform(snells, new_snells), Transform(rest, colon)) self.dither() return colon
def construct(self): logo = ImageMobject("LogoGeneration", invert=False) name_mob = TextMobject("3Blue1Brown").center() name_mob.highlight("grey") name_mob.shift(2 * DOWN) self.add(name_mob, logo) new_text = TextMobject(["with ", "Steven Strogatz"]) new_text.next_to(name_mob, DOWN) self.play(*[ShimmerIn(part) for part in new_text.split()]) self.dither() with_word, steve = new_text.split() steve_copy = steve.copy().center().to_edge(UP) # logo.sort_points(lambda p : -np.linalg.norm(p)) sort_by_color(logo) self.play(Transform(steve, steve_copy), DelayByOrder(Transform(logo, Point())), FadeOut(with_word), FadeOut(name_mob), run_time=3)
def equivalence(self, left_mob, arrow, right_mob): self.clear() self.add(left_mob, arrow, right_mob) words = TextMobject("is equivalent to") words.shift(0.25 * LEFT) words.highlight(BLUE) new_left = left_mob.copy().shift(RIGHT) new_right = right_mob.copy() new_right.shift( (words.get_right()[0]-\ right_mob.get_left()[0]+\ 0.5 )*RIGHT ) for mob in arrow, words: mob.sort_points(np.linalg.norm) self.play(ApplyMethod(left_mob.shift, RIGHT), Transform(arrow, words), ApplyMethod(right_mob.to_edge, RIGHT)) self.wait()
def construct(self): glass = Region(lambda x, y : y < 0, color = BLUE_E) self.generate_start_and_end_points() straight = Line(self.start_point, self.end_point) slow = TextMobject("Slow") slow.rotate(np.arctan(straight.get_slope())) slow.shift(straight.points[int(0.7*straight.get_num_points())]) slow.shift(0.5*DOWN) too_long = TextMobject("Too long") too_long.shift(UP) air = TextMobject("Air").shift(2*UP) water = TextMobject("Water").shift(2*DOWN) self.add(glass) self.play(GrowFromCenter(air)) self.play(GrowFromCenter(water)) self.dither() self.remove(air, water) ShowMultiplePathsScene.construct(self) self.play( Transform(self.path, straight) ) self.dither() self.play(GrowFromCenter(slow)) self.dither() self.remove(slow) self.leftmost.ingest_submobjects() self.play(Transform(self.path, self.leftmost, run_time = 3)) self.dither() self.play(ShimmerIn(too_long)) self.dither()
def construct(self): glass = Region(lambda x, y : y < 0, color = BLUE_E) self.generate_start_and_end_points() straight = Line(self.start_point, self.end_point) slow = TextMobject("Slow") slow.rotate(np.arctan(straight.get_slope())) slow.shift(straight.points[int(0.7*straight.get_num_points())]) slow.shift(0.5*DOWN) too_long = TextMobject("Too long") too_long.shift(UP) air = TextMobject("Air").shift(2*UP) water = TextMobject("Water").shift(2*DOWN) self.add(glass) self.play(GrowFromCenter(air)) self.play(GrowFromCenter(water)) self.wait() self.remove(air, water) ShowMultiplePathsScene.construct(self) self.play( Transform(self.path, straight) ) self.wait() self.play(GrowFromCenter(slow)) self.wait() self.remove(slow) self.leftmost.ingest_submobjects() self.play(Transform(self.path, self.leftmost, run_time = 3)) self.wait() self.play(ShimmerIn(too_long)) self.wait()
def discontinuous_point(self): point_description = TextMobject("Point where the function jumps") point_description.shift(3 * RIGHT) discontinuous_at_A = TextMobject("``Discontinuous at A''", size="\\Large") discontinuous_at_A.shift(2 * UP).to_edge(LEFT) text = TextMobject(""" Circle around ouput \\\\ points can never \\\\ be smaller than \\\\ the jump """) text.scale(0.75) text.shift(3.5 * RIGHT) input_value = 0.5 input_radius = 0.04 vary_circles = VaryCircles( self, input_value, input_radius, run_time=5, ) for dot in self.input_dot, self.output_dot: dot.center() kwargs = { "rate_func": lambda t: interpolate(0.45, input_value, smooth(t)) } self.play(Homotopy(self.input_homotopy, self.input_dot, **kwargs), Homotopy(self.output_homotopy, self.output_dot, **kwargs)) discontinuous_arrow = Arrow(discontinuous_at_A, self.input_dot) arrow = Arrow(point_description, self.output_dot, buff=0.05, color=self.output_color) self.play(ShimmerIn(point_description), ShowCreation(arrow)) self.dither() self.remove(point_description, arrow) tup = self.get_circles_and_points(input_value - input_radius, input_value + input_radius) input_circle, input_points, output_circle, output_points = tup input_points_copy = input_points.copy() self.play(ShowCreation(input_circle)) self.play(ShowCreation(input_points)) self.play(Transform(input_points_copy, output_points), run_time=2) self.play(ShowCreation(output_circle)) self.dither() self.play(ShimmerIn(text)) self.remove(input_circle, input_points, output_circle, input_points_copy) self.play(vary_circles) self.dither() self.play(ShimmerIn(discontinuous_at_A), ShowCreation(discontinuous_arrow)) self.dither(3) self.remove(vary_circles.mobject, discontinuous_at_A, discontinuous_arrow)
def equivalence(self, left_mob, arrow, right_mob): self.clear() self.add(left_mob, arrow, right_mob) words = TextMobject("is equivalent to") words.shift(0.25*LEFT) words.highlight(BLUE) new_left = left_mob.copy().shift(RIGHT) new_right = right_mob.copy() new_right.shift( (words.get_right()[0]-\ right_mob.get_left()[0]+\ 0.5 )*RIGHT ) for mob in arrow, words: mob.sort_points(np.linalg.norm) self.play( ApplyMethod(left_mob.shift, RIGHT), Transform(arrow, words), ApplyMethod(right_mob.to_edge, RIGHT) ) self.dither()
def construct(self): self.add_cycloid_end_points() start = self.point_a.get_center() end = self.point_b.get_center() angle = 2*np.pi/3 path = Arc(angle, radius = 3) path.gradient_highlight(RED_D, WHITE) radius = Line(ORIGIN, path.points[0]) randy = Randolph() randy.scale(RANDY_SCALE_VAL) randy.shift(-randy.get_bottom()) randy_copy = randy.copy() words = TextMobject("Circular paths are good, \\\\ but still not the best") words.shift(UP) self.play( ShowCreation(path), ApplyMethod( radius.rotate, angle, path_func = path_along_arc(angle) ) ) self.play(FadeOut(radius)) self.play( ApplyMethod( path.position_endpoints_on, start, end, path_func = path_along_arc(-angle) ), run_time = 3 ) self.adjust_mobject_to_index(randy_copy, 1, path.points) self.play(FadeIn(randy_copy)) self.remove(randy_copy) self.slide(randy, path) self.play(ShimmerIn(words)) self.dither()
def construct(self): glass = Region(lambda x, y : y < 0, color = BLUE_E) kwargs = { "density" : self.zoom_factor*DEFAULT_POINT_DENSITY_1D } top_line = Line(SPACE_HEIGHT*UP+2*LEFT, ORIGIN, **kwargs) extension = Line(ORIGIN, SPACE_HEIGHT*DOWN+2*RIGHT, **kwargs) bottom_line = Line(ORIGIN, SPACE_HEIGHT*DOWN+RIGHT, **kwargs) path1 = Mobject(top_line, extension) path2 = Mobject(top_line, bottom_line) for mob in path1, path2: mob.ingest_submobjects() extension.highlight(RED) theta1 = np.arctan(bottom_line.get_slope()) theta2 = np.arctan(extension.get_slope()) arc = Arc(theta2-theta1, start_angle = theta1, radius = 2) question_mark = TextMobject("$\\theta$?") question_mark.shift(arc.get_center()+0.5*DOWN+0.25*RIGHT) wave = self.wavify(path2) wave.highlight(YELLOW) wave.scale(0.5) self.add(glass) self.play(ShowCreation(path1)) self.play(Transform(path1, path2)) self.dither() # self.activate_zooming() self.dither() self.play(ShowPassingFlash( wave, run_time = 3, rate_func = None )) self.dither() self.play(ShowCreation(extension)) self.play( ShowCreation(arc), ShimmerIn(question_mark) )
def construct(self): clock = Circle(radius = 2, color = WHITE) clock.add(Dot(ORIGIN)) ticks = Mobject(*[ Line(1.8*vect, 2*vect, color = GREY) for vect in compass_directions(12) ]) clock.add(ticks) hour_hand = Line(ORIGIN, UP) minute_hand = Line(ORIGIN, 1.5*UP) clock.add(hour_hand, minute_hand) clock.to_corner(UP+RIGHT) hour_hand.get_center = lambda : clock.get_center() minute_hand.get_center = lambda : clock.get_center() solution = ImageMobject( "Newton_brachistochrone_solution2", use_cache = False ) solution.stroke_width = 3 solution.highlight(GREY) solution.scale_to_fit_width(5) solution.to_corner(UP+RIGHT) newton = ImageMobject("Old_Newton", invert = False) newton.scale(0.8) phil_trans = TextMobject("Philosophical Transactions") rect = Rectangle(height = 6, width = 4.5, color = WHITE) rect.to_corner(UP+RIGHT) rect.shift(DOWN) phil_trans.scale_to_fit_width(0.8*rect.get_width()) phil_trans.next_to(Point(rect.get_top()), DOWN) new_solution = solution.copy() new_solution.scale_to_fit_width(phil_trans.get_width()) new_solution.next_to(phil_trans, DOWN, buff = 1) not_newton = TextMobject("-Totally not by Newton") not_newton.scale_to_fit_width(2.5) not_newton.next_to(new_solution, DOWN, aligned_edge = RIGHT) phil_trans.add(rect) newton_complaint = TextMobject([ "``I do not love to be", " \\emph{dunned} ", "and teased by foreigners''" ], size = "\\small") newton_complaint.to_edge(UP, buff = 0.2) dunned = newton_complaint.split()[1] dunned.highlight() dunned_def = TextMobject("(old timey term for making \\\\ demands on someone)") dunned_def.scale(0.7) dunned_def.next_to(phil_trans, LEFT) dunned_def.shift(2*UP) dunned_arrow = Arrow(dunned_def, dunned) johann = ImageMobject("Johann_Bernoulli2", invert = False) johann.scale(0.4) johann.to_edge(LEFT) johann.shift(DOWN) johann_quote = TextMobject("``I recognize the lion by his claw''") johann_quote.next_to(johann, UP, aligned_edge = LEFT) self.play(ApplyMethod(newton.to_edge, LEFT)) self.play(ShowCreation(clock)) kwargs = { "axis" : OUT, "rate_func" : smooth } self.play( Rotating(hour_hand, radians = -2*np.pi, **kwargs), Rotating(minute_hand, radians = -12*2*np.pi, **kwargs), run_time = 5 ) self.dither() self.clear() self.add(newton) clock.ingest_submobjects() self.play(Transform(clock, solution)) self.remove(clock) self.add(solution) self.dither() self.play( FadeIn(phil_trans), Transform(solution, new_solution) ) self.dither() self.play(ShimmerIn(not_newton)) phil_trans.add(solution, not_newton) self.dither() self.play(*map(ShimmerIn, newton_complaint.split())) self.dither() self.play( ShimmerIn(dunned_def), ShowCreation(dunned_arrow) ) self.dither() self.remove(dunned_def, dunned_arrow) self.play(FadeOut(newton_complaint)) self.remove(newton_complaint) self.play( FadeOut(newton), GrowFromCenter(johann) ) self.remove(newton) self.dither() self.play(ShimmerIn(johann_quote)) self.dither()
def construct(self): horiz_radius = 5 vert_radius = 3 vert_axis = NumberLine(numerical_radius = vert_radius) vert_axis.rotate(np.pi/2) vert_axis.shift(horiz_radius*LEFT) horiz_axis = NumberLine( numerical_radius = 5, numbers_with_elongated_ticks = [] ) axes = Mobject(horiz_axis, vert_axis) graph = FunctionGraph( lambda x : 0.4*(x-2)*(x+2)+3, x_min = -2, x_max = 2, density = 3*DEFAULT_POINT_DENSITY_1D ) graph.stretch_to_fit_width(2*horiz_radius) graph.highlight(YELLOW) min_point = Dot(graph.get_bottom()) nature_finds = TextMobject("Nature finds this point") nature_finds.scale(0.5) nature_finds.highlight(GREEN) nature_finds.shift(2*RIGHT+3*UP) arrow = Arrow( nature_finds.get_bottom(), min_point, color = GREEN ) side_words_start = TextMobject("Parameter describing") top_words, last_side_words = [ map(TextMobject, pair) for pair in [ ("Light's travel time", "Potential energy"), ("path", "mechanical state") ] ] for word in top_words + last_side_words + [side_words_start]: word.scale(0.7) side_words_start.next_to(horiz_axis, DOWN) side_words_start.to_edge(RIGHT) for words in top_words: words.next_to(vert_axis, UP) words.to_edge(LEFT) for words in last_side_words: words.next_to(side_words_start, DOWN) for words in top_words[1], last_side_words[1]: words.highlight(RED) self.add( axes, top_words[0], side_words_start, last_side_words[0] ) self.play(ShowCreation(graph)) self.play( ShimmerIn(nature_finds), ShowCreation(arrow), ShowCreation(min_point) ) self.dither() self.play( FadeOut(top_words[0]), FadeOut(last_side_words[0]), GrowFromCenter(top_words[1]), GrowFromCenter(last_side_words[1]) ) self.dither(3)
def construct(self): clock = Circle(radius=2, color=WHITE) clock.add(Dot(ORIGIN)) ticks = Mobject(*[ Line(1.8 * vect, 2 * vect, color=GREY) for vect in compass_directions(12) ]) clock.add(ticks) hour_hand = Line(ORIGIN, UP) minute_hand = Line(ORIGIN, 1.5 * UP) clock.add(hour_hand, minute_hand) clock.to_corner(UP + RIGHT) hour_hand.get_center = lambda: clock.get_center() minute_hand.get_center = lambda: clock.get_center() solution = ImageMobject("Newton_brachistochrone_solution2", use_cache=False) solution.stroke_width = 3 solution.highlight(GREY) solution.scale_to_fit_width(5) solution.to_corner(UP + RIGHT) newton = ImageMobject("Old_Newton", invert=False) newton.scale(0.8) phil_trans = TextMobject("Philosophical Transactions") rect = Rectangle(height=6, width=4.5, color=WHITE) rect.to_corner(UP + RIGHT) rect.shift(DOWN) phil_trans.scale_to_fit_width(0.8 * rect.get_width()) phil_trans.next_to(Point(rect.get_top()), DOWN) new_solution = solution.copy() new_solution.scale_to_fit_width(phil_trans.get_width()) new_solution.next_to(phil_trans, DOWN, buff=1) not_newton = TextMobject("-Totally not by Newton") not_newton.scale_to_fit_width(2.5) not_newton.next_to(new_solution, DOWN, aligned_edge=RIGHT) phil_trans.add(rect) newton_complaint = TextMobject([ "``I do not love to be", " \\emph{dunned} ", "and teased by foreigners''" ], size="\\small") newton_complaint.to_edge(UP, buff=0.2) dunned = newton_complaint.split()[1] dunned.highlight() dunned_def = TextMobject( "(old timey term for making \\\\ demands on someone)") dunned_def.scale(0.7) dunned_def.next_to(phil_trans, LEFT) dunned_def.shift(2 * UP) dunned_arrow = Arrow(dunned_def, dunned) johann = ImageMobject("Johann_Bernoulli2", invert=False) johann.scale(0.4) johann.to_edge(LEFT) johann.shift(DOWN) johann_quote = TextMobject("``I recognize the lion by his claw''") johann_quote.next_to(johann, UP, aligned_edge=LEFT) self.play(ApplyMethod(newton.to_edge, LEFT)) self.play(ShowCreation(clock)) kwargs = {"axis": OUT, "rate_func": smooth} self.play(Rotating(hour_hand, radians=-2 * np.pi, **kwargs), Rotating(minute_hand, radians=-12 * 2 * np.pi, **kwargs), run_time=5) self.wait() self.clear() self.add(newton) clock.ingest_submobjects() self.play(Transform(clock, solution)) self.remove(clock) self.add(solution) self.wait() self.play(FadeIn(phil_trans), Transform(solution, new_solution)) self.wait() self.play(ShimmerIn(not_newton)) phil_trans.add(solution, not_newton) self.wait() self.play(*map(ShimmerIn, newton_complaint.split())) self.wait() self.play(ShimmerIn(dunned_def), ShowCreation(dunned_arrow)) self.wait() self.remove(dunned_def, dunned_arrow) self.play(FadeOut(newton_complaint)) self.remove(newton_complaint) self.play(FadeOut(newton), GrowFromCenter(johann)) self.remove(newton) self.wait() self.play(ShimmerIn(johann_quote)) self.wait()
def construct(self): word = TextMobject(["Bra", "chis", "to", "chrone"]) original_word = word.copy() dots = [] for part in word.split(): if dots: part.next_to(dots[-1], buff=0.06) dot = TexMobject("\\cdot") dot.next_to(part, buff=0.06) dots.append(dot) dots = Mobject(*dots[:-1]) dots.shift(0.1 * DOWN) Mobject(word, dots).center() overbrace1 = Brace(Mobject(*word.split()[:-1]), UP) overbrace2 = Brace(word.split()[-1], UP) shortest = TextMobject("Shortest") shortest.next_to(overbrace1, UP) shortest.highlight(YELLOW) time = TextMobject("Time") time.next_to(overbrace2, UP) time.highlight(YELLOW) chrono_example = TextMobject(""" As in ``Chronological'' \\\\ or ``Synchronize'' """) chrono_example.scale(0.5) chrono_example.to_edge(RIGHT) chrono_example.shift(2 * UP) chrono_example.highlight(BLUE_D) chrono_arrow = Arrow(word.get_right(), chrono_example.get_bottom(), color=BLUE_D) brachy_example = TextMobject("As in . . . brachydactyly?") brachy_example.scale(0.5) brachy_example.to_edge(LEFT) brachy_example.shift(2 * DOWN) brachy_example.highlight(GREEN) brachy_arrow = Arrow(word.get_left(), brachy_example.get_top(), color=GREEN) pronunciation = TextMobject( ["/br", "e", "kist", "e", "kr$\\bar{o}$n/"]) pronunciation.split()[1].rotate_in_place(np.pi) pronunciation.split()[3].rotate_in_place(np.pi) pronunciation.scale(0.7) pronunciation.shift(DOWN) latin = TextMobject(list("Latin")) greek = TextMobject(list("Greek")) for mob in latin, greek: mob.to_edge(LEFT) question_mark = TextMobject("?").next_to(greek, buff=0.1) stars = Stars().highlight(BLACK) stars.scale(0.5).shift(question_mark.get_center()) self.play(Transform(original_word, word), ShowCreation(dots)) self.play(ShimmerIn(pronunciation)) self.dither() self.play(GrowFromCenter(overbrace1), GrowFromCenter(overbrace2)) self.dither() self.play(ShimmerIn(latin)) self.play(FadeIn(question_mark)) self.play(Transform(latin, greek, path_func=counterclockwise_path())) self.dither() self.play(Transform(question_mark, stars)) self.remove(stars) self.dither() self.play(ShimmerIn(shortest)) self.play(ShimmerIn(time)) for ex, ar in [(chrono_example, chrono_arrow), (brachy_example, brachy_arrow)]: self.play(ShowCreation(ar), ShimmerIn(ex)) self.dither()
def show_change_side_by_side(self): seed = TextMobject("Seed") seed.shift(3*LEFT+2*DOWN) fractal = TextMobject("Fractal") fractal.shift(3*RIGHT+2*DOWN) words = map(TextMobject, [ "A sharper angle results in a richer curve", "A more obtuse angle gives a sparser curve", "And as the angle approaches 0\\dots", "We have a new space-filling curve." ]) for text in words: text.to_edge(UP) sharper, duller, space_filling = [ CurveClass(order = 1).shift(3*LEFT) for CurveClass in SharperKoch, DullerKoch, SpaceFillingKoch ] shaper_f, duller_f, space_filling_f = [ CurveClass(order = self.max_order).shift(3*RIGHT) for CurveClass in SharperKoch, DullerKoch, SpaceFillingKoch ] self.add(words[0]) left_curve = SharperKoch(order = 1) right_curve = SharperKoch(order = 1) self.play( Transform(left_curve, sharper), ApplyMethod(right_curve.shift, 3*RIGHT), ) self.play( Transform( right_curve, SharperKoch(order = 2).shift(3*RIGHT) ), ShimmerIn(seed), ShimmerIn(fractal) ) for order in range(3, self.max_order): self.play(Transform( right_curve, SharperKoch(order = order).shift(3*RIGHT) )) self.remove(words[0]) self.add(words[1]) kwargs = { "run_time" : 4, } self.play( Transform(left_curve, duller, **kwargs), Transform(right_curve, duller_f, **kwargs) ) self.dither() kwargs["run_time"] = 7 kwargs["rate_func"] = None self.remove(words[1]) self.add(words[2]) self.play( Transform(left_curve, space_filling, **kwargs), Transform(right_curve, space_filling_f, **kwargs) ) self.remove(words[2]) self.add(words[3]) self.dither()
def discontinuous_point(self): point_description = TextMobject( "Point where the function jumps" ) point_description.shift(3*RIGHT) discontinuous_at_A = TextMobject( "``Discontinuous at A''", size = "\\Large" ) discontinuous_at_A.shift(2*UP).to_edge(LEFT) text = TextMobject(""" Circle around ouput \\\\ points can never \\\\ be smaller than \\\\ the jump """) text.scale(0.75) text.shift(3.5*RIGHT) input_value = 0.5 input_radius = 0.04 vary_circles = VaryCircles( self, input_value, input_radius, run_time = 5, ) for dot in self.input_dot, self.output_dot: dot.center() kwargs = { "rate_func" : lambda t : interpolate(0.45, input_value, smooth(t)) } self.play( Homotopy(self.input_homotopy, self.input_dot, **kwargs), Homotopy(self.output_homotopy, self.output_dot, **kwargs) ) discontinuous_arrow = Arrow(discontinuous_at_A, self.input_dot) arrow = Arrow( point_description, self.output_dot, buff = 0.05, color = self.output_color ) self.play( ShimmerIn(point_description), ShowCreation(arrow) ) self.dither() self.remove(point_description, arrow) tup = self.get_circles_and_points( input_value-input_radius, input_value+input_radius ) input_circle, input_points, output_circle, output_points = tup input_points_copy = input_points.copy() self.play(ShowCreation(input_circle)) self.play(ShowCreation(input_points)) self.play( Transform(input_points_copy, output_points), run_time = 2 ) self.play(ShowCreation(output_circle)) self.dither() self.play(ShimmerIn(text)) self.remove(input_circle, input_points, output_circle, input_points_copy) self.play(vary_circles) self.dither() self.play( ShimmerIn(discontinuous_at_A), ShowCreation(discontinuous_arrow) ) self.dither(3) self.remove(vary_circles.mobject, discontinuous_at_A, discontinuous_arrow)
def construct(self): word = TextMobject(["Bra", "chis", "to", "chrone"]) original_word = word.copy() dots = [] for part in word.split(): if dots: part.next_to(dots[-1], buff = 0.06) dot = TexMobject("\\cdot") dot.next_to(part, buff = 0.06) dots.append(dot) dots = Mobject(*dots[:-1]) dots.shift(0.1*DOWN) Mobject(word, dots).center() overbrace1 = Brace(Mobject(*word.split()[:-1]), UP) overbrace2 = Brace(word.split()[-1], UP) shortest = TextMobject("Shortest") shortest.next_to(overbrace1, UP) shortest.highlight(YELLOW) time = TextMobject("Time") time.next_to(overbrace2, UP) time.highlight(YELLOW) chrono_example = TextMobject(""" As in ``Chronological'' \\\\ or ``Synchronize'' """) chrono_example.scale(0.5) chrono_example.to_edge(RIGHT) chrono_example.shift(2*UP) chrono_example.highlight(BLUE_D) chrono_arrow = Arrow( word.get_right(), chrono_example.get_bottom(), color = BLUE_D ) brachy_example = TextMobject("As in . . . brachydactyly?") brachy_example.scale(0.5) brachy_example.to_edge(LEFT) brachy_example.shift(2*DOWN) brachy_example.highlight(GREEN) brachy_arrow = Arrow( word.get_left(), brachy_example.get_top(), color = GREEN ) pronunciation = TextMobject(["/br", "e", "kist","e","kr$\\bar{o}$n/"]) pronunciation.split()[1].rotate_in_place(np.pi) pronunciation.split()[3].rotate_in_place(np.pi) pronunciation.scale(0.7) pronunciation.shift(DOWN) latin = TextMobject(list("Latin")) greek = TextMobject(list("Greek")) for mob in latin, greek: mob.to_edge(LEFT) question_mark = TextMobject("?").next_to(greek, buff = 0.1) stars = Stars().highlight(BLACK) stars.scale(0.5).shift(question_mark.get_center()) self.play(Transform(original_word, word), ShowCreation(dots)) self.play(ShimmerIn(pronunciation)) self.dither() self.play( GrowFromCenter(overbrace1), GrowFromCenter(overbrace2) ) self.dither() self.play(ShimmerIn(latin)) self.play(FadeIn(question_mark)) self.play(Transform( latin, greek, path_func = counterclockwise_path() )) self.dither() self.play(Transform(question_mark, stars)) self.remove(stars) self.dither() self.play(ShimmerIn(shortest)) self.play(ShimmerIn(time)) for ex, ar in [(chrono_example, chrono_arrow), (brachy_example, brachy_arrow)]: self.play( ShowCreation(ar), ShimmerIn(ex) ) self.dither()
def show_equation(self): equation = TexMobject([ "\\left(\\dfrac{1}{\\phantom{v_air}}\\right)", "\\sin(\\theta_1)", "=", "\\left(\\dfrac{1}{\\phantom{v_water}}\\right)", "\\sin(\\theta_2)" ]) equation.to_corner(UP+RIGHT) frac1, sin1, equals, frac2, sin2 = equation.split() v_air, v_water = [ TexMobject("v_{\\text{%s}}"%s, size = "\\Large") for s in "air", "water" ] v_air.next_to(Point(frac1.get_center()), DOWN) v_water.next_to(Point(frac2.get_center()), DOWN) frac1.add(v_air) frac2.add(v_water) f1, f2 = [ TexMobject("F_%d"%d, size = "\\Large") for d in 1, 2 ] f1.next_to(sin1, LEFT) f2.next_to(equals, RIGHT) sin2_start = sin2.copy().next_to(f2, RIGHT) bar1 = TexMobject("\\dfrac{\\qquad}{\\qquad}") bar2 = bar1.copy() bar1.next_to(sin1, DOWN) bar2.next_to(sin2, DOWN) v_air_copy = v_air.copy().next_to(bar1, DOWN) v_water_copy = v_water.copy().next_to(bar2, DOWN) bars = Mobject(bar1, bar2) new_eq = equals.copy().center().shift(bars.get_center()) snells = TextMobject("Snell's Law") snells.highlight(YELLOW) snells.shift(new_eq.get_center()[0]*RIGHT) snells.shift(UP) anims = [] for mob in f1, sin1, equals, f2, sin2_start: anims.append(ShimmerIn(mob)) self.play(*anims) self.dither() for f, frac in (f1, frac1), (f2, frac2): target = frac.copy().ingest_submobjects() also = [] if f is f2: also.append(Transform(sin2_start, sin2)) sin2 = sin2_start self.play(Transform(f, target), *also) self.remove(f) self.add(frac) self.dither() self.play( FadeOut(frac1), FadeOut(frac2), Transform(v_air, v_air_copy), Transform(v_water, v_water_copy), ShowCreation(bars), Transform(equals, new_eq) ) self.dither() frac1 = Mobject(sin1, bar1, v_air) frac2 = Mobject(sin2, bar2, v_water) for frac, vect in (frac1, LEFT), (frac2, RIGHT): self.play(ApplyMethod( frac.next_to, equals, vect )) self.dither() self.play(ShimmerIn(snells)) self.dither()