Exemple #1
0
 def generate_points(self):
     self.cell_height = self.height / self.nrows
     self.cell_width = self.width / self.nrows
     self.bottom_left = (self.cell_width * self.nrows / 2.0)*LEFT + \
                        (self.cell_height * self.nrows / 2.0)*DOWN
     num_to_num_mob   = {} 
     self.coords_to_mobs   = {}
     self.coords = [
         (n, k) 
         for n in range(self.nrows) 
         for k in range(n+1)
     ]
     for n, k in self.coords:
         num = choose(n, k)              
         center = self.coords_to_center(n, k)
         num_mob = TexMobject(str(num))
         scale_factor = min(
             1,
             self.portion_to_fill * self.cell_height / num_mob.get_height(),
             self.portion_to_fill * self.cell_width / num_mob.get_width(),
         )
         num_mob.center().scale(scale_factor).shift(center)
         if n not in self.coords_to_mobs:
             self.coords_to_mobs[n] = {}
         self.coords_to_mobs[n][k] = num_mob
     self.add(*[
         self.coords_to_mobs[n][k] 
         for n, k in self.coords
     ])
     return self
Exemple #2
0
    def cycle_through_shapes(self):
        circle = Circle(radius = 2.5, color = WHITE)
        ellipse = circle.copy()
        ellipse.stretch(1.5, 0)
        ellipse.stretch(0.7, 1)
        ellipse.rotate(-np.pi/2)
        ellipse.scale_to_fit_height(4)
        pi_loop = TexMobject("\\pi")[0]
        pi_loop.set_fill(opacity = 0)
        pi_loop.set_stroke(
            color = WHITE,
            width = DEFAULT_POINT_THICKNESS
        )
        pi_loop.scale_to_fit_height(4)
        randy = Randolph()
        randy.look(DOWN)
        randy.scale_to_fit_width(pi_loop.get_width())
        randy.move_to(pi_loop, aligned_edge = DOWN)
        randy.body.set_fill(opacity = 0)
        randy.mouth.set_stroke(width = 0)

        self.transform_loop(circle)
        self.dither()
        odd_eigths = np.linspace(1./8, 7./8, 4)
        self.move_dots_to_alphas(odd_eigths)
        self.dither()
        for nudge in 0.1, -0.1, 0:
            self.move_dots_to_alphas(odd_eigths+nudge)
        self.dither()
        self.transform_loop(ellipse)
        self.dither()
        nudge = 0.055
        self.move_dots_to_alphas(
            odd_eigths + [nudge, -nudge, nudge, -nudge]
        )
        self.dither(2)
        self.transform_loop(pi_loop)
        self.let_dots_wonder()
        randy_anims = [
            FadeIn(randy),
            Animation(randy),            
            Blink(randy),
            Animation(randy),
            Blink(randy, rate_func = smooth)
        ]
        for anim in randy_anims:
            self.let_dots_wonder(
                run_time = 1,
                random_seed = 0,
                added_anims = [anim]
            )
        self.remove(randy)
        self.transform_loop(self.get_default_loop())
Exemple #3
0
 def get_number_mobjects(self, *numbers):
     # TODO, handle decimals
     if len(numbers) == 0:
         numbers = self.default_numbers_to_display()
     result = []
     for number in numbers:
         mob = TexMobject(str(int(number)))
         vert_scale = 2 * self.tick_size / mob.get_height()
         hori_scale = self.tick_frequency * self.unit_length_to_spatial_width / mob.get_width()
         mob.scale(min(vert_scale, hori_scale))
         mob.shift(self.number_to_point(number))
         mob.shift(self.get_vertical_number_offset())
         result.append(mob)
     return result
Exemple #4
0
 def generate_n_choose_k_mobs(self):
     self.coords_to_n_choose_k = {}
     for n, k in self.coords:
         nck_mob = TexMobject(r"{%d \choose %d}" % (n, k))
         scale_factor = min(
             1,
             self.portion_to_fill * self.cell_height / nck_mob.get_height(),
             self.portion_to_fill * self.cell_width / nck_mob.get_width(),
         )
         center = self.coords_to_mobs[n][k].get_center()
         nck_mob.center().scale(scale_factor).shift(center)
         if n not in self.coords_to_n_choose_k:
             self.coords_to_n_choose_k[n] = {}
         self.coords_to_n_choose_k[n][k] = nck_mob
     return self
Exemple #5
0
 def generate_n_choose_k_mobs(self):
     self.coords_to_n_choose_k = {}
     for n, k in self.coords:
         nck_mob = TexMobject(r"{%d \choose %d}"%(n, k)) 
         scale_factor = min(
             1,
             self.portion_to_fill * self.cell_height / nck_mob.get_height(),
             self.portion_to_fill * self.cell_width / nck_mob.get_width(),
         )
         center = self.coords_to_mobs[n][k].get_center()
         nck_mob.center().scale(scale_factor).shift(center)
         if n not in self.coords_to_n_choose_k:
             self.coords_to_n_choose_k[n] = {}
         self.coords_to_n_choose_k[n][k] = nck_mob
     return self
Exemple #6
0
 def get_number_mobjects(self, *numbers):
     #TODO, handle decimals
     if len(numbers) == 0:
         numbers = self.default_numbers_to_display()
     result = []
     for number in numbers:
         mob = TexMobject(str(int(number)))
         vert_scale = 2 * self.tick_size / mob.get_height()
         hori_scale = self.tick_frequency * self.unit_length_to_spatial_width / mob.get_width(
         )
         mob.scale(min(vert_scale, hori_scale))
         mob.shift(self.number_to_point(number))
         mob.shift(self.get_vertical_number_offset())
         result.append(mob)
     return result
Exemple #7
0
    def scale_vector(self, v, factor, v_label, 
                     v_name = "v", factor_tex = None):
        starting_mobjects = list(self.mobjects)

        if factor_tex is None:
            factor_tex = str(factor)
        scaled_vector = self.add_vector(
            factor*v.get_end(), animate = False
        )
        self.remove(scaled_vector)
        label_tex = "%s\\vec{\\textbf{%s}}"%(factor_tex, v_name)
        label = self.label_vector(
            scaled_vector, label_tex, animate = False,
            add_to_vector = False
        )
        self.remove(label)
        factor_mob = TexMobject(factor_tex)
        if factor_mob.get_height() > 1:
            factor_mob.scale_to_fit_height(0.9)
        if factor_mob.get_width() > 1:
            factor_mob.scale_to_fit_width(0.9)
        factor_mob.shift(1.5*RIGHT+2.5*UP)

        num_factor_parts = len(factor_mob.split())
        factor_mob_parts_in_label = label.split()[:num_factor_parts]
        label_remainder_parts = label.split()[num_factor_parts:]
        factor_in_label = VMobject(*factor_mob_parts_in_label)
        label_remainder = VMobject(*label_remainder_parts)


        self.play(Write(factor_mob, run_time = 1))
        self.dither()
        self.play(
            ApplyMethod(v.copy().highlight, DARK_GREY),
            ApplyMethod(v_label.copy().highlight, DARK_GREY),
            Transform(factor_mob, factor_in_label),
            Transform(v.copy(), scaled_vector),
            Transform(v_label.copy(), label_remainder),
        )
        self.dither(2)

        self.clear()
        self.add(*starting_mobjects)
Exemple #8
0
    def scale_vector(self, v, factor, v_label, 
                     v_name = "v", factor_tex = None):
        starting_mobjects = list(self.mobjects)

        if factor_tex is None:
            factor_tex = str(factor)
        scaled_vector = self.add_vector(
            factor*v.get_end(), animate = False
        )
        self.remove(scaled_vector)
        label_tex = "%s\\vec{\\textbf{%s}}"%(factor_tex, v_name)
        label = self.label_vector(
            scaled_vector, label_tex, animate = False,
            add_to_vector = False
        )
        self.remove(label)
        factor_mob = TexMobject(factor_tex)
        if factor_mob.get_height() > 1:
            factor_mob.scale_to_fit_height(0.9)
        if factor_mob.get_width() > 1:
            factor_mob.scale_to_fit_width(0.9)
        factor_mob.shift(1.5*RIGHT+2.5*UP)

        num_factor_parts = len(factor_mob.split())
        factor_mob_parts_in_label = label.split()[:num_factor_parts]
        label_remainder_parts = label.split()[num_factor_parts:]
        factor_in_label = VMobject(*factor_mob_parts_in_label)
        label_remainder = VMobject(*label_remainder_parts)


        self.play(Write(factor_mob, run_time = 1))
        self.wait()
        self.play(
            ApplyMethod(v.copy().highlight, DARK_GREY),
            ApplyMethod(v_label.copy().highlight, DARK_GREY),
            Transform(factor_mob, factor_in_label),
            Transform(v.copy(), scaled_vector),
            Transform(v_label.copy(), label_remainder),
        )
        self.wait(2)

        self.clear()
        self.add(*starting_mobjects)
Exemple #9
0
    def take_derivatives_of_monomial(self, term):
        """
        Must be a group of pure TexMobjects,
        last part must be of the form x^n
        """
        n = int(term[-1].get_tex_string()[-1])
        curr_term = term
        for k in range(n, 0, -1):
            exponent = curr_term[-1][-1]
            exponent_copy = exponent.copy()
            front_num = TexMobject("%d \\cdot"%k)
            front_num.move_to(curr_term[0][0], DOWN+LEFT)

            new_monomial = TexMobject("x^%d"%(k-1))
            new_monomial.replace(curr_term[-1])
            Transform(curr_term[-1], new_monomial).update(1)
            curr_term.generate_target()
            curr_term.target.shift(
                (front_num.get_width()+SMALL_BUFF)*RIGHT
            )
            curr_term[-1][-1].set_fill(opacity = 0)

            self.play(
                ApplyMethod(
                    exponent_copy.replace, front_num[0],
                    path_arc = np.pi,
                ),
                Write(
                    front_num[1], 
                    rate_func = squish_rate_func(smooth, 0.5, 1)
                ),
                MoveToTarget(curr_term),
                run_time = 2
            )
            self.remove(exponent_copy)
            self.add(front_num)
            curr_term = VGroup(front_num, *curr_term)
        self.dither()
        self.play(FadeOut(curr_term[-1]))

        return VGroup(*curr_term[:-1])
Exemple #10
0
    def construct(self):

        MAX_OPACITY = 0.4
        INDICATOR_RADIUS = 0.6
        OPACITY_FOR_UNIT_INTENSITY = 0.5

        A = np.array([5., -3., 0.])
        B = np.array([-5., 3., 0.])
        C = np.array([-5., -3., 0.])

        morty = self.get_primary_pi_creature()
        morty.scale(0.3).flip()
        right_pupil = morty.pupils[1]
        morty.next_to(C, LEFT, buff=0, submobject_to_align=right_pupil)

        horizontal = VMobject(stroke_width=1)
        horizontal.set_points_as_corners([C, A])
        vertical = VMobject(stroke_width=1)
        vertical.set_points_as_corners([C, B])

        self.play(ShowCreation(horizontal), ShowCreation(vertical))

        indicator = LightIndicator(
            color=LIGHT_COLOR,
            radius=INDICATOR_RADIUS,
            opacity_for_unit_intensity=OPACITY_FOR_UNIT_INTENSITY,
            show_reading=True,
            precision=2)

        indicator.next_to(morty, LEFT)

        self.play(Write(indicator))

        ls1 = LightSource(radius=20, num_levels=50)
        ls2 = ls1.deepcopy()
        #print "==="
        #print ls1.get_source_point()
        ls1.move_source_to(A)
        #print ls1.get_source_point()
        #print "==="
        #print ls2.get_source_point()
        ls2.move_source_to(B)
        #print ls2.get_source_point()

        self.play(FadeIn(ls1.lighthouse), FadeIn(ls2.lighthouse),
                  SwitchOn(ls1.ambient_light), SwitchOn(ls2.ambient_light))

        distance1 = np.linalg.norm(C - ls1.get_source_point())
        intensity = ls1.ambient_light.opacity_function(
            distance1) / indicator.opacity_for_unit_intensity
        distance2 = np.linalg.norm(C - ls2.get_source_point())
        intensity += ls2.ambient_light.opacity_function(
            distance2) / indicator.opacity_for_unit_intensity

        self.play(UpdateLightIndicator(indicator, intensity))

        self.wait()

        ls3 = ls1.deepcopy()
        ls3.move_to(np.array([6, 3.5, 0]))

        new_indicator = indicator.copy()
        new_indicator.light_source = ls3
        new_indicator.measurement_point = C
        self.add(new_indicator)
        self.play(indicator.shift, 2 * UP)

        #intensity = intensity_for_light_source(ls3)

        self.play(
            SwitchOff(ls1.ambient_light),
            #FadeOut(ls1.lighthouse),
            SwitchOff(ls2.ambient_light),
            #FadeOut(ls2.lighthouse),
            UpdateLightIndicator(new_indicator, 0.0))

        # create a *continual* animation for the replacement source
        updater = ContinualLightIndicatorUpdate(new_indicator)
        self.add(updater)

        self.play(
            SwitchOn(ls3.ambient_light),
            FadeIn(ls3.lighthouse),
        )

        self.wait()

        # move the light source around
        # TODO: moving along a path arc

        location = np.array([-3, -2., 0.])
        self.play(ls3.move_source_to, location)
        location = np.array([6., 1., 0.])
        self.play(ls3.move_source_to, location)
        location = np.array([5., 2., 0.])
        self.play(ls3.move_source_to, location)
        closer_location = interpolate(location, C, 0.5)
        self.play(ls3.move_source_to, closer_location)
        self.play(ls3.move_source_to, location)

        # maybe move in a circle around C using a loop?

        # find the coords of the altitude point H
        # as the solution of a certain LSE
        xA = A[0]
        yA = A[1]
        xB = B[0]
        yB = B[1]
        xC = C[0]
        yC = C[1]
        matrix = np.array([[yA - yB, xB - xA], [xA - xB, yA - yB]])  # sic
        vector = np.array([xB * yA - xA * yB, xC * (xA - xB) + yC * (yA - yB)])
        H2 = np.linalg.solve(matrix, vector)
        H = np.append(H2, 0.)

        self.play(ls3.move_source_to, H)

        # draw lines to complete the geometric picture
        # and label the lengths

        line_a = VMobject()
        line_a.set_points_as_corners([B, C])
        line_b = VMobject()
        line_b.set_points_as_corners([A, C])
        line_c = VMobject()
        line_c.set_points_as_corners([A, B])
        line_h = VMobject()
        line_h.set_points_as_corners([H, C])

        label_a = TexMobject("a")
        label_a.next_to(line_a, LEFT, buff=0.5)
        label_b = TexMobject("b")
        label_b.next_to(line_b, DOWN, buff=0.5)
        label_h = TexMobject("h")
        label_h.next_to(line_h.get_center(), RIGHT, buff=0.5)

        self.play(ShowCreation(line_a), Write(label_a))

        self.play(ShowCreation(line_b), Write(label_b))

        self.play(ShowCreation(line_c), )

        self.play(ShowCreation(line_h), Write(label_h))

        # state the IPT
        theorem_location = np.array([3., 2., 0.])
        theorem = TexMobject("{1\over a^2} + {1\over b^2} = {1\over h^2}")
        theorem_name = TextMobject("Inverse Pythagorean Theorem")
        buffer = 1.2
        theorem_box = Rectangle(width=buffer * theorem.get_width(),
                                height=buffer * theorem.get_height())

        theorem.move_to(theorem_location)
        theorem_box.move_to(theorem_location)
        theorem_name.next_to(theorem_box, UP)

        self.play(Write(theorem), )

        self.play(
            ShowCreation(theorem_box),
            Write(theorem_name),
        )