from manimlib.imports import * import displayer as disp from hilbert.curves import \ TransformOverIncreasingOrders, FlowSnake, HilbertCurve, \ SnakeCurve, PeanoCurve from hilbert.section1 import get_mathy_and_bubble from scipy.spatial.distance import cdist def get_time_line(): length = 2.6*FRAME_WIDTH year_range = 400 time_line = NumberLine( numerical_radius = year_range/2, unit_length_to_spatial_width = length/year_range, tick_frequency = 10, leftmost_tick = 1720, number_at_center = 1870, numbers_with_elongated_ticks = list(range(1700, 2100, 100)) ) time_line.sort_points(lambda p : p[0]) time_line.set_color_by_gradient( PeanoCurve.CONFIG["start_color"], PeanoCurve.CONFIG["end_color"] ) time_line.add_numbers( 2020, *list(range(1800, 2050, 50)) ) return time_line class SectionTwo(Scene): def construct(self): self.add(TextMobject("Section 2: Filling space")) self.wait() class HilbertCurveIsPerfect(Scene): def construct(self): curve = HilbertCurve(order = 6) curve.set_color(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() class AskMathematicianFriend(Scene): def construct(self): mathy, bubble = get_mathy_and_bubble() bubble.sort_points(lambda p : np.dot(p, UP+RIGHT)) self.add(mathy) self.wait() self.play(ApplyMethod( mathy.blink, rate_func = squish_rate_func(there_and_back) )) self.wait() self.play(ShowCreation(bubble)) self.wait() self.play( ApplyMethod(mathy.shift, 3*(DOWN+LEFT)), ApplyPointwiseFunction( lambda p : 15*p/get_norm(p), bubble ), run_time = 3 ) class TimeLineAboutSpaceFilling(Scene): def construct(self): curve = PeanoCurve(order = 5) curve.stretch_to_fit_width(FRAME_WIDTH) curve.stretch_to_fit_height(FRAME_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.wait() self.play( Transform(time_line, curve_start), FadeOut(brace), FadeOut(words) ) self.play(ShowCreation( curve, run_time = 5, rate_func=linear )) self.wait() class NotPixelatedSpace(Scene): 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.set_color_by_gradient(curve.start_color, curve.end_color) for mob in grid, space_mobject: mob.sort_points(get_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.wait() self.play(Transform(grid, space_mobject, run_time = 5)) self.remove(grid) self.set_color_region(space_region, DARK_GREY) self.wait() self.add(infinitely, detailed) self.wait() self.play(DelayByOrder(Transform(detailed, extending))) self.play(ShowCreation(arrows)) self.wait() self.clear() self.set_color_region(space_region, DARK_GREY) self.play(ShowCreation(line)) self.play(Transform(line, curve, run_time = 5)) class HistoryOfDiscover(Scene): 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.set_color_by_gradient(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) )) class DefinitionOfCurve(Scene): 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() class PseudoHilbertCurvesDontFillSpace(Scene): 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.wait() 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.set_color( Color(rgb = curve.rgbas[curve.get_num_points()/3]) ) square.shift( grid.get_corner(UP+LEFT)-\ square.get_corner(UP+LEFT) ) self.wait() self.play( FadeOut(grid), FadeOut(curve), FadeIn(square) ) self.play( ApplyMethod(square.replace, grid) ) self.wait() class HilbertCurveIsLimit(Scene): def construct(self): mathy, bubble = get_mathy_and_bubble() bubble.write( "A Hilbert curve is the \\\\ limit of all these \\dots" ) self.add(mathy, bubble) self.play(ShimmerIn(bubble.content)) self.wait() class DefiningCurves(Scene): 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.wait() self.play( FadeOut(words), ApplyMethod(curves1.replace, curves2), ShimmerIn(top_words.split()[1]) ) self.wait() self.play(FadeIn(number)) self.play(ShowCreation(arrow)) self.play(FadeIn(pair)) self.wait() self.play(ShowCreation(number_line)) self.play(ShowCreation(low_arrow)) self.play(ShowCreation(grid)) self.wait() class PseudoHilbertCurveAsFunctionExample(Scene): args_list = [(2,), (3,)] # For subclasses to turn args in the above # list into stings which can be appended to the name @staticmethod def args_to_string(order): return "Order%d"%order @staticmethod def string_to_args(order_str): return int(order_str) 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() class ContinuityRequired(Scene): def construct(self): words = TextMobject([ "A function must be", "\\emph{continuous}", "if it is to represent a curve." ]) words.split()[1].set_color(YELLOW_C) self.add(words) self.wait() class FormalDefinitionOfContinuity(Scene): def construct(self): self.setup() self.label_spaces() self.move_dot() self.label_jump() self.draw_circles() self.vary_circle_sizes() self.discontinuous_point() def setup(self): self.input_color = YELLOW_C self.output_color = RED def spiril(t): theta = 2*np.pi*t return t*np.cos(theta)*RIGHT+t*np.sin(theta)*UP self.spiril1 = ParametricFunction( lambda t : 1.5*RIGHT + DOWN + 2*spiril(t), density = 5*DEFAULT_POINT_DENSITY_1D, ) self.spiril2 = ParametricFunction( lambda t : 5.5*RIGHT + UP - 2*spiril(1-t), density = 5*DEFAULT_POINT_DENSITY_1D, ) Mobject.align_data(self.spiril1, self.spiril2) self.output = Mobject(self.spiril1, self.spiril2) self.output.ingest_submobjects() self.output.set_color(GREEN_A) self.interval = UnitInterval() self.interval.set_width(FRAME_X_RADIUS-1) self.interval.to_edge(LEFT) self.input_dot = Dot(color = self.input_color) self.output_dot = self.input_dot.copy().set_color(self.output_color) left, right = self.interval.get_left(), self.interval.get_right() self.input_homotopy = lambda x_y_z_t : (x_y_z_t[0], x_y_z_t[1], x_y_z_t[3]) + interpolate(left, right, x_y_z_t[3]) output_size = self.output.get_num_points()-1 output_points = self.output.points self.output_homotopy = lambda x_y_z_t1 : (x_y_z_t1[0], x_y_z_t1[1], x_y_z_t1[2]) + output_points[int(x_y_z_t1[3]*output_size)] def get_circles_and_points(self, min_input, max_input): input_left, input_right = [ self.interval.number_to_point(num) for num in (min_input, max_input) ] input_circle = Circle( radius = get_norm(input_left-input_right)/2, color = WHITE ) input_circle.shift((input_left+input_right)/2) input_points = Line( input_left, input_right, color = self.input_color ) output_points = Mobject(color = self.output_color) n = self.output.get_num_points() output_points.add_points( self.output.points[int(min_input*n):int(max_input*n)] ) output_center = output_points.points[int(0.5*output_points.get_num_points())] max_distance = get_norm(output_center-output_points.points[-1]) output_circle = Circle( radius = max_distance, color = WHITE ) output_circle.shift(output_center) return ( input_circle, input_points, output_circle, output_points ) def label_spaces(self): input_space = TextMobject("Input Space") input_space.to_edge(UP) input_space.shift(LEFT*FRAME_X_RADIUS/2) output_space = TextMobject("Output Space") output_space.to_edge(UP) output_space.shift(RIGHT*FRAME_X_RADIUS/2) line = Line( UP*FRAME_Y_RADIUS, DOWN*FRAME_Y_RADIUS, color = WHITE ) self.play( ShimmerIn(input_space), ShimmerIn(output_space), ShowCreation(line), ShowCreation(self.interval), ) self.wait() def move_dot(self): kwargs = { "rate_func" : None, "run_time" : 3 } self.play( Homotopy(self.input_homotopy, self.input_dot, **kwargs), Homotopy(self.output_homotopy, self.output_dot, **kwargs), ShowCreation(self.output, **kwargs) ) self.wait() def label_jump(self): jump_points = Mobject( Point(self.spiril1.points[-1]), Point(self.spiril2.points[0]) ) self.brace = Brace(jump_points, RIGHT) self.jump = TextMobject("Jump") self.jump.next_to(self.brace, RIGHT) self.play( GrowFromCenter(self.brace), ShimmerIn(self.jump) ) self.wait() self.remove(self.brace, self.jump) 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 = list(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 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.wait() 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.wait() self.remove(vary_circles.mobject, text, arrow) 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.wait() 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.wait() self.play(ShimmerIn(text)) self.remove(input_circle, input_points, output_circle, input_points_copy) self.play(vary_circles) self.wait() self.play( ShimmerIn(discontinuous_at_A), ShowCreation(discontinuous_arrow) ) self.wait(3) self.remove(vary_circles.mobject, discontinuous_at_A, discontinuous_arrow) def continuous_point(self): pass class VaryCircles(Animation): def __init__(self, scene, input_value, radius, **kwargs): digest_locals(self) Animation.__init__(self, Mobject(), **kwargs) def interpolate_mobject(self, alpha): radius = self.radius + 0.9*self.radius*np.sin(1.5*np.pi*alpha) self.mobject = Mobject(*self.scene.get_circles_and_points( self.input_value-radius, self.input_value+radius )).ingest_submobjects() class FunctionIsContinuousText(Scene): 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() class DefineActualHilbertCurveText(Scene): def construct(self): self.add(TextMobject(""" Finally define a Hilbert Curve\\dots """)) self.wait() class ReliesOnWonderfulProperty(Scene): def construct(self): self.add(TextMobject(""" \\dots which relies on a certain property of Pseudo-Hilbert-curves. """)) self.wait() class WonderfulPropertyOfPseudoHilbertCurves(Scene): 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].set_color() 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() class FollowManyPoints(Scene): def construct(self): text = TextMobject([ "PHC", "_n", "(", "x", ")$", " has a limit point ", "as $n \\to \\infty$", "\\\\ for all $x$" ]) parts = text.split() parts[-1].next_to(Mobject(*parts[:-1]), DOWN) parts[-1].set_color(BLUE) parts[3].set_color(BLUE) parts[1].set_color() parts[-2].set_color() text.to_edge(UP) curve = UnitInterval() curve.sort_points(lambda p : p[0]) vals = np.arange(0.1, 1, 0.1) dots = Mobject(*[ Dot(curve.number_to_point(val)) for val in vals ]) curve.add_numbers(0, 1) starter_dots = dots.copy().ingest_submobjects() starter_dots.shift(2*UP) self.add(curve, text) self.wait() self.play(DelayByOrder(ApplyMethod(starter_dots.shift, 2*DOWN))) self.wait() self.remove(starter_dots) self.add(dots) for num in range(1, 10): new_curve = HilbertCurve(order = num) new_curve.scale(0.8) new_dots = Mobject(*[ Dot(new_curve.points[int(val*new_curve.get_num_points())]) for val in vals ]) self.play( Transform(curve, new_curve), Transform(dots, new_dots), ) # self.wait() class FormalDefinitionOfHilbertCurve(Scene): def construct(self): val = 0.7 text = TexMobject([ "\\text{HC}(", "x", ")", "=\\lim_{n \\to \\infty}\\text{PHC}_n(", "x", ")" ]) text.to_edge(UP) x1 = text.split()[1] x2 = text.split()[-2] x2.set_color(BLUE) explanation = TextMobject("Actual Hilbert curve function") exp_arrow = Arrow(explanation, text.split()[0]) curve = UnitInterval() dot = Dot(curve.number_to_point(val)) x_arrow = Arrow(x1.get_bottom(), dot, buff = 0) curve.sort_points(lambda p : p[0]) curve.add_numbers(0, 1) self.add(*text.split()[:3]) self.play( ShimmerIn(explanation), ShowCreation(exp_arrow) ) self.wait() self.remove(explanation, exp_arrow) self.play(ShowCreation(curve)) self.play( ApplyMethod(x1.set_color, BLUE), ShowCreation(x_arrow), ShowCreation(dot) ) self.wait() self.remove(x_arrow) limit = Mobject(*text.split()[3:]).ingest_submobjects() limit.stroke_width = 1 self.play(ShimmerIn(limit)) for num in range(1, 9): new_curve = HilbertCurve(order = num) new_curve.scale(0.8) new_dot = Dot(new_curve.points[int(val*new_curve.get_num_points())]) self.play( Transform(curve, new_curve), Transform(dot, new_dot), ) class CouldNotDefineForSnakeCurve(Scene): def construct(self): self.add(TextMobject(""" You could not define a limit curve from snake curves. """)) self.wait() class ThreeThingsToProve(Scene): def construct(self): definition = TexMobject([ "\\text{HC}(", "x", ")", "=\\lim_{n \\to \\infty}\\text{PHC}_n(", "x", ")" ]) definition.to_edge(UP) definition.split()[1].set_color(BLUE) definition.split()[-2].set_color(BLUE) intro = TextMobject("Three things need to be proven") prove_that = TextMobject("Prove that HC is $\\dots$") prove_that.scale(0.7) prove_that.to_edge(LEFT) items = TextMobject([ "\\begin{enumerate}", "\\item Well-defined: ", "Points on Pseudo-Hilbert-curves really do converge", "\\item A Curve: ", "HC is continuous", "\\item Space-filling: ", "Each point in the unit square is an output of HC", "\\end{enumerate}", ]).split() items[1].set_color(GREEN) items[3].set_color(YELLOW_C) items[5].set_color(MAROON) Mobject(*items).to_edge(RIGHT) self.add(definition) self.play(ShimmerIn(intro)) self.wait() self.play(Transform(intro, prove_that)) for item in items[1:-1]: self.play(ShimmerIn(item)) self.wait() class TilingSpace(Scene): def construct(self): coords_set = [ORIGIN] for n in range(int(FRAME_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=linear, run_time = 15 )) class ColorIntervals(Scene): def construct(self): number_line = NumberLine( numerical_radius = 5, number_at_center = 5, leftmost_tick = 0, density = 2*DEFAULT_POINT_DENSITY_1D ) number_line.shift(2*RIGHT) number_line.add_numbers() number_line.scale(2) brace = Brace(Mobject( *number_line.submobjects[:2] )) self.add(number_line) for n in range(0, 10, 2): if n == 0: brace_anim = GrowFromCenter(brace) else: brace_anim = ApplyMethod(brace.shift, 2*RIGHT) self.play( ApplyMethod( number_line.set_color, RED, lambda p : p[0] > n-6.2 and p[0] < n-4 and p[1] > -0.4 ), brace_anim )