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 setup_axes(self, animate=False): ##TODO, once eoc is done, refactor this to be less redundant. x_num_range = float(self.x_max - self.x_min) self.space_unit_to_x = self.x_axis_width / x_num_range self.x_labeled_nums = self.x_labeled_nums or [] if self.x_leftmost_tick is None: self.x_leftmost_tick = self.x_min x_axis = NumberLine(x_min=self.x_min, x_max=self.x_max, unit_size=self.space_unit_to_x, tick_frequency=self.x_tick_frequency, leftmost_tick=self.x_leftmost_tick, numbers_with_elongated_ticks=self.x_labeled_nums, color=self.axes_color) x_axis.shift(self.graph_origin - x_axis.number_to_point(0)) if len(self.x_labeled_nums) > 0: if self.exclude_zero_label: self.x_labeled_nums = filter(lambda x: x != 0, self.x_labeled_nums) x_axis.add_numbers(*self.x_labeled_nums) x_label = TextMobject(self.x_axis_label) x_label.next_to(x_axis.get_tick_marks(), UP + RIGHT, buff=SMALL_BUFF) x_label.shift_onto_screen() x_axis.add(x_label) self.x_axis_label_mob = x_label y_num_range = float(self.y_max - self.y_min) self.space_unit_to_y = self.y_axis_height / y_num_range self.y_labeled_nums = self.y_labeled_nums or [] if self.y_bottom_tick is None: self.y_bottom_tick = self.y_min y_axis = NumberLine(x_min=self.y_min, x_max=self.y_max, unit_size=self.space_unit_to_y, tick_frequency=self.y_tick_frequency, leftmost_tick=self.y_bottom_tick, numbers_with_elongated_ticks=self.y_labeled_nums, color=self.axes_color) y_axis.shift(self.graph_origin - y_axis.number_to_point(0)) y_axis.rotate(np.pi / 2, about_point=y_axis.number_to_point(0)) if len(self.y_labeled_nums) > 0: if self.exclude_zero_label: self.y_labeled_nums = filter(lambda y: y != 0, self.y_labeled_nums) y_axis.add_numbers(*self.y_labeled_nums) for mob in y_axis.numbers: mob.next_to(mob.get_center(), LEFT, MED_SMALL_BUFF) mob.shift(self.y_axis_numbers_nudge) y_label = TextMobject(self.y_axis_label) y_label.next_to(y_axis.get_tick_marks(), UP + RIGHT, buff=SMALL_BUFF) y_label.shift_onto_screen() y_axis.add(y_label) self.y_axis_label_mob = y_label if animate: self.play(Write(VGroup(x_axis, y_axis))) else: self.add(x_axis, y_axis) self.x_axis, self.y_axis = self.axes = VGroup(x_axis, y_axis) self.default_graph_colors = it.cycle(self.default_graph_colors)
def finite_analog(self, left_mob, arrow, right_mob): self.clear() self.add(left_mob, arrow, right_mob) ex = TextMobject("\\times") ex.highlight(RED) # ex.shift(arrow.get_center()) middle = TexMobject("\\sum_{n=0}^N 2^n \\equiv -1 \\mod 2^{N+1}") finite_analog = TextMobject("Finite analog") finite_analog.scale(0.8) brace = Brace(middle, UP) finite_analog.next_to(brace, UP) new_left = left_mob.copy().to_edge(LEFT) new_right = right_mob.copy().to_edge(RIGHT) left_arrow, right_arrow = [ Arrow(mob1.get_right()[0] * RIGHT, mob2.get_left()[0] * RIGHT, buff=0) for mob1, mob2 in [(new_left, middle), (middle, new_right)] ] for mob in ex, middle: mob.sort_points(np.linalg.norm) self.play(GrowFromCenter(ex)) self.wait() self.play(Transform(left_mob, new_left), Transform(arrow.copy(), left_arrow), DelayByOrder(Transform(ex, middle)), Transform(arrow, right_arrow), Transform(right_mob, new_right)) self.play(GrowFromCenter(brace), ShimmerIn(finite_analog)) self.wait() self.equivalence(left_mob, left_arrow, Mobject(middle, brace, finite_analog))
def construct(self): words, s = TextMobject(["Pseudo-Hilbert Curve", "s"]).split() pre_words = TextMobject("Order 1") pre_words.next_to(words, LEFT, buff = 0.5) s.next_to(words, RIGHT, buff = 0.05, aligned_edge = DOWN) cluster = Mobject(pre_words, words, s) cluster.center() cluster.scale(0.7) cluster.to_edge(UP, buff = 0.3) cluster.highlight(GREEN) grid1 = Grid(1, 1) grid2 = Grid(2, 2) curve = HilbertCurve(order = 1) self.add(words, s) self.dither() self.play(Transform( s, pre_words, path_func = path_along_arc(-np.pi/3) )) self.dither() self.play(ShowCreation(grid1)) self.dither() self.play(ShowCreation(grid2)) self.dither() kwargs = { "run_time" : 5, "rate_func" : None } self.play(ShowCreation(curve, **kwargs)) self.dither()
def construct(self): low_res = ImageMobject("low_resolution_lion", invert = False) high_res = ImageMobject("Lion", invert = False) grid = get_grid().scale(0.8) for mob in low_res, high_res: mob.replace(grid, stretch = True) side_brace = Brace(low_res, LEFT) top_brace = Brace(low_res, UP) top_words = TextMobject("256 Px", size = "\\normal") side_words = top_words.copy().rotate(np.pi/2) top_words.next_to(top_brace, UP) side_words.next_to(side_brace, LEFT) self.add(high_res) self.dither() self.play(DelayByOrder(Transform(high_res, low_res))) self.dither() self.play( GrowFromCenter(top_brace), GrowFromCenter(side_brace), ShimmerIn(top_words), ShimmerIn(side_words) ) self.dither() for mob in grid, high_res: mob.sort_points(np.linalg.norm) self.play(DelayByOrder(Transform(high_res, grid))) self.dither()
def show_diameter(self): exceptions = [ self.circle, self.tangent_line, self.pc_line, self.right_angle_symbol ] everything = set(self.mobjects).difference(exceptions) everything_copy = Mobject(*everything).copy() light_everything = everything_copy.copy() dark_everything = everything_copy.copy() dark_everything.fade(0.8) bottom_point = np.array(self.c_point) bottom_point += 2 * self.radius * DOWN diameter = Line(bottom_point, self.c_point) brace = Brace(diameter, RIGHT) diameter_word = TextMobject("Diameter") d_mob = TexMobject("D") diameter_word.next_to(brace) d_mob.next_to(diameter) self.remove(*everything) self.play(Transform(everything_copy, dark_everything)) self.dither() self.play(ShowCreation(diameter)) self.play(GrowFromCenter(brace)) self.play(ShimmerIn(diameter_word)) self.dither() self.play(*[Transform(mob, d_mob) for mob in brace, diameter_word]) self.remove(brace, diameter_word) self.add(d_mob) self.play(Transform(everything_copy, light_everything)) self.remove(everything_copy) self.add(*everything) self.d_mob = d_mob self.bottom_point = bottom_point
def construct(self): hilbert_curves, snake_curves = [ [ CurveClass(order = n) for n in range(2, 7) ] for CurveClass in HilbertCurve, SnakeCurve ] for curve in hilbert_curves+snake_curves: curve.scale(0.8) for curve in hilbert_curves: curve.to_edge(LEFT) for curve in snake_curves: curve.to_edge(RIGHT) greater_than = TexMobject(">") question_mark = TextMobject("?") question_mark.next_to(greater_than, UP) self.add(greater_than, question_mark) hilbert_curve = hilbert_curves[0] snake_curve = snake_curves[0] for new_hc, new_sc in zip(hilbert_curves[1:], snake_curves[1:]): self.play(*[ Transform(hilbert_curve, new_hc), Transform(snake_curve, new_sc) ]) self.dither()
def construct(self): CycloidScene.construct(self) equation = TexMobject( ["\\dfrac{\\sin(\\theta)}{\\sqrt{y}}", "= \\text{constant}"]) sin_sqrt, const = equation.split() new_eq = equation.copy() new_eq.to_edge(UP, buff=1.3) cycloid_word = TextMobject("Cycloid") arrow = Arrow(2 * UP, cycloid_word) arrow.reverse_points() q_mark = TextMobject("?") self.play(*map(ShimmerIn, equation.split())) self.dither() self.play(ApplyMethod(equation.shift, 2.2 * UP), ShowCreation(arrow)) q_mark.next_to(sin_sqrt) self.play(ShimmerIn(cycloid_word)) self.dither() self.grow_parts() self.draw_cycloid() self.dither() extra_terms = [const, arrow, cycloid_word] self.play(*[Transform(mob, q_mark) for mob in extra_terms]) self.remove(*extra_terms) self.roll_back() q_marks, arrows = self.get_q_marks_and_arrows(sin_sqrt) self.draw_cycloid(3, ShowCreation(q_marks), ShowCreation(arrows)) self.dither()
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): curve = PeanoCurve(order=5) curve.stretch_to_fit_width(2 * SPACE_WIDTH) curve.stretch_to_fit_height(2 * SPACE_HEIGHT) curve_start = curve.copy() curve_start.apply_over_attr_arrays(lambda arr: arr[:200]) time_line = get_time_line() time_line.shift(-time_line.number_to_point(2000)) self.add(time_line) self.play( ApplyMethod(time_line.shift, -time_line.number_to_point(1900), run_time=3)) brace = Brace( Mobject( Point(time_line.number_to_point(1865)), Point(time_line.number_to_point(1888)), ), UP) words = TextMobject(""" Cantor drives himself (and the \\\\ mathematical community at large) \\\\ crazy with research on infinity. """) words.next_to(brace, UP) self.play(GrowFromCenter(brace), ShimmerIn(words)) self.dither() self.play(Transform(time_line, curve_start), FadeOut(brace), FadeOut(words)) self.play(ShowCreation(curve, run_time=5, rate_func=None)) self.dither()
def add_title(self, title = "Sample space", buff = MED_SMALL_BUFF): title_mob = TextMobject(title) if title_mob.get_width() > self.get_width(): title_mob.scale_to_fit_width(self.get_width()) title_mob.next_to(self.full_space, UP, buff = buff) self.title = title_mob self.add(title_mob)
def construct(self): t_axis = NumberLine() theta_axis = NumberLine().rotate(np.pi / 2) theta_mob = TexMobject("\\theta(t)") t_mob = TexMobject("t") theta_mob.next_to(theta_axis, RIGHT) theta_mob.to_edge(UP) t_mob.next_to(t_axis, UP) t_mob.to_edge(RIGHT) graph = ParametricFunction( lambda t: 4 * t * RIGHT + 2 * smooth(t) * UP) line = Line(graph.points[0], graph.points[-1], color=WHITE) q_mark = TextMobject("?") q_mark.next_to(Point(graph.get_center()), LEFT) stars = Stars(color=BLACK) stars.scale(0.1).shift(q_mark.get_center()) squiggle = ParametricFunction(lambda t: t * RIGHT + 0.2 * t * (5 - t) * (np.sin(t)**2) * UP, start=0, end=5) self.play(ShowCreation(t_axis), ShowCreation(theta_axis), ShimmerIn(theta_mob), ShimmerIn(t_mob)) self.play(ShimmerIn(q_mark), ShowCreation(graph)) self.wait() self.play(Transform(q_mark, stars), Transform(graph, line)) self.wait() self.play(Transform(graph, squiggle)) self.wait()
def construct(self): self.knob = Circle(color = BLUE_D) self.knob.add_line(UP, DOWN) self.knob.to_corner(UP+RIGHT) self.knob.shift(0.5*DOWN) self.last_angle = np.pi/2 arrow = Vector(ORIGIN, RIGHT) arrow.next_to(self.knob, LEFT) words = TextMobject("Turn this knob over time to define the curve") words.next_to(arrow, LEFT) self.path = self.get_path() self.path.shift(1.5*DOWN) self.path.show() self.path.highlight(BLACK) randy = Randolph() randy.scale(RANDY_SCALE_VAL) randy.shift(-randy.get_bottom()) self.play(ShimmerIn(words)) self.play(ShowCreation(arrow)) self.play(ShowCreation(self.knob)) self.dither() self.add(self.path) self.slide(randy, self.path) self.dither()
def construct(self): self.knob = Circle(color=BLUE_D) self.knob.add_line(UP, DOWN) self.knob.to_corner(UP + RIGHT) self.knob.shift(0.5 * DOWN) self.last_angle = np.pi / 2 arrow = Vector(ORIGIN, RIGHT) arrow.next_to(self.knob, LEFT) words = TextMobject("Turn this knob over time to define the curve") words.next_to(arrow, LEFT) self.path = self.get_path() self.path.shift(1.5 * DOWN) self.path.show() self.path.highlight(BLACK) randy = Randolph() randy.scale(RANDY_SCALE_FACTOR) randy.shift(-randy.get_bottom()) self.play(ShimmerIn(words)) self.play(ShowCreation(arrow)) self.play(ShowCreation(self.knob)) self.dither() self.add(self.path) self.slide(randy, self.path) self.dither()
def add_title(self, title="Sample space", buff=MED_SMALL_BUFF): title_mob = TextMobject(title) if title_mob.get_width() > self.get_width(): title_mob.scale_to_fit_width(self.get_width()) title_mob.next_to(self.full_space, UP, buff=buff) self.title = title_mob self.add(title_mob)
def construct(self): names = [ "Johann_Bernoulli2", "Jacob_Bernoulli", "Gottfried_Wilhelm_von_Leibniz", "Newton" ] guys = [ImageMobject(name, invert=False) for name in names] johann = guys[0] johann.scale(0.8) pensive_johann = johann.copy() pensive_johann.scale(0.25) pensive_johann.to_corner(DOWN + LEFT) comparitive_johann = johann.copy() template = Square(side_length=2) comparitive_johann.replace(template) comparitive_johann.shift(UP + LEFT) greater_than = TexMobject(">") greater_than.next_to(comparitive_johann) for guy, name in zip(guys, names)[1:]: guy.replace(template) guy.next_to(greater_than) name_mob = TextMobject(name.replace("_", " ")) name_mob.scale(0.5) name_mob.next_to(guy, DOWN) guy.name_mob = name_mob guy.sort_points(lambda p: np.dot(p, DOWN + RIGHT)) bubble = ThoughtBubble(initial_width=12) bubble.stretch_to_fit_height(6) bubble.ingest_submobjects() bubble.pin_to(pensive_johann) bubble.shift(DOWN) point = Point(johann.get_corner(UP + RIGHT)) upper_point = Point(comparitive_johann.get_corner(UP + RIGHT)) lightbulb = ImageMobject("Lightbulb", invert=False) lightbulb.scale(0.1) lightbulb.sort_points(np.linalg.norm) lightbulb.next_to(upper_point, RIGHT) self.add(johann) self.wait() self.play(Transform(johann, pensive_johann), Transform(point, bubble), run_time=2) self.remove(point) self.add(bubble) weakling = guys[1] self.play(FadeIn(comparitive_johann), ShowCreation(greater_than), FadeIn(weakling)) self.wait(2) for guy in guys[2:]: self.play(DelayByOrder(Transform(weakling, upper_point))) self.play(FadeIn(guy), ShimmerIn(guy.name_mob)) self.wait(3) self.remove(guy.name_mob) weakling = guy self.play(FadeOut(weakling), FadeOut(greater_than)) self.play(ShowCreation(lightbulb)) self.wait() self.play(FadeOut(comparitive_johann), FadeOut(lightbulb)) self.play(ApplyMethod(Mobject(johann, bubble).scale, 10, run_time=3))
def add_title(self, title = "Sample space", buff = MED_SMALL_BUFF): ##TODO, should this really exist in SampleSpaceScene title_mob = TextMobject(title) if title_mob.get_width() > self.get_width(): title_mob.scale_to_fit_width(self.get_width()) title_mob.next_to(self, UP, buff = buff) self.title = title_mob self.add(title_mob)
def show_pendulum(self, arc_angle = np.pi, arc_color = GREEN): words = TextMobject(": Instantaneous center of rotation") words.next_to(self.c_label) line = Line(self.p_point, self.c_point) line_angle = line.get_angle()+np.pi line_length = line.get_length() line.add(self.p_dot.copy()) line.get_center = lambda : self.c_point tangent_line = Line(3*LEFT, 3*RIGHT) tangent_line.rotate(line_angle-np.pi/2) tangent_line.shift(self.p_point) tangent_line.highlight(arc_color) right_angle_symbol = Mobject( Line(UP, UP+RIGHT), Line(UP+RIGHT, RIGHT) ) right_angle_symbol.scale(0.3) right_angle_symbol.rotate(tangent_line.get_angle()+np.pi) right_angle_symbol.shift(self.p_point) self.play(ShowCreation(line)) self.play(ShimmerIn(words)) self.wait() pairs = [ (line_angle, arc_angle/2), (line_angle+arc_angle/2, -arc_angle), (line_angle-arc_angle/2, arc_angle/2), ] arcs = [] for start, angle in pairs: arc = Arc( angle = angle, radius = line_length, start_angle = start, color = GREEN ) arc.shift(self.c_point) self.play( ShowCreation(arc), ApplyMethod( line.rotate_in_place, angle, path_func = path_along_arc(angle) ), run_time = 2 ) arcs.append(arc) self.wait() self.play(Transform(arcs[1], tangent_line)) self.add(tangent_line) self.play(ShowCreation(right_angle_symbol)) self.wait() self.tangent_line = tangent_line self.right_angle_symbol = right_angle_symbol self.pc_line = line self.remove(words, *arcs)
def show_pendulum(self, arc_angle = np.pi, arc_color = GREEN): words = TextMobject(": Instantaneous center of rotation") words.next_to(self.c_label) line = Line(self.p_point, self.c_point) line_angle = line.get_angle()+np.pi line_length = line.get_length() line.add(self.p_dot.copy()) line.get_center = lambda : self.c_point tangent_line = Line(3*LEFT, 3*RIGHT) tangent_line.rotate(line_angle-np.pi/2) tangent_line.shift(self.p_point) tangent_line.highlight(arc_color) right_angle_symbol = Mobject( Line(UP, UP+RIGHT), Line(UP+RIGHT, RIGHT) ) right_angle_symbol.scale(0.3) right_angle_symbol.rotate(tangent_line.get_angle()+np.pi) right_angle_symbol.shift(self.p_point) self.play(ShowCreation(line)) self.play(ShimmerIn(words)) self.dither() pairs = [ (line_angle, arc_angle/2), (line_angle+arc_angle/2, -arc_angle), (line_angle-arc_angle/2, arc_angle/2), ] arcs = [] for start, angle in pairs: arc = Arc( angle = angle, radius = line_length, start_angle = start, color = GREEN ) arc.shift(self.c_point) self.play( ShowCreation(arc), ApplyMethod( line.rotate_in_place, angle, path_func = path_along_arc(angle) ), run_time = 2 ) arcs.append(arc) self.dither() self.play(Transform(arcs[1], tangent_line)) self.add(tangent_line) self.play(ShowCreation(right_angle_symbol)) self.dither() self.tangent_line = tangent_line self.right_angle_symbol = right_angle_symbol self.pc_line = line self.remove(words, *arcs)
def rearrange(self): sqrt_nudge = 0.2*LEFT y, equals = self.y_equals.split() d, sin, squared, theta = self.y_expression.split() y_sqrt = TexMobject("\\sqrt{\\phantom{y}}") d_sqrt = y_sqrt.copy() y_sqrt.shift(y.get_center()+sqrt_nudge) d_sqrt.shift(d.get_center()+sqrt_nudge) self.play( ShimmerIn(y_sqrt), ShimmerIn(d_sqrt), ApplyMethod(squared.shift, 4*UP), ApplyMethod(theta.shift, 1.5* squared.get_width()*LEFT) ) self.wait() y_sqrt.add(y) d_sqrt.add(d) sin.add(theta) sin_over = TexMobject("\\dfrac{\\phantom{\\sin(\\theta)}}{\\quad}") sin_over.next_to(sin, DOWN, 0.15) new_eq = equals.copy() new_eq.next_to(sin_over, LEFT) one_over = TexMobject("\\dfrac{1}{\\quad}") one_over.next_to(new_eq, LEFT) one_over.shift( (sin_over.get_bottom()[1]-one_over.get_bottom()[1])*UP ) self.play( Transform(equals, new_eq), ShimmerIn(sin_over), ShimmerIn(one_over), ApplyMethod( d_sqrt.next_to, one_over, DOWN, path_func = path_along_arc(-np.pi) ), ApplyMethod( y_sqrt.next_to, sin_over, DOWN, path_func = path_along_arc(-np.pi) ), run_time = 2 ) self.wait() brace = Brace(d_sqrt, DOWN) constant = TextMobject("Constant") constant.next_to(brace, DOWN) self.play( GrowFromCenter(brace), ShimmerIn(constant) )
def rearrange(self): sqrt_nudge = 0.2*LEFT y, equals = self.y_equals.split() d, sin, squared, theta = self.y_expression.split() y_sqrt = TexMobject("\\sqrt{\\phantom{y}}") d_sqrt = y_sqrt.copy() y_sqrt.shift(y.get_center()+sqrt_nudge) d_sqrt.shift(d.get_center()+sqrt_nudge) self.play( ShimmerIn(y_sqrt), ShimmerIn(d_sqrt), ApplyMethod(squared.shift, 4*UP), ApplyMethod(theta.shift, 1.5* squared.get_width()*LEFT) ) self.dither() y_sqrt.add(y) d_sqrt.add(d) sin.add(theta) sin_over = TexMobject("\\dfrac{\\phantom{\\sin(\\theta)}}{\\quad}") sin_over.next_to(sin, DOWN, 0.15) new_eq = equals.copy() new_eq.next_to(sin_over, LEFT) one_over = TexMobject("\\dfrac{1}{\\quad}") one_over.next_to(new_eq, LEFT) one_over.shift( (sin_over.get_bottom()[1]-one_over.get_bottom()[1])*UP ) self.play( Transform(equals, new_eq), ShimmerIn(sin_over), ShimmerIn(one_over), ApplyMethod( d_sqrt.next_to, one_over, DOWN, path_func = path_along_arc(-np.pi) ), ApplyMethod( y_sqrt.next_to, sin_over, DOWN, path_func = path_along_arc(-np.pi) ), run_time = 2 ) self.dither() brace = Brace(d_sqrt, DOWN) constant = TextMobject("Constant") constant.next_to(brace, DOWN) self.play( GrowFromCenter(brace), ShimmerIn(constant) )
def construct(self): grid = Grid(16, 16).fade() snake_curve = SnakeCurve(order=4) words = TextMobject("``Snake Curve''") words.next_to(grid, UP) self.add(grid) self.play(ShowCreation(snake_curve, run_time=7, rate_func=None)) self.dither() self.play(ShimmerIn(words)) self.dither()
def construct(self, with_words): CycloidScene.construct(self) randy = Randolph() randy.scale(RANDY_SCALE_VAL) randy.shift(-randy.get_bottom()) central_randy = randy.copy() start_randy = self.adjust_mobject_to_index( randy.copy(), 1, self.cycloid.points ) if with_words: words1 = TextMobject("Trajectory due to gravity") arrow = TexMobject("\\leftrightarrow") words2 = TextMobject("Trajectory due \\emph{constantly} rotating wheel") words1.next_to(arrow, LEFT) words2.next_to(arrow, RIGHT) words = Mobject(words1, arrow, words2) words.scale_to_fit_width(2*SPACE_WIDTH-1) words.to_edge(UP, buff = 0.2) words.to_edge(LEFT) self.play(ShowCreation(self.cycloid.copy())) self.slide(randy, self.cycloid) self.add(self.slider) self.dither() self.grow_parts() self.draw_cycloid() self.dither() self.play(Transform(self.slider, start_randy)) self.dither() self.roll_back() self.dither() if with_words: self.play(*map(ShimmerIn, [words1, arrow, words2])) self.dither() self.remove(self.circle) start_time = len(self.frames)*self.frame_duration self.remove(self.slider) self.slide(central_randy, self.cycloid) end_time = len(self.frames)*self.frame_duration self.play_over_time_range( start_time, end_time, RollAlongVector( self.circle, self.cycloid.points[-1]-self.cycloid.points[0], run_time = end_time-start_time, rate_func = None ) ) self.add(self.circle, self.slider) self.dither()
def construct(self, with_words): CycloidScene.construct(self) randy = Randolph() randy.scale(RANDY_SCALE_FACTOR) randy.shift(-randy.get_bottom()) central_randy = randy.copy() start_randy = self.adjust_mobject_to_index( randy.copy(), 1, self.cycloid.points ) if with_words: words1 = TextMobject("Trajectory due to gravity") arrow = TexMobject("\\leftrightarrow") words2 = TextMobject("Trajectory due \\emph{constantly} rotating wheel") words1.next_to(arrow, LEFT) words2.next_to(arrow, RIGHT) words = Mobject(words1, arrow, words2) words.scale_to_fit_width(2*SPACE_WIDTH-1) words.to_edge(UP, buff = 0.2) words.to_edge(LEFT) self.play(ShowCreation(self.cycloid.copy())) self.slide(randy, self.cycloid) self.add(self.slider) self.wait() self.grow_parts() self.draw_cycloid() self.wait() self.play(Transform(self.slider, start_randy)) self.wait() self.roll_back() self.wait() if with_words: self.play(*map(ShimmerIn, [words1, arrow, words2])) self.wait() self.remove(self.circle) start_time = len(self.frames)*self.frame_duration self.remove(self.slider) self.slide(central_randy, self.cycloid) end_time = len(self.frames)*self.frame_duration self.play_over_time_range( start_time, end_time, RollAlongVector( self.circle, self.cycloid.points[-1]-self.cycloid.points[0], run_time = end_time-start_time, rate_func = None ) ) self.add(self.circle, self.slider) self.wait()
def construct(self): mathy, bubble = get_mathy_and_bubble() squiggle_mouth = mathy.mouth.copy() squiggle_mouth.apply_function( lambda (x, y, z) : (x, y+0.02*np.sin(50*x), z) ) bubble.ingest_submobjects() bubble.write("Why not use a Hilbert curve \\textinterrobang ") words1 = bubble.content bubble.write("So, it's not one curve but an infinite family of curves \\dots") words2 = bubble.content bubble.write("Well, no, it \\emph{is} just one thing, but I need \\\\ \ to tell you about a certain infinite family first.") words3 = bubble.content description = TextMobject("Mathematician friend", size = "\\small") description.next_to(mathy, buff = 2) arrow = Arrow(description, mathy) self.add(mathy) self.play( ShowCreation(arrow), ShimmerIn(description) ) self.dither() point = Point(bubble.get_tip()) self.play( Transform(point, bubble), ) self.remove(point) self.add(bubble) self.play(ShimmerIn(words1)) self.dither() self.remove(description, arrow) self.play( Transform(mathy.mouth, squiggle_mouth), ApplyMethod(mathy.arm.wag, 0.2*RIGHT, LEFT), ) self.remove(words1) self.add(words2) self.dither(2) self.remove(words2) self.add(words3) self.dither(2) self.play( ApplyPointwiseFunction( lambda p : 15*p/np.linalg.norm(p), bubble ), ApplyMethod(mathy.shift, 5*(DOWN+LEFT)), FadeOut(words3), run_time = 3 )
def construct(self): left_words = TextMobject("Infinite result") right_words = TextMobject("Finite world") for words in left_words, right_words: words.scale(0.8) left_formula = TexMobject( "\\sum_{n = 0}^{\\infty} 2^n = -1" ) right_formula = TexMobject("111\\cdots111") for formula in left_formula, right_formula: formula.add( Brace(formula, UP), ) formula.ingest_sub_mobjects() right_overwords = TextMobject( "\\substack{\ \\text{How computers} \\\\ \ \\text{represent $-1$}\ }" ).scale(1.5) left_mobs = [left_words, left_formula] right_mobs = [right_words, right_formula] for mob in left_mobs: mob.to_edge(RIGHT, buff = 1) mob.shift(SPACE_WIDTH*LEFT) for mob in right_mobs: mob.to_edge(LEFT, buff = 1) mob.shift(SPACE_WIDTH*RIGHT) arrow = Arrow(left_words, right_words) right_overwords.next_to(right_formula, UP) self.play(ShimmerIn(left_words)) self.play(ShowCreation(arrow)) self.play(ShimmerIn(right_words)) self.dither() self.play( ShimmerIn(left_formula), ApplyMethod(left_words.next_to, left_formula, UP) ) self.dither() self.play( ShimmerIn(right_formula), Transform(right_words, right_overwords) ) self.dither() self.finite_analog( Mobject(left_formula, left_words), arrow, Mobject(right_formula, right_words) )
def construct(self): self.add_layers() brace = Brace(Mobject(Point(self.top), Point(self.get_bottom())), RIGHT) n_layers = TextMobject("$n$ layers") n_layers.next_to(brace) self.dither() self.add(brace) self.show_frame() self.play(GrowFromCenter(brace), GrowFromCenter(n_layers)) self.dither()
def add_rod_and_ring(self, rod, ring): rod_word = TextMobject("Rod") rod_word.next_to(Point(), UP) ring_word = TextMobject("Ring") ring_word.next_to(ring, UP) self.dither() self.add(rod) self.play(ShimmerIn(rod_word)) self.dither() self.remove(rod_word) self.play(ShowCreation(ring)) self.play(ShimmerIn(ring_word)) self.dither() self.remove(ring_word)
def construct(self): image = ImageMobject("lion", invert=False) image.scale(0.5) image.shift(2 * LEFT) self.add(image) for vect, num in zip([DOWN, RIGHT], [1, 2]): brace = Brace(image, vect) words_mob = TextMobject("Dimension %d" % num) words_mob.next_to(image, vect, buff=1) self.play(Transform(Point(brace.get_center()), brace), ShimmerIn(words_mob), 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 add_rod_and_ring(self, rod, ring): rod_word = TextMobject("Rod") rod_word.next_to(Point(), UP) ring_word = TextMobject("Ring") ring_word.next_to(ring, UP) self.wait() self.add(rod) self.play(ShimmerIn(rod_word)) self.wait() self.remove(rod_word) self.play(ShowCreation(ring)) self.play(ShimmerIn(ring_word)) self.wait() self.remove(ring_word)
def construct(self): grid = Grid(16, 16).fade() snake_curve = SnakeCurve(order = 4) words = TextMobject("``Snake Curve''") words.next_to(grid, UP) self.add(grid) self.play(ShowCreation( snake_curve, run_time = 7, rate_func = None )) self.dither() self.play(ShimmerIn(words)) self.dither()
def finite_analog(self, left_mob, arrow, right_mob): self.clear() self.add(left_mob, arrow, right_mob) ex = TextMobject("\\times") ex.highlight(RED) # ex.shift(arrow.get_center()) middle = TexMobject( "\\sum_{n=0}^N 2^n \\equiv -1 \\mod 2^{N+1}" ) finite_analog = TextMobject("Finite analog") finite_analog.scale(0.8) brace = Brace(middle, UP) finite_analog.next_to(brace, UP) new_left = left_mob.copy().to_edge(LEFT) new_right = right_mob.copy().to_edge(RIGHT) left_arrow, right_arrow = [ Arrow( mob1.get_right()[0]*RIGHT, mob2.get_left()[0]*RIGHT, buff = 0 ) for mob1, mob2 in [ (new_left, middle), (middle, new_right) ] ] for mob in ex, middle: mob.sort_points(np.linalg.norm) self.play(GrowFromCenter(ex)) self.dither() self.play( Transform(left_mob, new_left), Transform(arrow.copy(), left_arrow), DelayByOrder(Transform(ex, middle)), Transform(arrow, right_arrow), Transform(right_mob, new_right) ) self.play( GrowFromCenter(brace), ShimmerIn(finite_analog) ) self.dither() self.equivalence( left_mob, left_arrow, Mobject(middle, brace, finite_analog) )
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): kwargs = {"size": "\\Large"} left = TextMobject("Speed of light is constant", **kwargs) arrow = TexMobject("\\Rightarrow", **kwargs) right = TextMobject("Staight path is fastest", **kwargs) left.next_to(arrow, LEFT) right.next_to(arrow, RIGHT) squaggle, line = self.get_paths() self.play(*map(ShimmerIn, [left, arrow, right])) self.play(ShowCreation(squaggle)) self.play( self.photon_run_along_path(squaggle, run_time=2, rate_func=None)) self.play(Transform(squaggle, line, path_func=path_along_arc(np.pi))) self.play(self.photon_run_along_path(line, rate_func=None)) self.wait()
def construct(self): image = ImageMobject("lion", invert = False) image.scale(0.5) image.shift(2*LEFT) self.add(image) for vect, num in zip([DOWN, RIGHT], [1, 2]): brace = Brace(image, vect) words_mob = TextMobject("Dimension %d"%num) words_mob.next_to(image, vect, buff = 1) self.play( Transform(Point(brace.get_center()), brace), ShimmerIn(words_mob), run_time = 2 ) self.dither()
def construct(self): curve = PeanoCurve(order = 5) curve.stretch_to_fit_width(2*SPACE_WIDTH) curve.stretch_to_fit_height(2*SPACE_HEIGHT) curve_start = curve.copy() curve_start.apply_over_attr_arrays( lambda arr : arr[:200] ) time_line = get_time_line() time_line.shift(-time_line.number_to_point(2000)) self.add(time_line) self.play(ApplyMethod( time_line.shift, -time_line.number_to_point(1900), run_time = 3 )) brace = Brace( Mobject( Point(time_line.number_to_point(1865)), Point(time_line.number_to_point(1888)), ), UP ) words = TextMobject(""" Cantor drives himself (and the \\\\ mathematical community at large) \\\\ crazy with research on infinity. """) words.next_to(brace, UP) self.play( GrowFromCenter(brace), ShimmerIn(words) ) self.dither() self.play( Transform(time_line, curve_start), FadeOut(brace), FadeOut(words) ) self.play(ShowCreation( curve, run_time = 5, rate_func = None )) self.dither()
def setup_axes(self, animate = True): x_num_range = float(self.x_max - self.x_min) x_axis = NumberLine( x_min = self.x_min, x_max = self.x_max, space_unit_to_num = self.x_axis_width/x_num_range, tick_frequency = self.x_tick_frequency, leftmost_tick = self.x_leftmost_tick or self.x_min, numbers_with_elongated_ticks = self.x_labeled_nums, color = self.axes_color ) x_axis.shift(self.graph_origin - x_axis.number_to_point(0)) if self.x_labeled_nums: x_axis.add_numbers(*self.x_labeled_nums) x_label = TextMobject(self.x_axis_label) x_label.next_to(x_axis, RIGHT+UP, buff = SMALL_BUFF) x_label.shift_onto_screen() x_axis.add(x_label) self.x_axis_label_mob = x_label y_num_range = float(self.y_max - self.y_min) y_axis = NumberLine( x_min = self.y_min, x_max = self.y_max, space_unit_to_num = self.y_axis_height/y_num_range, tick_frequency = self.y_tick_frequency, leftmost_tick = self.y_bottom_tick or self.y_min, numbers_with_elongated_ticks = self.y_labeled_nums, color = self.axes_color ) y_axis.shift(self.graph_origin-y_axis.number_to_point(0)) y_axis.rotate(np.pi/2, about_point = y_axis.number_to_point(0)) if self.y_labeled_nums: y_axis.add_numbers(*self.y_labeled_nums) y_axis.numbers.shift(self.y_axis_numbers_nudge) y_label = TextMobject(self.y_axis_label) y_label.next_to(y_axis.get_top(), RIGHT, buff = 2*MED_BUFF) y_label.shift_onto_screen() y_axis.add(y_label) self.y_axis_label_mob = y_label if animate: self.play(Write(VGroup(x_axis, y_axis))) else: selfe.add(x_axis, y_axis_label) self.x_axis, self.y_axis = x_axis, y_axis
def setup_axes(self, animate=True): x_num_range = float(self.x_max - self.x_min) self.space_unit_to_x = self.x_axis_width / x_num_range x_axis = NumberLine(x_min=self.x_min, x_max=self.x_max, space_unit_to_num=self.space_unit_to_x, tick_frequency=self.x_tick_frequency, leftmost_tick=self.x_leftmost_tick or self.x_min, numbers_with_elongated_ticks=self.x_labeled_nums, color=self.axes_color) x_axis.shift(self.graph_origin - x_axis.number_to_point(0)) if self.x_labeled_nums: x_axis.add_numbers(*self.x_labeled_nums) x_label = TextMobject(self.x_axis_label) x_label.next_to(x_axis, RIGHT + UP, buff=SMALL_BUFF) x_label.shift_onto_screen() x_axis.add(x_label) self.x_axis_label_mob = x_label y_num_range = float(self.y_max - self.y_min) self.space_unit_to_y = self.y_axis_height / y_num_range y_axis = NumberLine(x_min=self.y_min, x_max=self.y_max, space_unit_to_num=self.space_unit_to_y, tick_frequency=self.y_tick_frequency, leftmost_tick=self.y_bottom_tick or self.y_min, numbers_with_elongated_ticks=self.y_labeled_nums, color=self.axes_color) y_axis.shift(self.graph_origin - y_axis.number_to_point(0)) y_axis.rotate(np.pi / 2, about_point=y_axis.number_to_point(0)) if self.y_labeled_nums: y_axis.add_numbers(*self.y_labeled_nums) y_axis.numbers.shift(self.y_axis_numbers_nudge) y_label = TextMobject(self.y_axis_label) y_label.next_to(y_axis.get_top(), RIGHT, buff=2 * MED_BUFF) y_label.shift_onto_screen() y_axis.add(y_label) self.y_axis_label_mob = y_label if animate: self.play(Write(VGroup(x_axis, y_axis))) else: self.add(x_axis, y_axis) self.x_axis, self.y_axis = x_axis, y_axis self.default_graph_colors = it.cycle(self.default_graph_colors)
def get_corner_numbers(self, value, symbol): value_mob = TextMobject(value) width = self.get_width() / self.card_width_to_corner_num_width height = self.get_height() / self.card_height_to_corner_num_height value_mob.scale_to_fit_width(width) value_mob.stretch_to_fit_height(height) value_mob.next_to(self.get_corner(UP + LEFT), DOWN + RIGHT, buff=MED_LARGE_BUFF * width) value_mob.set_color(symbol.get_color()) corner_symbol = symbol.copy() corner_symbol.scale_to_fit_width(width) corner_symbol.next_to(value_mob, DOWN, buff=MED_SMALL_BUFF * width) corner_group = VGroup(value_mob, corner_symbol) opposite_corner_group = corner_group.copy() opposite_corner_group.rotate(np.pi, about_point=self.get_center()) return VGroup(corner_group, opposite_corner_group)
def construct(self): t_axis = NumberLine() theta_axis = NumberLine().rotate(np.pi/2) theta_mob = TexMobject("\\theta(t)") t_mob = TexMobject("t") theta_mob.next_to(theta_axis, RIGHT) theta_mob.to_edge(UP) t_mob.next_to(t_axis, UP) t_mob.to_edge(RIGHT) graph = ParametricFunction( lambda t : 4*t*RIGHT + 2*smooth(t)*UP ) line = Line(graph.points[0], graph.points[-1], color = WHITE) q_mark = TextMobject("?") q_mark.next_to(Point(graph.get_center()), LEFT) stars = Stars(color = BLACK) stars.scale(0.1).shift(q_mark.get_center()) squiggle = ParametricFunction( lambda t : t*RIGHT + 0.2*t*(5-t)*(np.sin(t)**2)*UP, start = 0, end = 5 ) self.play( ShowCreation(t_axis), ShowCreation(theta_axis), ShimmerIn(theta_mob), ShimmerIn(t_mob) ) self.play( ShimmerIn(q_mark), ShowCreation(graph) ) self.dither() self.play( Transform(q_mark, stars), Transform(graph, line) ) self.dither() self.play(Transform(graph, squiggle)) self.dither()
def construct(self): time_line = get_time_line() time_line.shift(-time_line.number_to_point(1900)) hilbert_curve = HilbertCurve(order = 3) peano_curve = PeanoCurve(order = 2) for curve in hilbert_curve, peano_curve: curve.scale(0.5) hilbert_curve.to_corner(DOWN+RIGHT) peano_curve.to_corner(UP+LEFT) squares = Mobject(*[ Square(side_length=3, color=WHITE).replace(curve) for curve in hilbert_curve, peano_curve ]) self.add(time_line) self.dither() for year, curve, vect, text in [ (1890, peano_curve, UP, "Peano Curve"), (1891, hilbert_curve, DOWN, "Hilbert Curve"), ]: point = time_line.number_to_point(year) point[1] = 0.2 arrow = Arrow(point+2*vect, point, buff = 0.1) arrow.gradient_highlight(curve.start_color, curve.end_color) year_mob = TexMobject(str(year)) year_mob.next_to(arrow, vect) words = TextMobject(text) words.next_to(year_mob, vect) self.play( ShowCreation(arrow), ShimmerIn(year_mob), ShimmerIn(words) ) self.play(ShowCreation(curve)) self.dither() self.play(ShowCreation(squares)) self.dither() self.play(ApplyMethod( Mobject(*self.mobjects).shift, 20*(DOWN+RIGHT) ))
def construct(self): time_line = get_time_line() time_line.shift(-time_line.number_to_point(1900)) hilbert_curve = HilbertCurve(order = 3) peano_curve = PeanoCurve(order = 2) for curve in hilbert_curve, peano_curve: curve.scale(0.5) hilbert_curve.to_corner(DOWN+RIGHT) peano_curve.to_corner(UP+LEFT) squares = Mobject(*[ Square(side_length=3, color=WHITE).replace(curve) for curve in hilbert_curve, peano_curve ]) self.add(time_line) self.wait() for year, curve, vect, text in [ (1890, peano_curve, UP, "Peano Curve"), (1891, hilbert_curve, DOWN, "Hilbert Curve"), ]: point = time_line.number_to_point(year) point[1] = 0.2 arrow = Arrow(point+2*vect, point, buff = 0.1) arrow.gradient_highlight(curve.start_color, curve.end_color) year_mob = TexMobject(str(year)) year_mob.next_to(arrow, vect) words = TextMobject(text) words.next_to(year_mob, vect) self.play( ShowCreation(arrow), ShimmerIn(year_mob), ShimmerIn(words) ) self.play(ShowCreation(curve)) self.wait() self.play(ShowCreation(squares)) self.wait() self.play(ApplyMethod( Mobject(*self.mobjects).shift, 20*(DOWN+RIGHT) ))
def construct(self): overtones = 5 floor = 2 * DOWN main_string = Vibrate(color=BLUE_D) component_strings = [ Vibrate(num_periods=k + 1, overtones=1, color=color, center=2 * DOWN + UP * k) for k, color in zip(range(overtones), Color(BLUE_E).range_to(WHITE, overtones)) ] dots = [ Dot(string.mobject.get_center(), color=string.mobject.get_color()) for string in component_strings ] freq_line = get_freq_line() freq_line.shift(floor) freq_line.sort_points(np.linalg.norm) brace = Brace(freq_line, UP) words = TextMobject("Range of frequency values") words.next_to(brace, UP) self.play(*[ TransformAnimations(main_string.copy(), string, run_time=5) for string in component_strings ]) self.clear() self.play(*[ TransformAnimations(string, Animation(dot)) for string, dot in zip(component_strings, dots) ]) self.clear() self.play( ShowCreation(freq_line), GrowFromCenter(brace), ShimmerIn(words), *[ Transform(dot, dot.copy().scale(2).rotate(-np.pi / 2).shift(floor), path_func=path_along_arc(np.pi / 3)) for dot in dots ]) self.dither(0.5)
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): kwargs = {"size" : "\\Large"} left = TextMobject("Speed of light is constant", **kwargs) arrow = TexMobject("\\Rightarrow", **kwargs) right = TextMobject("Staight path is fastest", **kwargs) left.next_to(arrow, LEFT) right.next_to(arrow, RIGHT) squaggle, line = self.get_paths() self.play(*map(ShimmerIn, [left, arrow, right])) self.play(ShowCreation(squaggle)) self.play(self.photon_run_along_path( squaggle, run_time = 2, rate_func = None )) self.play(Transform( squaggle, line, path_func = path_along_arc(np.pi) )) self.play(self.photon_run_along_path(line, rate_func = None)) 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 show_diameter(self): exceptions = [ self.circle, self.tangent_line, self.pc_line, self.right_angle_symbol ] everything = set(self.mobjects).difference(exceptions) everything_copy = Mobject(*everything).copy() light_everything = everything_copy.copy() dark_everything = everything_copy.copy() dark_everything.fade(0.8) bottom_point = np.array(self.c_point) bottom_point += 2*self.radius*DOWN diameter = Line(bottom_point, self.c_point) brace = Brace(diameter, RIGHT) diameter_word = TextMobject("Diameter") d_mob = TexMobject("D") diameter_word.next_to(brace) d_mob.next_to(diameter) self.remove(*everything) self.play(Transform(everything_copy, dark_everything)) self.dither() self.play(ShowCreation(diameter)) self.play(GrowFromCenter(brace)) self.play(ShimmerIn(diameter_word)) self.dither() self.play(*[ Transform(mob, d_mob) for mob in brace, diameter_word ]) self.remove(brace, diameter_word) self.add(d_mob) self.play(Transform(everything_copy, light_everything)) self.remove(everything_copy) self.add(*everything) self.d_mob = d_mob self.bottom_point = bottom_point
def construct(self): CycloidScene.construct(self) equation = TexMobject([ "\\dfrac{\\sin(\\theta)}{\\sqrt{y}}", "= \\text{constant}" ]) sin_sqrt, const = equation.split() new_eq = equation.copy() new_eq.to_edge(UP, buff = 1.3) cycloid_word = TextMobject("Cycloid") arrow = Arrow(2*UP, cycloid_word) arrow.reverse_points() q_mark = TextMobject("?") self.play(*map(ShimmerIn, equation.split())) self.dither() self.play( ApplyMethod(equation.shift, 2.2*UP), ShowCreation(arrow) ) q_mark.next_to(sin_sqrt) self.play(ShimmerIn(cycloid_word)) self.dither() self.grow_parts() self.draw_cycloid() self.dither() extra_terms = [const, arrow, cycloid_word] self.play(*[ Transform(mob, q_mark) for mob in extra_terms ]) self.remove(*extra_terms) self.roll_back() q_marks, arrows = self.get_q_marks_and_arrows(sin_sqrt) self.draw_cycloid(3, ShowCreation(q_marks), ShowCreation(arrows) ) self.dither()
def construct(self): self.add_layers() brace = Brace( Mobject( Point(self.top), Point(self.get_bottom()) ), RIGHT ) n_layers = TextMobject("$n$ layers") n_layers.next_to(brace) self.dither() self.add(brace) self.show_frame() self.play( GrowFromCenter(brace), GrowFromCenter(n_layers) ) self.dither()
def construct(self): grid = Grid(64, 64) space_region = Region() space_mobject = MobjectFromRegion(space_region, DARK_GREY) curve = PeanoCurve(order = 5).replace(space_mobject) line = Line(5*LEFT, 5*RIGHT) line.gradient_highlight(curve.start_color, curve.end_color) for mob in grid, space_mobject: mob.sort_points(np.linalg.norm) infinitely = TextMobject("Infinitely") detailed = TextMobject("detailed") extending = TextMobject("extending") detailed.next_to(infinitely, RIGHT) extending.next_to(infinitely, RIGHT) Mobject(extending, infinitely, detailed).center() arrows = Mobject(*[ Arrow(2*p, 4*p) for theta in np.arange(np.pi/6, 2*np.pi, np.pi/3) for p in [rotate_vector(RIGHT, theta)] ]) self.add(grid) self.dither() self.play(Transform(grid, space_mobject, run_time = 5)) self.remove(grid) self.highlight_region(space_region, DARK_GREY) self.dither() self.add(infinitely, detailed) self.dither() self.play(DelayByOrder(Transform(detailed, extending))) self.play(ShowCreation(arrows)) self.dither() self.clear() self.highlight_region(space_region, DARK_GREY) self.play(ShowCreation(line)) self.play(Transform(line, curve, run_time = 5))
def get_corner_numbers(self, value, symbol): value_mob = TextMobject(value) width = self.get_width()/self.card_width_to_corner_num_width height = self.get_height()/self.card_height_to_corner_num_height value_mob.scale_to_fit_width(width) value_mob.stretch_to_fit_height(height) value_mob.next_to( self.get_corner(UP+LEFT), DOWN+RIGHT, buff = MED_LARGE_BUFF*width ) value_mob.highlight(symbol.get_color()) corner_symbol = symbol.copy() corner_symbol.scale_to_fit_width(width) corner_symbol.next_to( value_mob, DOWN, buff = MED_SMALL_BUFF*width ) corner_group = VGroup(value_mob, corner_symbol) opposite_corner_group = corner_group.copy() opposite_corner_group.rotate( np.pi, about_point = self.get_center() ) return VGroup(corner_group, opposite_corner_group)
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 setup_axes(self, animate = False): x_num_range = float(self.x_max - self.x_min) self.space_unit_to_x = self.x_axis_width/x_num_range self.x_labeled_nums = self.x_labeled_nums or [] x_axis = NumberLine( x_min = self.x_min, x_max = self.x_max, space_unit_to_num = self.space_unit_to_x, tick_frequency = self.x_tick_frequency, leftmost_tick = self.x_leftmost_tick or self.x_min, numbers_with_elongated_ticks = self.x_labeled_nums, color = self.axes_color ) x_axis.shift(self.graph_origin - x_axis.number_to_point(0)) if len(self.x_labeled_nums) > 0: if self.exclude_zero_label: self.x_labeled_nums = filter( lambda x : x != 0, self.x_labeled_nums ) x_axis.add_numbers(*self.x_labeled_nums) x_label = TextMobject(self.x_axis_label) x_label.next_to( x_axis.get_tick_marks(), UP+RIGHT, buff = SMALL_BUFF ) x_label.shift_onto_screen() x_axis.add(x_label) self.x_axis_label_mob = x_label y_num_range = float(self.y_max - self.y_min) self.space_unit_to_y = self.y_axis_height/y_num_range self.y_labeled_nums = self.y_labeled_nums or [] y_axis = NumberLine( x_min = self.y_min, x_max = self.y_max, space_unit_to_num = self.space_unit_to_y, tick_frequency = self.y_tick_frequency, leftmost_tick = self.y_bottom_tick or self.y_min, numbers_with_elongated_ticks = self.y_labeled_nums, color = self.axes_color ) y_axis.shift(self.graph_origin-y_axis.number_to_point(0)) y_axis.rotate(np.pi/2, about_point = y_axis.number_to_point(0)) if len(self.y_labeled_nums) > 0: if self.exclude_zero_label: self.y_labeled_nums = filter( lambda y : y != 0, self.y_labeled_nums ) y_axis.add_numbers(*self.y_labeled_nums) for mob in y_axis.numbers: mob.next_to(mob.get_center(), LEFT, MED_SMALL_BUFF) mob.shift(self.y_axis_numbers_nudge) y_label = TextMobject(self.y_axis_label) y_label.next_to( y_axis.get_tick_marks(), UP+RIGHT, buff = SMALL_BUFF ) y_label.shift_onto_screen() y_axis.add(y_label) self.y_axis_label_mob = y_label if animate: self.play(Write(VGroup(x_axis, y_axis))) else: self.add(x_axis, y_axis) self.x_axis, self.y_axis = self.axes = VGroup(x_axis, y_axis) self.default_graph_colors = it.cycle(self.default_graph_colors)
def construct(self): names = [ "Johann_Bernoulli2", "Jacob_Bernoulli", "Gottfried_Wilhelm_von_Leibniz", "Newton" ] guys = [ ImageMobject(name, invert = False) for name in names ] johann = guys[0] johann.scale(0.8) pensive_johann = johann.copy() pensive_johann.scale(0.25) pensive_johann.to_corner(DOWN+LEFT) comparitive_johann = johann.copy() template = Square(side_length = 2) comparitive_johann.replace(template) comparitive_johann.shift(UP+LEFT) greater_than = TexMobject(">") greater_than.next_to(comparitive_johann) for guy, name in zip(guys, names)[1:]: guy.replace(template) guy.next_to(greater_than) name_mob = TextMobject(name.replace("_", " ")) name_mob.scale(0.5) name_mob.next_to(guy, DOWN) guy.name_mob = name_mob guy.sort_points(lambda p : np.dot(p, DOWN+RIGHT)) bubble = ThoughtBubble(initial_width = 12) bubble.stretch_to_fit_height(6) bubble.ingest_submobjects() bubble.pin_to(pensive_johann) bubble.shift(DOWN) point = Point(johann.get_corner(UP+RIGHT)) upper_point = Point(comparitive_johann.get_corner(UP+RIGHT)) lightbulb = ImageMobject("Lightbulb", invert = False) lightbulb.scale(0.1) lightbulb.sort_points(np.linalg.norm) lightbulb.next_to(upper_point, RIGHT) self.add(johann) self.dither() self.play( Transform(johann, pensive_johann), Transform(point, bubble), run_time = 2 ) self.remove(point) self.add(bubble) weakling = guys[1] self.play( FadeIn(comparitive_johann), ShowCreation(greater_than), FadeIn(weakling) ) self.dither(2) for guy in guys[2:]: self.play(DelayByOrder(Transform( weakling, upper_point ))) self.play( FadeIn(guy), ShimmerIn(guy.name_mob) ) self.dither(3) self.remove(guy.name_mob) weakling = guy self.play(FadeOut(weakling), FadeOut(greater_than)) self.play(ShowCreation(lightbulb)) self.dither() self.play(FadeOut(comparitive_johann), FadeOut(lightbulb)) self.play(ApplyMethod( Mobject(johann, bubble).scale, 10, run_time = 3 ))