def construct(self): title = TextMobject("(A few) Fathers of Calculus") title.to_edge(UP) self.add(title) men = Mobject() for name in self.names: image = ImageMobject(name, invert=False) image.scale_to_fit_height(self.picture_height) title = TextMobject(name) title.scale(0.8) title.next_to(image, DOWN) image.add(title) men.add(image) men.arrange_submobjects(RIGHT, aligned_edge=UP) men.shift(DOWN) discover_brace = Brace(Mobject(*men[:3]), UP) discover = discover_brace.get_text("Discovered it") VGroup(discover_brace, discover).highlight(BLUE) rigor_brace = Brace(Mobject(*men[3:]), UP) rigor = rigor_brace.get_text("Made it rigorous") rigor.shift(0.1 * DOWN) VGroup(rigor_brace, rigor).highlight(YELLOW) for man in men: self.play(FadeIn(man)) self.play(GrowFromCenter(discover_brace), Write(discover, run_time=1)) self.play(GrowFromCenter(rigor_brace), Write(rigor, run_time=1)) self.dither()
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 __init__(self, AnimationClass, mobjects, **kwargs): centers = [mob.get_center() for mob in mobjects] kwargs["mobject"] = Mobject().add_points(centers) self.centers_container = AnimationClass(**kwargs) kwargs.pop("mobject") Animation.__init__(self, Mobject(*mobjects), **kwargs) self.name = str(self) + AnimationClass.__name__
def construct(self): glass = Region(lambda x, y: y < 0, color=BLUE_E) kwargs = {"density": self.zoom_factor * DEFAULT_POINT_DENSITY_1D} top_line = Line(SPACE_HEIGHT * UP + 2 * LEFT, ORIGIN, **kwargs) extension = Line(ORIGIN, SPACE_HEIGHT * DOWN + 2 * RIGHT, **kwargs) bottom_line = Line(ORIGIN, SPACE_HEIGHT * DOWN + RIGHT, **kwargs) path1 = Mobject(top_line, extension) path2 = Mobject(top_line, bottom_line) for mob in path1, path2: mob.ingest_submobjects() extension.highlight(RED) theta1 = np.arctan(bottom_line.get_slope()) theta2 = np.arctan(extension.get_slope()) arc = Arc(theta2 - theta1, start_angle=theta1, radius=2) question_mark = TextMobject("$\\theta$?") question_mark.shift(arc.get_center() + 0.5 * DOWN + 0.25 * RIGHT) wave = self.wavify(path2) wave.highlight(YELLOW) wave.scale(0.5) self.add(glass) self.play(ShowCreation(path1)) self.play(Transform(path1, path2)) self.wait() # self.activate_zooming() self.wait() self.play(ShowPassingFlash(wave, run_time=3, rate_func=None)) self.wait() self.play(ShowCreation(extension)) self.play(ShowCreation(arc), ShimmerIn(question_mark))
def show_equation(self): equation = TexMobject([ "\\left(\\dfrac{1}{\\phantom{v_air}}\\right)", "\\sin(\\theta_1)", "=", "\\left(\\dfrac{1}{\\phantom{v_water}}\\right)", "\\sin(\\theta_2)" ]) equation.to_corner(UP + RIGHT) frac1, sin1, equals, frac2, sin2 = equation.split() v_air, v_water = [ TexMobject("v_{\\text{%s}}" % s, size="\\Large") for s in "air", "water" ] v_air.next_to(Point(frac1.get_center()), DOWN) v_water.next_to(Point(frac2.get_center()), DOWN) frac1.add(v_air) frac2.add(v_water) f1, f2 = [TexMobject("F_%d" % d, size="\\Large") for d in 1, 2] f1.next_to(sin1, LEFT) f2.next_to(equals, RIGHT) sin2_start = sin2.copy().next_to(f2, RIGHT) bar1 = TexMobject("\\dfrac{\\qquad}{\\qquad}") bar2 = bar1.copy() bar1.next_to(sin1, DOWN) bar2.next_to(sin2, DOWN) v_air_copy = v_air.copy().next_to(bar1, DOWN) v_water_copy = v_water.copy().next_to(bar2, DOWN) bars = Mobject(bar1, bar2) new_eq = equals.copy().center().shift(bars.get_center()) snells = TextMobject("Snell's Law") snells.highlight(YELLOW) snells.shift(new_eq.get_center()[0] * RIGHT) snells.shift(UP) anims = [] for mob in f1, sin1, equals, f2, sin2_start: anims.append(ShimmerIn(mob)) self.play(*anims) self.wait() for f, frac in (f1, frac1), (f2, frac2): target = frac.copy().ingest_submobjects() also = [] if f is f2: also.append(Transform(sin2_start, sin2)) sin2 = sin2_start self.play(Transform(f, target), *also) self.remove(f) self.add(frac) self.wait() self.play(FadeOut(frac1), FadeOut(frac2), Transform(v_air, v_air_copy), Transform(v_water, v_water_copy), ShowCreation(bars), Transform(equals, new_eq)) self.wait() frac1 = Mobject(sin1, bar1, v_air) frac2 = Mobject(sin2, bar2, v_water) for frac, vect in (frac1, LEFT), (frac2, RIGHT): self.play(ApplyMethod(frac.next_to, equals, vect)) self.wait() self.play(ShimmerIn(snells)) self.wait()
def __init__(self, AnimationClass, mobjects, **kwargs): full_kwargs = AnimationClass.CONFIG full_kwargs.update(kwargs) full_kwargs["mobject"] = Mobject( *[mob.get_point_mobject() for mob in mobjects]) self.centers_container = AnimationClass(**full_kwargs) full_kwargs.pop("mobject") Animation.__init__(self, Mobject(*mobjects), **full_kwargs) self.name = str(self) + AnimationClass.__name__
def nearest_neighbor_align(mobject1, mobject2): distance_matrix = cdist(mobject1.points, mobject2.points) closest_point_indices = np.apply_along_axis(np.argmin, 0, distance_matrix) new_mob1 = Mobject() new_mob2 = Mobject() for n in range(mobject1.get_num_points()): indices = (closest_point_indices == n) new_mob1.add_points([mobject1.points[n]] * sum(indices)) new_mob2.add_points(mobject2.points[indices], rgbas=mobject2.rgbas[indices]) return new_mob1, new_mob2
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 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 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.wait()
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): left, right = 5*LEFT, 5*RIGHT top_words = TextMobject("The next 15 minutes of your life:") top_words.to_edge(UP) line = Line(left, right, color = BLUE_D) for a in np.arange(0, 4./3, 1./3): vect = interpolate(left, right, a) line.add_line(vect+0.2*DOWN, vect+0.2*UP) left_brace = Brace( Mobject( Point(left), Point(interpolate(left, right, 2./3)) ), DOWN ) right_brace = Brace( Mobject( Point(interpolate(left, right, 2./3)), Point(right) ), UP ) left_brace.words = map(TextMobject, [ "Problem statement", "History", "Johann Bernoulli's cleverness" ]) curr = left_brace right_brace.words = map(TextMobject, [ "Challenge", "Mark Levi's cleverness", ]) for brace in left_brace, right_brace: curr = brace direction = DOWN if brace is left_brace else UP for word in brace.words: word.next_to(curr, direction) curr = word right_brace.words.reverse() self.play(ShimmerIn(top_words)) self.play(ShowCreation(line)) for brace in left_brace, right_brace: self.play(GrowFromCenter(brace)) self.dither() for word in brace.words: self.play(ShimmerIn(word)) 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 __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 construct(self): mathematicians = [ ImageMobject(name, invert=False) for name in [ "Old_Newton", "Johann_Bernoulli2", "Jacob_Bernoulli", "Ehrenfried_von_Tschirnhaus", "Gottfried_Wilhelm_von_Leibniz", "Guillaume_de_L'Hopital", ] ] newton = mathematicians.pop(0) newton.scale(0.8) new_newton = newton.copy() new_newton.scale_to_fit_height(3) new_newton.to_edge(UP) for man in mathematicians: man.scale_to_fit_width(1.7) johann = mathematicians.pop(0) johann.next_to(new_newton, DOWN) last_left, last_right = johann, johann for man, count in zip(mathematicians, it.count()): if count % 2 == 0: man.next_to(last_left, LEFT) last_left = man else: man.next_to(last_right, RIGHT) last_right = man self.play(Transform(newton, new_newton), GrowFromCenter(johann)) self.wait() self.play(FadeIn(Mobject(*mathematicians))) self.wait()
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.wait() self.play(Transform(intro, prove_that)) for item in items[1:-1]: self.play(ShimmerIn(item)) self.wait()
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 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): 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.highlight, RED, lambda p : p[0] > n-6.2 and p[0] < n-4 and p[1] > -0.4 ), brace_anim )
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_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 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.wait(2) self.play(Transform( start, end, path_func = counterclockwise_path() )) self.wait(2) self.remove(start, end)
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([ "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.rgbs = 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 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.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 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 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 construct(self): digest_config(self, {}) ## Usually shouldn't need this... self.frame_duration = self.CONFIG["frame_duration"] ## digest_config(self, {}) circle = Circle(density=self.circle_density, color=self.circle_blue) circle.repeat(self.circle_repeats) circle.scale(self.radius) sphere = Sphere(density=self.sphere_density, color=self.sphere_blue) sphere.scale(self.radius) sphere.rotate(-np.pi / 7, [1, 0, 0]) sphere.rotate(-np.pi / 7) iris = Mobject() iris.interpolate(circle, sphere, self.interpolation_factor) for mob, color in [(iris, self.sphere_brown), (circle, self.circle_brown)]: mob.highlight(color, lambda (x, y, z): x < 0 and y > 0) mob.highlight( "black", lambda point: np.linalg.norm(point) < \ self.inner_radius_ratio*self.radius ) self.name_mob = TextMobject("3Blue1Brown").center() self.name_mob.highlight("grey") self.name_mob.shift(2 * DOWN) self.play(Transform(circle, iris, run_time=self.run_time)) self.frames = drag_pixels(self.frames) self.save_image(IMAGE_DIR) self.logo = MobjectFromPixelArray(self.frames[-1]) self.add(self.name_mob) self.dither()
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()