def add_lines(self, left, right): line_kwargs = { "color": BLUE, "stroke_width": 2, } left_rows = [VMobject(*row) for row in left.get_mob_matrix()] h_lines = VMobject() for row in left_rows[:-1]: h_line = Line(row.get_left(), row.get_right(), **line_kwargs) h_line.next_to(row, DOWN, buff=left.v_buff / 2.) h_lines.add(h_line) right_cols = [ VMobject(*col) for col in np.transpose(right.get_mob_matrix()) ] v_lines = VMobject() for col in right_cols[:-1]: v_line = Line(col.get_top(), col.get_bottom(), **line_kwargs) v_line.next_to(col, RIGHT, buff=right.h_buff / 2.) v_lines.add(v_line) self.play(ShowCreation(h_lines)) self.play(ShowCreation(v_lines)) self.wait() self.show_frame()
def construct(self): words = TextMobject("Order 3 Pseudo-Hilbert Curve") words.highlight(GREEN) words.to_edge(UP) grid4 = Mobject(Grid(2, 2), Grid(4, 4, point_thickness=2)) grid8 = Grid(8, 8, point_thickness=1) order_3_curve = HilbertCurve(order=3) mini_curves = [ HilbertCurve(order=2).scale(0.5).shift(1.5 * vect) for vect in [LEFT + DOWN, LEFT + UP, RIGHT + UP, RIGHT + DOWN] ] self.add(words, grid4) self.dither() self.play(ShowCreation(grid8)) self.dither() self.play(*map(GrowFromCenter, mini_curves)) self.dither() self.clear() self.add(words, grid8, *mini_curves) self.play(*[ ApplyMethod(curve.rotate_in_place, np.pi, axis) for curve, axis in [(mini_curves[0], UP + RIGHT), (mini_curves[3], UP + LEFT)] ]) self.play(ShowCreation(order_3_curve, run_time=5)) self.dither()
def show_angles(self): words = TextMobject(""" Let's see what happens as we change the angle in this seed """) words.to_edge(UP) koch, sharper_koch, duller_koch = curves = [ CurveClass(order=1) for CurveClass in StraightKoch, SharperKoch, DullerKoch ] arcs = [ Arc(2 * (np.pi / 2 - curve.angle), radius=r, start_angle=np.pi + curve.angle).shift( curve.points[curve.get_num_points() / 2]) for curve, r in zip(curves, [0.6, 0.7, 0.4]) ] theta = TexMobject("\\theta") theta.shift(arcs[0].get_center() + 2.5 * DOWN) arrow = Arrow(theta, arcs[0]) self.add(words, koch) self.play(ShowCreation(arcs[0])) self.play(ShowCreation(arrow), ShimmerIn(theta)) self.wait(2) self.remove(theta, arrow) self.play( Transform(koch, duller_koch), Transform(arcs[0], arcs[2]), ) self.play( Transform(koch, sharper_koch), Transform(arcs[0], arcs[1]), ) self.clear()
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): words = TextMobject([ "One does not simply define the limit \\\\ \ of a sequence of", "curves", "\\dots" ]) top_words = TextMobject(["curves", "are functions"]).to_edge(UP) curves1 = words.split()[1] curves2 = top_words.split()[0] words.ingest_submobjects() number = TexMobject("0.27") pair = TexMobject("(0.53, 0.02)") pair.next_to(number, buff=2) arrow = Arrow(number, pair) Mobject(number, arrow, pair).center().shift(UP) number_line = UnitInterval() number_line.stretch_to_fit_width(5) number_line.to_edge(LEFT).shift(DOWN) grid = Grid(4, 4).scale(0.4) grid.next_to(number_line, buff=2) low_arrow = Arrow(number_line, grid) self.play(ShimmerIn(words)) self.dither() self.play(FadeOut(words), ApplyMethod(curves1.replace, curves2), ShimmerIn(top_words.split()[1])) self.dither() self.play(FadeIn(number)) self.play(ShowCreation(arrow)) self.play(FadeIn(pair)) self.dither() self.play(ShowCreation(number_line)) self.play(ShowCreation(low_arrow)) self.play(ShowCreation(grid)) self.dither()
def construct(self): words = TextMobject("Order 2 Pseudo-Hilbert Curve") words.to_edge(UP, buff=0.3) words.highlight(GREEN) grid2 = Grid(2, 2) grid4 = Grid(4, 4, point_thickness=2) # order_1_curve = HilbertCurve(order = 1) # squaggle_curve = order_1_curve.copy().apply_function( # lambda (x, y, z) : (x + np.cos(3*y), y + np.sin(3*x), z) # ) # squaggle_curve.show() mini_curves = [ HilbertCurve(order=1).scale(0.5).shift(1.5 * vect) for vect in [LEFT + DOWN, LEFT + UP, RIGHT + UP, RIGHT + DOWN] ] last_curve = mini_curves[0] naive_curve = Mobject(last_curve) for mini_curve in mini_curves[1:]: line = Line(last_curve.points[-1], mini_curve.points[0]) naive_curve.add(line, mini_curve) last_curve = mini_curve naive_curve.ingest_sub_mobjects() naive_curve.gradient_highlight(RED, GREEN) order_2_curve = HilbertCurve(order=2) self.add(words, grid2) self.dither() self.play(ShowCreation(grid4)) self.play(*[ShowCreation(mini_curve) for mini_curve in mini_curves]) self.dither() self.play(ShowCreation(naive_curve, run_time=5)) self.remove(*mini_curves) self.dither() self.play(Transform(naive_curve, order_2_curve)) self.dither()
def coords_to_vector(self, vector, coords_start=2 * RIGHT + 2 * UP, clean_up=True): starting_mobjects = list(self.mobjects) array = Matrix(vector) array.shift(coords_start) arrow = Vector(vector) x_line = Line(ORIGIN, vector[0] * RIGHT) y_line = Line(x_line.get_end(), arrow.get_end()) x_line.highlight(X_COLOR) y_line.highlight(Y_COLOR) x_coord, y_coord = array.get_mob_matrix().flatten() self.play(Write(array, run_time=1)) self.dither() self.play( ApplyFunction( lambda x: self.position_x_coordinate(x, x_line, vector), x_coord)) self.play(ShowCreation(x_line)) self.play( ApplyFunction( lambda y: self.position_y_coordinate(y, y_line, vector), y_coord), FadeOut(array.get_brackets())) y_coord, brackets = self.get_mobjects_from_last_animation() self.play(ShowCreation(y_line)) self.play(ShowCreation(arrow)) self.dither() if clean_up: self.clear() self.add(*starting_mobjects)
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 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, 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 construct(self): val = 0.3 text = TextMobject([ "PHC", "$_n", "(", "%3.1f"%val, ")$", " has a ", "limit point ", "as $n \\to \\infty$" ]) func_parts = text.copy().split()[:5] Mobject(*func_parts).center().to_edge(UP) num_str, val_str = func_parts[1], func_parts[3] curve = UnitInterval() curve.sort_points(lambda p : p[0]) dot = Dot().shift(curve.number_to_point(val)) arrow = Arrow(val_str, dot, buff = 0.1) curve.add_numbers(0, 1) self.play(ShowCreation(curve)) self.play( ShimmerIn(val_str), ShowCreation(arrow), ShowCreation(dot) ) self.wait() self.play( FadeOut(arrow), *[ FadeIn(func_parts[i]) for i in 0, 1, 2, 4 ] ) for num in range(2,9): new_curve = HilbertCurve(order = num) new_curve.scale(0.8) new_dot = Dot(new_curve.points[int(val*new_curve.get_num_points())]) new_num_str = TexMobject(str(num)).replace(num_str) self.play( Transform(curve, new_curve), Transform(dot, new_dot), Transform(num_str, new_num_str) ) self.wait() text.to_edge(UP) text_parts = text.split() for index in 1, -1: text_parts[index].highlight() starters = Mobject(*func_parts + [ Point(mob.get_center(), stroke_width=1) for mob in text_parts[5:] ]) self.play(Transform(starters, text)) arrow = Arrow(text_parts[-2].get_bottom(), dot, buff = 0.1) self.play(ShowCreation(arrow)) self.wait()
def construct(self, order): start_color, end_color = RED, GREEN curve = HilbertCurve(order = order) line = Line(5*LEFT, 5*RIGHT) for mob in curve, line: mob.gradient_highlight(start_color, end_color) freq_line = get_freq_line() freq_line.replace(line, stretch = True) unit = 6./(2**order) #sidelength of pixel up = unit*UP right = unit*RIGHT lower_left = 3*(LEFT+DOWN) squares = Mobject(*[ Square( side_length = unit, color = WHITE ).shift(x*right+y*up) for x, y in it.product(range(2**order), range(2**order)) ]) squares.center() targets = Mobject() for square in squares.submobjects: center = square.get_center() distances = np.apply_along_axis( lambda p : np.linalg.norm(p-center), 1, curve.points ) index_along_curve = np.argmin(distances) fraction_along_curve = index_along_curve/float(curve.get_num_points()) target = square.copy().center().scale(0.8/(2**order)) line_index = int(fraction_along_curve*line.get_num_points()) target.shift(line.points[line_index]) targets.add(target) self.add(squares) self.play(ShowCreation( curve, run_time = 5, rate_func = None )) self.dither() self.play( Transform(curve, line), Transform(squares, targets), run_time = 3 ) self.dither() self.play(ShowCreation(freq_line)) self.dither()
def construct(self): grid = get_grid() grid.scale_to_fit_width(6) grid.to_edge(LEFT) freq_line = get_freq_line() freq_line.scale_to_fit_width(6) freq_line.center().to_edge(RIGHT) arrow = Arrow(grid, freq_line) color1, color2 = YELLOW_C, RED square_length = 0.01 dot1 = Dot(color = color1) dot1.shift(3*RIGHT) dot2 = Dot(color = color2) dot2.shift(3.1*RIGHT) arrow1 = Arrow(2*RIGHT+UP, dot1, color = color1, buff = 0.1) arrow2 = Arrow(4*RIGHT+UP, dot2, color = color2, buff = 0.1) dot3, arrow3 = [ mob.copy().shift(5*LEFT+UP) for mob in dot1, arrow1 ] dot4, arrow4 = [ mob.copy().shift(5*LEFT+0.9*UP) for mob in dot2, arrow2 ] self.add(grid, freq_line, arrow) self.dither() self.play(ApplyMethod( arrow.rotate, np.pi, path_func = clockwise_path() )) self.dither() self.play(ShowCreation(arrow1)) self.add(dot1) self.play(ShowCreation(arrow2)) self.add(dot2) self.dither() self.remove(arrow1, arrow2) self.play( Transform(dot1, dot3), Transform(dot2, dot4) ) self.play( ApplyMethod(grid.fade, 0.8), Animation(Mobject(dot3, dot4)) ) self.play(ShowCreation(arrow3)) self.play(ShowCreation(arrow4)) self.dither()
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): big_grid_dim = 20. small_grid_dim = 6. big_grid = Grid(64, 64, height=big_grid_dim, width=big_grid_dim) big_grid.to_corner(UP + RIGHT, buff=2) small_grid = big_grid.copy() small_grid.scale(small_grid_dim / big_grid_dim) small_grid.center() pixel = MobjectFromRegion( region_from_polygon_vertices( *0.2 * np.array([RIGHT + DOWN, RIGHT + UP, LEFT + UP, LEFT + DOWN]))) pixel.set_color(WHITE) pixel_width = big_grid.width / big_grid.columns pixel.scale_to_fit_width(pixel_width) pixel.to_corner(UP + RIGHT, buff=2) pixel.shift(5 * pixel_width * (2 * LEFT + DOWN)) freq_line = get_freq_line() dot = Dot() dot.shift(freq_line.get_center() + 2 * RIGHT) string = Line(LEFT, RIGHT, color=GREEN) arrow = Arrow(dot, string.get_center()) vibration_config = { "overtones": 1, "spatial_period": 2, } vibration, loud_vibration, quiet_vibration = [ Vibrate(string.copy(), amplitude=a, **vibration_config) for a in [0.5, 1., 0.25] ] self.add(small_grid) self.dither() self.play(Transform(small_grid, big_grid)) self.play(FadeIn(pixel)) self.dither() self.play(FadeOut(small_grid), ShowCreation(freq_line)) self.remove(small_grid) self.play(Transform(pixel, dot), ) self.dither() self.play(ShowCreation(arrow)) self.play(loud_vibration) self.play(TransformAnimations(loud_vibration, quiet_vibration), ApplyMethod(dot.fade, 0.9)) self.clear() self.add(freq_line, dot, arrow) self.play(quiet_vibration)
def add_vector(self, vector, color=YELLOW, animate=True, **kwargs): if not isinstance(vector, Arrow): vector = Vector(vector, color=color, **kwargs) if animate: self.play(ShowCreation(vector)) self.add(vector) return vector
def construct(self): coords_set = [ORIGIN] for n in range(int(2*SPACE_WIDTH)): for vect in UP, RIGHT: for k in range(n): new_coords = coords_set[-1]+((-1)**n)*vect coords_set.append(new_coords) square = Square(side_length = 1, color = WHITE) squares = Mobject(*[ square.copy().shift(coords) for coords in coords_set ]).ingest_submobjects() self.play( DelayByOrder(FadeIn(squares)), run_time = 3 ) curve = HilbertCurve(order = 6).scale(1./6) all_curves = Mobject(*[ curve.copy().shift(coords) for coords in coords_set ]).ingest_submobjects() all_curves.thin_out(10) self.play(ShowCreation( all_curves, rate_func = None, run_time = 15 ))
def increase_order(self): mini_curves = [ self.curve.copy().scale(0.5).shift(1.5*vect) for vect in [ LEFT+DOWN, LEFT+UP, RIGHT+UP, RIGHT+DOWN ] ] self.remove(self.curve) self.play( Transform(self.curve.copy(), mini_curves[0]) ) self.play(*[ GrowFromCenter(mini_curve) for mini_curve in mini_curves[1:] ]) self.dither() self.clear() self.add(*mini_curves) self.play(*[ ApplyMethod(curve.rotate_in_place, np.pi, axis) for curve, axis in [ (mini_curves[0], UP+RIGHT), (mini_curves[3], UP+LEFT) ] ]) self.curve = HilbertCurve(order = self.curve.order+1) self.play(ShowCreation(self.curve, run_time = 2)) self.remove(*mini_curves) self.dither()
def __init__(self, pi_creature, *content, **kwargs): digest_config(self, kwargs) bubble = pi_creature.get_bubble("speech") bubble.write(*content) bubble.resize_to_content() bubble.pin_to(pi_creature) pi_creature.bubble = bubble AnimationGroup.__init__( self, ApplyMethod( pi_creature.change_mode, self.target_mode, **self.change_mode_kwargs ), ShowCreation( bubble, **self.bubble_creation_kwargs ), Write( bubble.content, **self.write_kwargs ), **kwargs )
def construct(self): curve = HilbertCurve(order=1) grid = Grid(2, 2, stroke_width=1) self.add(grid, curve) for order in range(2, 6): self.dither() new_grid = Grid(2**order, 2**order, stroke_width=1) self.play(ShowCreation(new_grid), Animation(curve)) self.remove(grid) grid = new_grid self.play(Transform(curve, HilbertCurve(order=order))) square = Square(side_length=6, color=WHITE) square.corner = Mobject1D() square.corner.add_line(3 * DOWN, ORIGIN) square.corner.add_line(ORIGIN, 3 * RIGHT) square.digest_mobject_attrs() square.scale(2**(-5)) square.corner.highlight( Color(rgb=curve.rgbs[curve.get_num_points() / 3])) square.shift( grid.get_corner(UP+LEFT)-\ square.get_corner(UP+LEFT) ) self.dither() self.play(FadeOut(grid), FadeOut(curve), FadeIn(square)) self.play(ApplyMethod(square.replace, grid)) self.dither()
def construct(self): start_curve = SnakeCurve(order = 6) end_curve = SnakeCurve(order = 7) start_dots, end_dots = [ Mobject(*[ Dot( curve.points[int(x*curve.get_num_points())], color = color ) for x, color in [ (0.202, GREEN), (0.48, BLUE), (0.7, RED) ] ]) for curve in start_curve, end_curve ] self.add(start_curve) self.dither() self.play( ShowCreation(start_dots, run_time = 2), ApplyMethod(start_curve.fade) ) end_curve.fade() self.play( Transform(start_curve, end_curve), Transform(start_dots, end_dots) ) self.dither()
def construct(self): scale_factor = 0.9 grid = Grid(4, 4, stroke_width=1) curve = HilbertCurve(order=2) for mob in grid, curve: mob.scale(scale_factor) words = TextMobject(""" Sequence of curves is stable $\\leftrightarrow$ existence of limit curve """, size="\\normal") words.scale(1.25) words.to_edge(UP) self.add(curve, grid) self.wait() for n in range(3, 7): if n == 5: self.play(ShimmerIn(words)) new_grid = Grid(2**n, 2**n, stroke_width=1) new_curve = HilbertCurve(order=n) for mob in new_grid, new_curve: mob.scale(scale_factor) self.play(ShowCreation(new_grid), Animation(curve)) self.remove(grid) grid = new_grid self.play(Transform(curve, new_curve)) self.wait()
def construct(self): curve = HilbertCurve(order = 6) curve.highlight(WHITE) colored_curve = curve.copy() colored_curve.thin_out(3) lion = ImageMobject("lion", invert = False) lion.replace(curve, stretch = True) sparce_lion = lion.copy() sparce_lion.thin_out(100) distance_matrix = cdist(colored_curve.points, sparce_lion.points) closest_point_indices = np.apply_along_axis( np.argmin, 1, distance_matrix ) colored_curve.rgbas = sparce_lion.rgbas[closest_point_indices] line = Line(5*LEFT, 5*RIGHT) Mobject.align_data(line, colored_curve) line.rgbas = colored_curve.rgbas self.add(lion) self.play(ShowCreation(curve, run_time = 3)) self.play( FadeOut(lion), Transform(curve, colored_curve), run_time = 3 ) self.wait() self.play(Transform(curve, line, run_time = 5)) self.wait()
def graph_function( self, func, color=BLUE, animate=False, is_main_graph=True, ): def parameterized_function(alpha): x = interpolate(self.x_min, self.x_max, alpha) return self.coords_to_point(x, func(x)) graph = ParametricFunction( parameterized_function, color=color, num_anchor_points=self.num_graph_anchor_points, ) graph.underlying_function = func if is_main_graph: self.graph = graph self.func = func if animate: self.play(ShowCreation(graph)) self.add(graph) return graph
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_arrows(self, true_length = False): if not hasattr(self, "function"): raise Exception("Must run use_function first") points = self.get_points(self.arrow_spacing) points = filter( lambda p : np.linalg.norm(self.function(p)) > 0.01, points ) angles = map(angle_of_vector, map(self.function, points)) prototype = Arrow( ORIGIN, RIGHT*self.arrow_spacing/2., color = self.arrow_color, tip_length = 0.1, buff = 0 ) arrows = [] for point in points: arrow = prototype.copy() output = self.function(point) if true_length: arrow.scale(np.linalg.norm(output)) arrow.rotate(angle_of_vector(output)) arrow.shift(point) arrows.append(arrow) self.arrows = Mobject(*arrows) self.play(ShowCreation(self.arrows)) self.dither()
def construct(self, name): run_time = 20 scale_factor = 0.8 image_array = get_image_array(name) edge_mobject = self.get_edge_mobject(image_array) full_picture = MobjectFromPixelArray(image_array) for mob in edge_mobject, full_picture: # mob.stroke_width = 4 mob.scale(scale_factor) mob.show() self.play( DelayByOrder(FadeIn( full_picture, run_time = run_time, rate_func = squish_rate_func(smooth, 0.7, 1) )), ShowCreation( edge_mobject, run_time = run_time, rate_func = None ) ) self.remove(edge_mobject) 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 construct(self): text = TextMobject(""" See links in the description for more on sight via sound. """) self.play(ShimmerIn(text)) self.play(ShowCreation(Arrow(text, 3*DOWN))) self.dither(2)