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.rgbs = sparce_lion.rgbs[closest_point_indices] line = Line(5*LEFT, 5*RIGHT) Mobject.align_data(line, colored_curve) line.rgbs = colored_curve.rgbs self.add(lion) self.play(ShowCreation(curve, run_time = 3)) self.play( FadeOut(lion), Transform(curve, colored_curve), run_time = 3 ) self.dither() self.play(Transform(curve, line, run_time = 5)) self.dither()
def __init__(self, **kwargs): x_axis = NumberLine(**kwargs) y_axis = NumberLine(**kwargs).rotate(np.pi/2, OUT) Mobject.__init__(self, x_axis, y_axis)
def play(self, *animations, **kwargs): self.num_animations += 1 if "run_time" in kwargs: run_time = kwargs["run_time"] else: run_time = animations[0].run_time for animation in animations: animation.set_run_time(run_time) moving_mobjects = [mobject for anim in animations for mobject in anim.mobject.submobject_family()] bundle = Mobject(*self.mobjects) static_mobjects = filter(lambda m: m not in moving_mobjects, bundle.submobject_family()) background = disp.paint_mobjects(static_mobjects, self.background, include_sub_mobjects=False) times = np.arange(0, run_time, self.frame_duration) time_progression = ProgressDisplay(times) time_progression.set_description( "Animation %d: " % self.num_animations + str(animations[0]) + (", etc." if len(animations) > 1 else "") ) for t in time_progression: for animation in animations: animation.update(t / animation.run_time) new_frame = disp.paint_mobjects([anim.mobject for anim in animations], background) self.frames.append(new_frame) for animation in animations: animation.clean_up() self.add(*[anim.mobject for anim in animations]) self.repaint_mojects() return self
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
class Flash(Animation): CONFIG = { "color" : "white", "slow_factor" : 0.01, "run_time" : 0.1, "rate_func" : None, } def __init__(self, mobject, **kwargs): self.intermediate = Mobject(color = self.color) self.intermediate.add_points([ point + (x, y, 0) for point in self.mobject.points for x in [-1, 1] for y in [-1, 1] ]) Animation.__init__(self, mobject, **kwargs) def update_mobject(self, alpha): #Makes alpha go from 0 to slow_factor to 0 instead of 0 to 1 alpha = self.slow_factor * (1.0 - 4 * (alpha - 0.5)**2) self.mobject.interpolate( self.starting_mobject, self.intermediate, alpha )
def __init__(self, *args, **kwargs): Mobject.__init__(self, *args, **kwargs) complex_power = 0.9 radius = self.INITIAL_WIDTH/2 circle = Circle(density = radius*DEFAULT_POINT_DENSITY_1D) circle.apply_complex_function(lambda z : z**complex_power) circle.scale(radius) boundary_point_as_complex = radius*complex(-1)**complex_power boundary_points = [ [ boundary_point_as_complex.real, unit*boundary_point_as_complex.imag, 0 ] for unit in -1, 1 ] tip = radius*(1.5*LEFT+UP) self.add( circle, Line(boundary_points[0], tip), Line(boundary_points[1], tip) ) self.highlight("white") self.rotate(np.pi/2) self.points[:,1] *= float(self.INITIAL_HEIGHT)/self.INITIAL_WIDTH Bubble.__init__(self, direction = LEFT)
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 = np.linalg.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 = np.linalg.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 show_sin_thetas(self): pc = Line(self.p_point, self.c_point) mob = Mobject(self.theta, self.d_mob).copy() mob.ingest_submobjects() triplets = [ (pc, "D\\sin(\\theta)", 0.5), (self.y_line, "D\\sin^2(\\theta)", 0.7), ] for line, tex, scale in triplets: trig_mob = TexMobject(tex) trig_mob.scale_to_fit_width( scale*line.get_length() ) trig_mob.shift(-1.2*trig_mob.get_top()) trig_mob.rotate(line.get_angle()) trig_mob.shift(line.get_center()) if line is self.y_line: trig_mob.shift(0.1*UP) self.play(Transform(mob, trig_mob)) self.add(trig_mob) self.dither() self.remove(mob) self.d_sin_squared_theta = trig_mob
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_sub_mobjects() self.output.highlight(GREEN_A) self.interval = UnitInterval() self.interval.scale_to_fit_width(SPACE_WIDTH-1) self.interval.to_edge(LEFT) self.input_dot = Dot(color = self.input_color) self.output_dot = self.input_dot.copy().highlight(self.output_color) left, right = self.interval.get_left(), self.interval.get_right() self.input_homotopy = lambda (x, y, z, t) : (x, y, t) + interpolate(left, right, t) output_size = self.output.get_num_points()-1 output_points = self.output.points self.output_homotopy = lambda (x, y, z, t) : (x, y, z) + output_points[int(t*output_size)]
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_sub_mobjects() 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_sub_mobjects() all_curves.thin_out(10) self.play(ShowCreation( all_curves, rate_func = None, run_time = 15 ))
def __init__(self, **kwargs): Mobject.__init__(self, **kwargs) for part_name in self.PART_NAMES: mob = ImageMobject( part_name_to_directory(part_name), should_center = False ) if part_name not in self.WHITE_PART_NAMES: mob.highlight(self.color) setattr(self, part_name, mob) self.eyes = Mobject(self.left_eye, self.right_eye) self.legs = Mobject(self.left_leg, self.right_leg) mouth_center = self.get_mouth_center() self.mouth.center() self.smile = self.mouth self.frown = self.mouth.copy().rotate(np.pi, RIGHT) self.straight_mouth = TexMobject("-").scale(0.7) for mouth in self.smile, self.frown, self.straight_mouth: mouth.sort_points(lambda p : p[0]) mouth.highlight(self.color) ##to blend into background mouth.shift(mouth_center) self.digest_mobject_attrs() self.give_smile() self.add(self.mouth) self.scale(PI_CREATURE_SCALE_VAL)
def __init__(self, mobject1, mobject2, run_time = DEFAULT_TRANSFORM_RUN_TIME, interpolation_function = straight_path, black_out_extra_points = False, *args, **kwargs): self.interpolation_function = interpolation_function count1, count2 = mobject1.get_num_points(), mobject2.get_num_points() if count2 == 0: mobject2 = Point((SPACE_WIDTH, SPACE_HEIGHT, 0)) count2 = mobject2.get_num_points() Mobject.align_data(mobject1, mobject2) Animation.__init__(self, mobject1, run_time = run_time, *args, **kwargs) self.ending_mobject = mobject2 self.mobject.SHOULD_BUFF_POINTS = \ mobject1.SHOULD_BUFF_POINTS and mobject2.SHOULD_BUFF_POINTS self.reference_mobjects.append(mobject2) self.name += "To" + str(mobject2) if black_out_extra_points and count2 < count1: #Ensure redundant pixels fade to black indices = np.arange( 0, count1-1, float(count1) / count2 ).astype('int') temp = np.zeros(mobject2.points.shape) temp[indices] = mobject2.rgbs[indices] mobject2.rgbs = temp self.non_redundant_m2_indices = indices
def __init__(self, function, **kwargs): self.function = function if self.density: self.epsilon = 1.0 / self.density elif self.dim == 1: self.epsilon = 1.0 / self.expected_measure / DEFAULT_POINT_DENSITY_1D else: self.epsilon = 1.0 / np.sqrt(self.expected_measure) / DEFAULT_POINT_DENSITY_2D Mobject.__init__(self, **kwargs)
def __init__(self, expression, **kwargs): if "size" not in kwargs: #Todo, make this more sophisticated. if len("".join(expression)) < MAX_LEN_FOR_HUGE_TEX_FONT: size = "\\Huge" else: size = "\\large" digest_locals(self) Mobject.__init__(self, **kwargs)
def __init__(self, condition = (lambda x, y : True), **kwargs): """ Condition must be a function which takes in two real arrays (representing x and y values of space respectively) and return a boolean array. This can essentially look like a function from R^2 to {True, False}, but & and | must be used in place of "and" and "or" """ Mobject.__init__(self, **kwargs) self.condition = condition
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 __init__(self, image_file, **kwargs): digest_locals(self) Mobject.__init__(self, **kwargs) self.name = to_camel_case( os.path.split(image_file)[-1].split(".")[0] ) path = get_full_image_path(image_file) self.generate_points_from_file(path) self.scale(self.scale_factorue) if self.should_center: self.center()
def play(self, *args, **kwargs): if not self.has_started: self.has_started = True everything = Mobject(*self.mobjects) vect = 2*SPACE_WIDTH*RIGHT everything.shift(vect) self.play(ApplyMethod( everything.shift, -vect, rate_func = rush_from )) Scene.play(self, *args, **kwargs)
def separate_moving_and_static_mobjects(self, *animations): moving_mobjects = list(it.chain(*[ anim.mobject.submobject_family() for anim in animations ])) bundle = Mobject(*self.mobjects) static_mobjects = filter( lambda m : m not in moving_mobjects, bundle.submobject_family() ) return moving_mobjects, static_mobjects
def __init__(self, **kwargs): digest_config(self, kwargs, locals()) if self.file_name is None: raise Exception("Must invoke Bubble subclass") SVGMobject.__init__(self, **kwargs) self.center() self.stretch_to_fit_height(self.height) self.stretch_to_fit_width(self.width) if self.direction[0] > 0: Mobject.flip(self) self.direction_was_specified = ("direction" in kwargs) self.content = Mobject()
def solve_energy(self): loss_in_potential = TextMobject("Loss in potential: ") loss_in_potential.shift(2*UP) potential = TexMobject("m g y".split()) potential.next_to(loss_in_potential) kinetic = TexMobject([ "\\dfrac{1}{2}","m","v","^2","=" ]) kinetic.next_to(potential, LEFT) nudge = 0.1*UP kinetic.shift(nudge) loss_in_potential.shift(nudge) ms = Mobject(kinetic.split()[1], potential.split()[0]) two = TexMobject("2") two.shift(ms.split()[1].get_center()) half = kinetic.split()[0] sqrt = TexMobject("\\sqrt{\\phantom{2mg}}") sqrt.shift(potential.get_center()) nudge = 0.2*LEFT sqrt.shift(nudge) squared = kinetic.split()[3] equals = kinetic.split()[-1] new_eq = equals.copy().next_to(kinetic.split()[2]) self.play( Transform( Point(loss_in_potential.get_left()), loss_in_potential ), *map(GrowFromCenter, potential.split()) ) self.dither(2) self.play( FadeOut(loss_in_potential), GrowFromCenter(kinetic) ) self.dither(2) self.play(ApplyMethod(ms.shift, 5*UP)) self.dither() self.play(Transform( half, two, path_func = counterclockwise_path() )) self.dither() self.play( Transform( squared, sqrt, path_func = clockwise_path() ), Transform(equals, new_eq) ) self.dither(2)
def get_triangles(self): triangle = Polygon( LEFT/np.sqrt(3), UP, RIGHT/np.sqrt(3), color = GREEN ) triangles = Mobject( triangle.copy().scale(0.5).shift(LEFT), triangle, triangle.copy().scale(0.3).shift(0.5*UP+RIGHT) ) triangles.center() return triangles
def __init__(self, mobject, ending_mobject, **kwargs): mobject, ending_mobject = map(instantiate, [mobject, ending_mobject]) digest_config(self, kwargs, locals()) count1, count2 = mobject.get_num_points(), ending_mobject.get_num_points() if count2 == 0: ending_mobject.add_points([SPACE_WIDTH*RIGHT+SPACE_HEIGHT*UP]) count2 = ending_mobject.get_num_points() Mobject.align_data(mobject, ending_mobject) if self.should_black_out_extra_points and count2 < count1: self.black_out_extra_points(count1, count2) Animation.__init__(self, mobject, **kwargs) self.name += "To" + str(ending_mobject) self.mobject.point_thickness = ending_mobject.point_thickness
def __init__(self, *args, **kwargs): Mobject.__init__(self, *args, **kwargs) self.add(Circle().scale(0.15).shift(2.5*DOWN+2*LEFT)) self.add(Circle().scale(0.3).shift(2*DOWN+1.5*LEFT)) for n in range(self.NUM_BULGES): theta = 2*np.pi*n/self.NUM_BULGES self.add(Circle().shift((np.cos(theta), np.sin(theta), 0))) self.filter_out(lambda p : np.linalg.norm(p) < self.INITIAL_INNER_RADIUS) self.stretch_to_fit_width(self.INITIAL_WIDTH) self.highlight("white") Bubble.__init__( self, index_of_tip = np.argmin(self.points[:,1]), **kwargs )
def get_edge_mobject(self, image_array): edged_image = get_edges(image_array) individual_edges = get_connected_components(edged_image) colored_edges = [ color_region(edge, image_array) for edge in individual_edges ] colored_edge_mobject_list = [ MobjectFromPixelArray(colored_edge) for colored_edge in colored_edges ] random.shuffle(colored_edge_mobject_list) edge_mobject = Mobject(*colored_edge_mobject_list) edge_mobject.ingest_submobjects() return edge_mobject
def slide_system(self, ring): equilibrium_slide_kwargs = dict(self.slide_kwargs) def jiggle_to_equilibrium(t): return 0.7*(1+((1-t)**2)*(-np.cos(10*np.pi*t))) equilibrium_slide_kwargs = { "rate_func" : jiggle_to_equilibrium, "run_time" : 3 } start = Mobject(ring, self.start_springs) end = Mobject( ring.copy().shift(self.ring_shift_val), self.end_springs ) for kwargs in self.slide_kwargs, equilibrium_slide_kwargs: self.play(Transform(start, end, **kwargs)) self.dither()
def generate_points(self): phi = (1 + np.sqrt(5)) / 2 x = np.array([1, 0, 0]) y = np.array([0, 1, 0]) z = np.array([0, 0, 1]) v1, v2 = (phi, 1/phi, 0), (phi, -1/phi, 0) vertex_pairs = [ (v1, v2), (x+y+z, v1), (x+y-z, v1), (x-y+z, v2), (x-y-z, v2), ] five_lines_points = Mobject(*[ Line(pair[0], pair[1], density = 1.0/self.epsilon) for pair in vertex_pairs ]).points #Rotate those 5 edges into all 30. for i in range(3): perm = map(lambda j : j%3, range(i, i+3)) for b in [-1, 1]: matrix = b*np.array([x[perm], y[perm], z[perm]]) self.add_points(np.dot(five_lines_points, matrix)) self.pose_at_angle() self.set_color(GREEN)
def show_equation(self, chopped_cycloid, ref_mob): point2, point1 = chopped_cycloid.points[-2:] arc, theta, vert_line, tangent_line = self.get_marks(point1, point2) equation = TexMobject([ "\\sin(\\theta)", "\\over \\sqrt{y}", ]) sin, sqrt_y = equation.split() equation.next_to(ref_mob) const = TexMobject(" = \\text{constant}") const.next_to(equation) ceil_point = np.array(point1) ceil_point[1] = self.top[1] brace = Brace(Mobject(Point(point1), Point(ceil_point)), RIGHT) y_mob = TexMobject("y").next_to(brace) self.play(GrowFromCenter(sin), ShowCreation(arc), GrowFromCenter(theta)) self.play(ShowCreation(vert_line)) self.play(ShowCreation(tangent_line)) self.dither() self.play(GrowFromCenter(sqrt_y), GrowFromCenter(brace), GrowFromCenter(y_mob)) self.dither() self.play(Transform(Point(const.get_left()), const)) 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 __init__(self, **kwargs): digest_config(self, kwargs, locals()) if self.file_name is None: raise Exception("Must invoke Bubble subclass") try: SVGMobject.__init__(self, **kwargs) except IOError as err: self.file_name = os.path.join(FILE_DIR, self.file_name) SVGMobject.__init__(self, **kwargs) self.center() self.stretch_to_fit_height(self.height) self.stretch_to_fit_width(self.width) if self.direction[0] > 0: Mobject.flip(self) self.direction_was_specified = ("direction" in kwargs) self.content = Mobject()
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([ "Fermat's principle:", """ If a beam of light travels from point $A$ to $B$, it does so along the fastest path possible. """ ]) words.split()[0].highlight(BLUE) everything = MobjectFromRegion(Region()) everything.scale(0.9) angles = np.apply_along_axis(angle_of_vector, 1, everything.points) norms = np.apply_along_axis(np.linalg.norm, 1, everything.points) norms -= np.min(norms) norms /= np.max(norms) alphas = 0.25 + 0.75 * norms * (1 + np.sin(12 * angles)) / 2 everything.rgbas = alphas.repeat(3).reshape((len(alphas), 3)) Mobject(everything, words).show() everything.sort_points(np.linalg.norm) self.add(words) self.play(DelayByOrder(FadeIn(everything, run_time=3)), Animation(words)) self.play(ApplyMethod(everything.highlight, WHITE), ) self.dither()
def construct(self): definition = TexMobject([ "\\text{HC}(", "x", ")", "=\\lim_{n \\to \\infty}\\text{PHC}_n(", "x", ")" ]) definition.to_edge(UP) definition.split()[1].highlight(BLUE) definition.split()[-2].highlight(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].highlight(GREEN) items[3].highlight(YELLOW_C) items[5].highlight(MAROON) Mobject(*items).to_edge(RIGHT) self.add(definition) self.play(ShimmerIn(intro)) self.dither() self.play(Transform(intro, prove_that)) for item in items[1:-1]: self.play(ShimmerIn(item)) self.dither()
def show_geometry(self, slider, vector): point_a = self.point_a.get_center() horiz_line = Line(point_a, point_a + 6 * RIGHT) ceil_point = point_a ceil_point[0] = slider.get_center()[0] vert_brace = Brace(Mobject(Point(ceil_point), Point(slider.get_center())), RIGHT, buff=0.5) vect_brace = Brace(slider) vect_brace.stretch_to_fit_width(vector.get_length()) vect_brace.rotate(np.arctan(vector.get_slope())) vect_brace.center().shift(vector.get_center()) nudge = 0.2 * (DOWN + LEFT) vect_brace.shift(nudge) y_mob = TexMobject("y") y_mob.next_to(vert_brace) sqrt_y = TexMobject("k\\sqrt{y}") sqrt_y.scale(0.5) sqrt_y.shift(vect_brace.get_center()) sqrt_y.shift(3 * nudge) self.play(ShowCreation(horiz_line)) self.play(GrowFromCenter(vert_brace), ShimmerIn(y_mob)) self.play(GrowFromCenter(vect_brace), ShimmerIn(sqrt_y)) self.dither(3) self.solve_energy()
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 construct(self): words = TextMobject("Order 3 Pseudo-Hilbert Curve") words.highlight(GREEN) words.to_edge(UP) grid4 = Mobject(Grid(2, 2), Grid(4, 4, stroke_width=2)) grid8 = Grid(8, 8, stroke_width=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.wait() self.play(ShowCreation(grid8)) self.wait() self.play(*map(GrowFromCenter, mini_curves)) self.wait() 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.wait()
def __init__(self, direction = LEFT, index_of_tip = -1, center = ORIGIN): self.direction = direction self.content = Mobject() self.index_of_tip = index_of_tip self.center_offset = center - Mobject.get_center(self) if direction[0] > 0: self.rotate(np.pi, UP)
def show_snells(self, index, frame): left_text, right_text = [ "\\dfrac{\\sin(\\theta_%d)}{\\phantom{\\sqrt{y_1}}}"%x for x in index, index+1 ] left, equals, right = TexMobject( [left_text, "=", right_text] ).split() vs = [] sqrt_ys = [] for x, numerator in [(index, left), (index+1, right)]: v, sqrt_y = [ TexMobject( text, size = "\\Large" ).next_to(numerator, DOWN) for text in "v_%d"%x, "\\sqrt{y_%d}"%x ] vs.append(v) sqrt_ys.append(sqrt_y) start, end = [ Mobject( left.copy(), mobs[0], equals.copy(), right.copy(), mobs[1] ).replace(frame) for mobs in vs, sqrt_ys ] self.add(start) self.dither(2) self.play(Transform( start, end, path_func = counterclockwise_path() )) self.dither(2) self.remove(start, end)
def get_paths(self): return [ Mobject(Line(self.start_point, midpoint), Line(midpoint, self.end_point)).highlight(color) for midpoint, color in zip([2 * UP, 2 * DOWN], Color(YELLOW).range_to(WHITE, 2)) ]
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.sub_mobjects[: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.highlight, RED, lambda p : p[0] > n-6.2 and p[0] < n-4 and p[1] > -0.4 ), brace_anim )
def show_infinite_objects(self): sigma, summand, equals, result = TexMobject([ "\\sum_{n = 1}^{\\infty}", "\\dfrac{1}{n^2}", "=", "\\dfrac{\pi^2}{6}" ]).split() alt_summand = TexMobject("n").replace(summand) alt_result = TexMobject("-\\dfrac{1}{12}").replace(result) rationals, other_equals, naturals = TexMobject([ "|\\mathds{Q}|", "=", "|\\mathds{N}|" ]).scale(2).split() infinity = TexMobject("\\infty").scale(2) local_mobjects = filter( lambda m : isinstance(m, Mobject), locals().values(), ) for mob in local_mobjects: mob.sort_points(np.linalg.norm) self.play(ShimmerIn(infinity)) self.dither() self.play( ShimmerIn(summand), ShimmerIn(equals), ShimmerIn(result), DelayByOrder(Transform(infinity, sigma)) ) self.dither() self.play( Transform(summand, alt_summand), Transform(result, alt_result), ) self.dither() self.remove(infinity) self.play(*[ CounterclockwiseTransform( Mobject(summand, equals, result, sigma), Mobject(rationals, other_equals, naturals) ) ]) self.dither() self.clear() self.add(self.bubble)
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 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 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 __init__(self, mobject, ending_mobject, **kwargs): mobject = instantiate(mobject) #Copy ending_mobject so as to not mess with caller ending_mobject = instantiate(ending_mobject).copy() digest_config(self, kwargs, locals()) count1, count2 = mobject.get_num_points( ), ending_mobject.get_num_points() if count2 == 0: ending_mobject.add_points([mobject.get_center()], color=BLACK) count2 = ending_mobject.get_num_points() Mobject.align_data(mobject, ending_mobject) if self.should_black_out_extra_points and count2 < count1: self.black_out_extra_points(count1, count2) Animation.__init__(self, mobject, **kwargs) self.name += "To" + str(ending_mobject) self.mobject.point_thickness = ending_mobject.point_thickness
def get_paths(self): self.leftmost, self.rightmost = result = [ Mobject(Line(self.start_point, midpoint), Line(midpoint, self.end_point)).highlight(color) for midpoint, color in zip([3 * LEFT, 3 * RIGHT], Color(YELLOW).range_to(WHITE, 2)) ] return result
def __init__(self, function, dim = 1, expected_measure = 10.0, density = None, *args, **kwargs): self.function = function self.dim = dim self.expected_measure = expected_measure if density: self.epsilon = 1.0 / density elif self.dim == 1: self.epsilon = 1.0 / expected_measure / DEFAULT_POINT_DENSITY_1D else: self.epsilon = 1.0 / np.sqrt(expected_measure) / DEFAULT_POINT_DENSITY_2D Mobject.__init__(self, *args, **kwargs)
def generate_springs(self, ring): self.start_springs, self.end_springs = [ Mobject( Spring(self.start_point, r.get_top()), Spring(self.end_point, r.get_bottom()) ) for r in ring, ring.copy().shift(self.ring_shift_val) ]
def add_extra_dots(self): dots = self.dots.split() for vect in UP+LEFT, DOWN+RIGHT: for n in range(5, 15): dots.append( dots[0].copy().center().shift(n*vect) ) self.dots = Mobject(*dots)
def construct(self): digest_config(self, {}) ## Usually shouldn't need this... self.frame_duration = self.DEFAULT_CONFIG["frame_duration"] ## digest_config(self, {}) circle = Circle( density = self.circle_density, color = self.circle_blue ) circle.repeat(self.circle_repeats) circle.scale(self.radius) sphere = Sphere( density = self.sphere_density, color = self.sphere_blue ) sphere.scale(self.radius) sphere.rotate(-np.pi / 7, [1, 0, 0]) sphere.rotate(-np.pi / 7) iris = Mobject() iris.interpolate( circle, sphere, self.interpolation_factor ) for mob, color in [(iris, self.sphere_brown), (circle, self.circle_brown)]: mob.highlight(color, lambda (x, y, z) : x < 0 and y > 0) mob.highlight( "black", lambda point: np.linalg.norm(point) < \ self.inner_radius_ratio*self.radius ) name = TextMobject("3Blue1Brown").center() name.highlight("grey") name.shift(2*DOWN) self.play(Transform( circle, iris, run_time = self.run_time )) self.frames = drag_pixels(self.frames) self.save_image(IMAGE_DIR) self.show_frame() self.add(name) self.dither() print "Dragging pixels..."
def 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 write_time(self, time): if hasattr(self, "time_mob"): self.remove(self.time_mob) digits = map(TexMobject, "%.2f" % time) digits[0].next_to(self.t_equals, buff=0.1) for left, right in zip(digits, digits[1:]): right.next_to(left, buff=0.1, aligned_edge=DOWN) self.time_mob = Mobject(*digits) self.add(self.time_mob)
def __init__(self, image_file, **kwargs): digest_locals(self) Mobject.__init__(self, **kwargs) self.name = to_cammel_case(os.path.split(image_file)[-1].split(".")[0]) possible_paths = [ image_file, os.path.join(IMAGE_DIR, image_file), os.path.join(IMAGE_DIR, image_file + ".jpg"), os.path.join(IMAGE_DIR, image_file + ".png"), ] for path in possible_paths: if os.path.exists(path): self.generate_points_from_file(path) self.scale(self.scale_value) if self.should_center: self.center() return raise IOError("File not Found")
def get_q_marks_and_arrows(self, mob, n_marks = 10): circle = Circle().replace(mob) q_marks, arrows = result = [Mobject(), Mobject()] for x in range(n_marks): index = (x+0.5)*self.cycloid.get_num_points()/n_marks q_point = self.cycloid.points[index] vect = q_point-mob.get_center() start_point = circle.get_boundary_point(vect) arrow = Arrow( start_point, q_point, color = BLUE_E ) q_marks.add(TextMobject("?").shift(q_point)) arrows.add(arrow) for mob in result: mob.ingest_submobjects() return result
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.dither() self.remove(self.brace, self.jump)
def __init__(self, mobject, **kwargs): self.intermediate = Mobject(color = self.color) self.intermediate.add_points([ point + (x, y, 0) for point in self.mobject.points for x in [-1, 1] for y in [-1, 1] ]) Animation.__init__(self, mobject, **kwargs)
def construct(self): words = TextMobject("Would this actually work?") 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) mapping = Mobject(grid, freq_line, Arrow(grid, freq_line)) mapping.ingest_sub_mobjects() lower_left = Point().to_corner(DOWN + LEFT, buff=0) lower_right = Point().to_corner(DOWN + RIGHT, buff=0) self.add(words) self.dither() self.play(Transform(words, lower_right), Transform(lower_left, mapping)) self.dither()
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.highlight(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.dither() self.remove(explanation, exp_arrow) self.play(ShowCreation(curve)) self.play( ApplyMethod(x1.highlight, BLUE), ShowCreation(x_arrow), ShowCreation(dot) ) self.dither() self.remove(x_arrow) limit = Mobject(*text.split()[3:]).ingest_sub_mobjects() limit.point_thickness = 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), )