Example #1
0
def get_det_text(
    matrix: Matrix,
    determinant: int | str | None = None,
    background_rect: bool = False,
    initial_scale_factor: int = 2
) -> VGroup:
    parens = Tex("(", ")")
    parens.scale(initial_scale_factor)
    parens.stretch_to_fit_height(matrix.get_height())
    l_paren, r_paren = parens.split()
    l_paren.next_to(matrix, LEFT, buff=0.1)
    r_paren.next_to(matrix, RIGHT, buff=0.1)
    det = TexText("det")
    det.scale(initial_scale_factor)
    det.next_to(l_paren, LEFT, buff=0.1)
    if background_rect:
        det.add_background_rectangle()
    det_text = VGroup(det, l_paren, r_paren)
    if determinant is not None:
        eq = Tex("=")
        eq.next_to(r_paren, RIGHT, buff=0.1)
        result = Tex(str(determinant))
        result.next_to(eq, RIGHT, buff=0.2)
        det_text.add(eq, result)
    return det_text
Example #2
0
    def get_dashed_rectangle(self, width, height):
        h1 = [ORIGIN, UP * height]
        w1 = [UP * height, UP * height + RIGHT * width]
        h2 = [UP * height + RIGHT * width, RIGHT * width]
        w2 = [RIGHT * width, ORIGIN]
        alpha = width / height
        divs = self.num_dashes

        n_h = int(divs / (2 * (alpha + 1)))
        n_w = int(alpha * n_h)
        dashedrectangle = VGroup()
        for n, l in zip([n_w, n_h], [[w1, w2], [h1, h2]]):
            for side in l:
                line = VMobject()
                line.set_points_as_corners(side)
                dashedrectangle.add(
                    DashedVMobject(
                        line,
                        num_dashes=n,
                        positive_space_ratio=self.positive_space_ratio,
                    ).set_color(self.color).set_style(**self.line_config))
        return [
            dashedrectangle[0], dashedrectangle[3], dashedrectangle[1],
            dashedrectangle[2]
        ]
 def setup_in_uv_space(self):
     u_values, v_values = self.get_u_values_and_v_values()
     faces = VGroup()
     for i in range(len(u_values) - 1):
         for j in range(len(v_values) - 1):
             u1, u2 = u_values[i:i + 2]
             v1, v2 = v_values[j:j + 2]
             face = ThreeDVMobject()
             face.set_points_as_corners([
                 [u1, v1, 0],
                 [u2, v1, 0],
                 [u2, v2, 0],
                 [u1, v2, 0],
                 [u1, v1, 0],
             ])
             faces.add(face)
             face.u_index = i
             face.v_index = j
             face.u1 = u1
             face.u2 = u2
             face.v1 = v1
             face.v2 = v2
     faces.set_fill(
         color=self.fill_color,
         opacity=self.fill_opacity
     )
     faces.set_stroke(
         color=self.stroke_color,
         width=self.stroke_width,
         opacity=self.stroke_opacity,
     )
     self.add(*faces)
     if self.checkerboard_colors:
         self.set_fill_by_checkerboard(*self.checkerboard_colors)
Example #4
0
    def __init__(self, point, color=YELLOW, **kwargs):
        digest_config(self, kwargs)
        lines = VGroup()
        for angle in np.arange(0, TAU, TAU / self.num_lines):
            line = Line(ORIGIN, self.line_length * RIGHT)
            line.shift((self.flash_radius - self.line_length) * RIGHT)
            line.rotate(angle, about_point=ORIGIN)
            lines.add(line)
        lines.move_to(point)
        lines.set_color(color)
        lines.set_stroke(width=3)
        line_anims = [
            ShowCreationThenDestruction(
                line, rate_func=squish_rate_func(smooth, 0, 0.5)
            )
            for line in lines
        ]
        fade_anims = [
            UpdateFromAlphaFunc(
                line, lambda m, a: m.set_stroke(
                    width=self.line_stroke_width * (1 - a)
                ),
                rate_func=squish_rate_func(smooth, 0, 0.75)
            )
            for line in lines
        ]

        AnimationGroup.__init__(
            self, *line_anims + fade_anims, **kwargs
        )
Example #5
0
    def add_lines(self, left, right):
        line_kwargs = {
            "color": BLUE,
            "stroke_width": 2,
        }
        left_rows = [
            VGroup(*row) for row in left.get_mob_matrix()
        ]
        h_lines = VGroup()
        for row in left_rows[:-1]:
            h_line = Line(row.get_left(), row.get_right(), **line_kwargs)
            h_line.next_to(row, DOWN, buff=left.v_buff / 2.)
            h_lines.add(h_line)

        right_cols = [
            VGroup(*col) for col in np.transpose(right.get_mob_matrix())
        ]
        v_lines = VGroup()
        for col in right_cols[:-1]:
            v_line = Line(col.get_top(), col.get_bottom(), **line_kwargs)
            v_line.next_to(col, RIGHT, buff=right.h_buff / 2.)
            v_lines.add(v_line)

        self.play(ShowCreation(h_lines))
        self.play(ShowCreation(v_lines))
        self.wait()
        self.show_frame()
Example #6
0
    def __init__(self, *text, line_spacing=-1, alignment=None, **config):
        self.line_spacing = line_spacing
        self.alignment = alignment
        VGroup.__init__(self, **config)

        lines_str = "\n".join(list(text))
        self.lines_text = Text(lines_str, line_spacing=line_spacing, **config)
        lines_str_list = lines_str.split("\n")
        self.chars = self.gen_chars(lines_str_list)

        chars_lines_text_list = VGroup()
        char_index_counter = 0
        for line_index in range(lines_str_list.__len__()):
            chars_lines_text_list.add(
                self.lines_text[char_index_counter:char_index_counter +
                                lines_str_list[line_index].__len__() + 1])
            char_index_counter += lines_str_list[line_index].__len__() + 1
        self.lines = []
        self.lines.append([])
        for line_no in range(chars_lines_text_list.__len__()):
            self.lines[0].append(chars_lines_text_list[line_no])
        self.lines_initial_positions = []
        for line_no in range(self.lines[0].__len__()):
            self.lines_initial_positions.append(
                self.lines[0][line_no].get_center())
        self.lines.append([])
        self.lines[1].extend(
            [self.alignment for _ in range(chars_lines_text_list.__len__())])
        VGroup.__init__(
            self, *[self.lines[0][i] for i in range(self.lines[0].__len__())],
            **config)
        self.move_to(np.array([0, 0, 0]))
        if self.alignment:
            self.set_all_lines_alignments(self.alignment)
Example #7
0
 def setup_in_uv_space(self):
     u_values, v_values = self.get_u_values_and_v_values()
     faces = VGroup()
     for i in range(len(u_values) - 1):
         for j in range(len(v_values) - 1):
             u1, u2 = u_values[i:i + 2]
             v1, v2 = v_values[j:j + 2]
             face = ThreeDVMobject()
             face.set_points_as_corners([
                 [u1, v1, 0],
                 [u2, v1, 0],
                 [u2, v2, 0],
                 [u1, v2, 0],
                 [u1, v1, 0],
             ])
             faces.add(face)
             face.u_index = i
             face.v_index = j
             face.u1 = u1
             face.u2 = u2
             face.v1 = v1
             face.v2 = v2
     faces.set_fill(
         color=self.fill_color,
         opacity=self.fill_opacity
     )
     faces.set_stroke(
         color=self.stroke_color,
         width=self.stroke_width,
         opacity=self.stroke_opacity,
     )
     self.add(*faces)
     if self.checkerboard_colors:
         self.set_fill_by_checkerboard(*self.checkerboard_colors)
Example #8
0
class Shadow_2d(VGroup):

    CONFIG = {
        'shadow_color': DARK_GRAY,
        'shadow_opacity': 0.6,
        'blur_width': 0.25,
        'layer_num': 40,
        'scale_factor': 1,
        'shadow_out': True,
        'show_basic_shape': True,
        'plot_depth':-1,
        'rate_func': lambda t: t ** 0.5,
    }

    def __init__(self, mob_or_points, **kwargs):
        VGroup.__init__(self, **kwargs)

        if type(mob_or_points) == list:
            self.shape = Polygon(*mob_or_points, stroke_width=0, plot_depth=-1)
        else:
            self.shape = mob_or_points.set_stroke(width=0)

        self.shape.set_fill(color=self.shadow_color, opacity=self.shadow_opacity * (1 if self.show_basic_shape else 0)).scale(self.scale_factor)
        self.blur_outline = VGroup()
        s = (self.shape.get_height() + self.shape.get_width())/2
        if self.blur_width > 1e-4:
            for i in range(self.layer_num):
                layer_i = self.shape.copy().set_stroke(color=self.shadow_color, width=100 * self.blur_width/self.layer_num, opacity=self.shadow_opacity * (1-self.rate_func(i/self.layer_num))).\
                    set_fill(opacity=0).scale((s + (1 if self.shadow_out else -1) * self.blur_width/self.layer_num * (i+0.5))/ s).set_plot_depth(-2)
                self.blur_outline.add(layer_i)

        self.add(self.shape, self.blur_outline)
Example #9
0
    def add_axes(self):
        x_axis = Line(self.tick_width * LEFT / 2, self.width * RIGHT)
        y_axis = Line(MED_LARGE_BUFF * DOWN, self.height * UP)
        ticks = VGroup()
        heights = np.linspace(0, self.height, self.n_ticks + 1)
        values = np.linspace(0, self.max_value, self.n_ticks + 1)
        for y, value in zip(heights, values):
            tick = Line(LEFT, RIGHT)
            tick.set_width(self.tick_width)
            tick.move_to(y * UP)
            ticks.add(tick)
        y_axis.add(ticks)

        self.add(x_axis, y_axis)
        self.x_axis, self.y_axis = x_axis, y_axis

        if self.label_y_axis:
            labels = VGroup()
            for tick, value in zip(ticks, values):
                label = TexMobject(str(np.round(value, 2)))
                label.set_height(self.y_axis_label_height)
                label.next_to(tick, LEFT, SMALL_BUFF)
                labels.add(label)
            self.y_axis_labels = labels
            self.add(labels)
Example #10
0
    def add_axes(self):
        x_axis = Line(self.tick_width * LEFT / 2, self.width * RIGHT)
        y_axis = Line(MED_LARGE_BUFF * DOWN, self.height * UP)
        ticks = VGroup()
        heights = np.linspace(0, self.height, self.n_ticks + 1)
        values = np.linspace(0, self.max_value, self.n_ticks + 1)
        for y, value in zip(heights, values):
            tick = Line(LEFT, RIGHT)
            tick.set_width(self.tick_width)
            tick.move_to(y * UP)
            ticks.add(tick)
        y_axis.add(ticks)

        self.add(x_axis, y_axis)
        self.x_axis, self.y_axis = x_axis, y_axis

        if self.label_y_axis:
            labels = VGroup()
            for tick, value in zip(ticks, values):
                label = Tex(str(np.round(value, 2)))
                label.set_height(self.y_axis_label_height)
                label.next_to(tick, LEFT, SMALL_BUFF)
                labels.add(label)
            self.y_axis_labels = labels
            self.add(labels)
Example #11
0
 def add_label(self):
     self.id_to_label = [
         "0", "H", "He",
         "Li", "Be", "B", "C", "N", "O", "F", "Ne",
         "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar",
         "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr",
         "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe",
         "Cs", "Ba",
         "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu",
         "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn",
         "Fr", "Ra",
         "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr",
         "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Cn", "Nh", "Fl", "Mc", "Lv", "Ts", "Og"
     ]
     self.label_to_id = {}
     for i, label in enumerate(self.id_to_label):
         self.label_to_id[label] = i
     labels = VGroup()
     for i in range(0, 119):
         label = TextMobject(self.id_to_label[i], color=BLACK, background_stroke_width=0)
         label.scale(0.5).move_to(self[0][i][1].get_center()).set_shade_in_3d(z_index_as_group=True).shift(OUT * 1e-3)
         labels.add(label)
     labels[0].set_fill(opacity=0)
     for i in [43, 61, *list(range(84, 119))]:
         labels[i].set_color(RED)
     self.add(labels)
     return self
Example #12
0
    def get_subdivision_braces_and_labels(
        self, parts, labels, direction,
        buff=SMALL_BUFF,
        min_num_quads=1
    ):
        label_mobs = VGroup()
        braces = VGroup()
        for label, part in zip(labels, parts):
            brace = Brace(
                part, direction,
                min_num_quads=min_num_quads,
                buff=buff
            )
            if isinstance(label, Mobject):
                label_mob = label
            else:
                label_mob = Tex(label)
                label_mob.scale(self.default_label_scale_val)
            label_mob.next_to(brace, direction, buff)

            braces.add(brace)
            label_mobs.add(label_mob)
        parts.braces = braces
        parts.labels = label_mobs
        parts.label_kwargs = {
            "labels": label_mobs.copy(),
            "direction": direction,
            "buff": buff,
        }
        return VGroup(parts.braces, parts.labels)
Example #13
0
    def get_coordinate_labels(self, *numbers):
        # TODO: Should merge this with the code from NumberPlane.get_coordinate_labels

        result = VGroup()
        if len(numbers) == 0:
            numbers = list(range(-int(self.x_radius), int(self.x_radius) + 1))
            numbers += [
                complex(0, y) for y in range(-int(self.y_radius),
                                             int(self.y_radius) + 1) if y != 0
            ]
        for number in numbers:
            # if number == complex(0, 0):
            #     continue
            point = self.number_to_point(number)
            num_str = str(number).replace("j", "i")
            if num_str.startswith("0"):
                num_str = "0"
            elif num_str in ["1i", "-1i"]:
                num_str = num_str.replace("1", "")
            num_mob = TexMobject(num_str)
            num_mob.add_background_rectangle()
            num_mob.set_height(self.written_coordinate_height)
            num_mob.next_to(point, DOWN + LEFT, SMALL_BUFF)
            result.add(num_mob)
        self.coordinate_labels = result
        return result
Example #14
0
    def get_subdivision_braces_and_labels(
        self, parts, labels, direction,
        buff=SMALL_BUFF,
        min_num_quads=1
    ):
        label_mobs = VGroup()
        braces = VGroup()
        for label, part in zip(labels, parts):
            brace = Brace(
                part, direction,
                min_num_quads=min_num_quads,
                buff=buff
            )
            if isinstance(label, Mobject):
                label_mob = label
            else:
                label_mob = TexMobject(label)
                label_mob.scale(self.default_label_scale_val)
            label_mob.next_to(brace, direction, buff)

            braces.add(brace)
            label_mobs.add(label_mob)
        parts.braces = braces
        parts.labels = label_mobs
        parts.label_kwargs = {
            "labels": label_mobs.copy(),
            "direction": direction,
            "buff": buff,
        }
        return VGroup(parts.braces, parts.labels)
Example #15
0
    def add_numbers(self, *numbers, excluding=None, font_size=24, x_values=None, **kwargs):
        if x_values is None:
            if numbers is not None:
                if len(numbers) == 1 and isinstance(numbers[0], list):
                    x_values = (numbers[0])
                if len(numbers) == 1 and numbers[0] is None:
                    x_values =  self.get_tick_range()
                elif len(numbers) > 0 and not isinstance(numbers[0], list):
                    x_values = list(numbers)
                else:
                    x_values =self.get_tick_range()
            else:
                x_values = self.get_tick_range()
        
        kwargs["font_size"] = font_size

        numbers = VGroup()
        for x in x_values:
            if self.numbers_to_exclude is not None and x in self.numbers_to_exclude:
                continue
            if excluding is not None and x in excluding:
                continue
            numbers.add(self.get_number_mobject(x, **kwargs))
        self.add(numbers)
        self.numbers = numbers
        return numbers
        '''
Example #16
0
 def get_tips(self):
     result = VGroup()
     if hasattr(self, "tip"):
         result.add(self.tip)
     if hasattr(self, "start_tip"):
         result.add(self.start_tip)
     return result
Example #17
0
 def get_words(self, *index):
     pre_index = []
     pos_index = []
     row_parameter = max([self[i].get_height() for i in range(len(self))])
     word_parameter = max([self[i].get_width() for i in range(len(self))])
     #print(word_parameter)
     start = 0
     for i in range(len(self) - 1):
         distance_letter_between = abs(self[i + 1].get_x() -
                                       self[i].get_x())
         distance_row_between = abs(self[i + 1].get_y() - self[i].get_y())
         if distance_letter_between > word_parameter:
             pre_index.append(start)
             pos_index.append(i + 1)
             start = i + 1
     #print(pre_index)
     pre_index.append(pos_index[-1] + 1)
     pos_index.append(len(self) - 1)
     all_words = VGroup(
         *[self[pre:pos + 1] for pre, pos in zip(pre_index, pos_index)])
     words = VGroup()
     for word in index:
         words.add(all_words[word])
     if len(index) == 0:
         return all_words
     else:
         return words
Example #18
0
    def add_lines(self, left, right):
        line_kwargs = {
            "color": BLUE,
            "stroke_width": 2,
        }
        left_rows = [VGroup(*row) for row in left.get_mob_matrix()]
        h_lines = VGroup()
        for row in left_rows[:-1]:
            h_line = Line(row.get_left(), row.get_right(), **line_kwargs)
            h_line.next_to(row, DOWN, buff=left.v_buff / 2.)
            h_lines.add(h_line)

        right_cols = [
            VGroup(*col) for col in np.transpose(right.get_mob_matrix())
        ]
        v_lines = VGroup()
        for col in right_cols[:-1]:
            v_line = Line(col.get_top(), col.get_bottom(), **line_kwargs)
            v_line.next_to(col, RIGHT, buff=right.h_buff / 2.)
            v_lines.add(v_line)

        self.play(ShowCreation(h_lines))
        self.play(ShowCreation(v_lines))
        self.wait()
        self.show_frame()
 def create_path(self):
     path = VGroup()
     self.get_path_xyz()
     if len(self.path_xyz) > 1:
         for i in range(len(self.path_xyz) - 1):
             if type(self.trail_color) == str:
                 path.add(
                     Line(self.path_xyz[i],
                          self.path_xyz[i + 1],
                          stroke_color=self.trail_color,
                          stroke_opacity=self.rate_func(i /
                                                        len(self.path_xyz)),
                          plot_depth=self.rate_func(2 -
                                                    i / len(self.path_xyz)),
                          stroke_width=self.max_width *
                          self.rate_func(i / len(self.path_xyz))))
             else:
                 path.add(
                     Line(self.path_xyz[i],
                          self.path_xyz[i + 1],
                          stroke_color=self.colors[i],
                          stroke_opacity=self.rate_func(i /
                                                        len(self.path_xyz)),
                          plot_depth=self.rate_func(2 -
                                                    i / len(self.path_xyz)),
                          stroke_width=self.max_width *
                          self.rate_func(i / len(self.path_xyz))))
             # print('i = %d' % i)
             # # print(self.path_xyz)
             # print(self.color)
             # print(self.rate_func(i/len(self.path_xyz)))
             # print(self.max_width*self.rate_func(i/len(self.path_xyz)))
     return path
Example #20
0
 def get_tips(self):
     result = VGroup()
     if hasattr(self, "tip"):
         result.add(self.tip)
     if hasattr(self, "start_tip"):
         result.add(self.start_tip)
     return result
Example #21
0
class DoubleArrow(Arrow):
    def init_tip(self):
        self.tip = VGroup()
        for b in True, False:
            t = self.add_tip(add_at_end=b)
            t.add_at_end = b
            self.tip.add(t)
        self.tip.match_style(self.tip[0])
Example #22
0
class ComplexPlane(NumberPlane):
    CONFIG = {
        "color": BLUE,
        "line_frequency": 1,
    }

    def number_to_point(self, number: complex | float) -> np.ndarray:
        number = complex(number)
        return self.coords_to_point(number.real, number.imag)

    def n2p(self, number: complex | float) -> np.ndarray:
        return self.number_to_point(number)

    def point_to_number(self, point: np.ndarray) -> complex:
        x, y = self.point_to_coords(point)
        return complex(x, y)

    def p2n(self, point: np.ndarray) -> complex:
        return self.point_to_number(point)

    def get_default_coordinate_values(self,
                                      skip_first: bool = True
                                      ) -> list[complex]:
        x_numbers = self.get_x_axis().get_tick_range()[1:]
        y_numbers = self.get_y_axis().get_tick_range()[1:]
        y_numbers = [complex(0, y) for y in y_numbers if y != 0]
        return [*x_numbers, *y_numbers]

    def add_coordinate_labels(self,
                              numbers: list[complex] | None = None,
                              skip_first: bool = True,
                              **kwargs):
        if numbers is None:
            numbers = self.get_default_coordinate_values(skip_first)

        self.coordinate_labels = VGroup()
        for number in numbers:
            z = complex(number)
            if abs(z.imag) > abs(z.real):
                axis = self.get_y_axis()
                value = z.imag
                kwargs["unit"] = "i"
            else:
                axis = self.get_x_axis()
                value = z.real
            number_mob = axis.get_number_mobject(value, **kwargs)
            # For i and -i, remove the "1"
            if z.imag == 1:
                number_mob.remove(number_mob[0])
            if z.imag == -1:
                number_mob.remove(number_mob[1])
                number_mob[0].next_to(number_mob[1],
                                      LEFT,
                                      buff=number_mob[0].get_width() / 4)
            self.coordinate_labels.add(number_mob)
        self.add(self.coordinate_labels)
        return self
 def get_transformer(self, **kwargs):
     transform_kwargs = dict(self.default_apply_complex_function_kwargs)
     transform_kwargs.update(kwargs)
     transformer = VGroup()
     if hasattr(self, "plane"):
         self.prepare_for_transformation(self.plane)
         transformer.add(self.plane)
     transformer.add(*self.transformable_mobjects)
     return transformer, transform_kwargs
def get_submobject_index_labels(mobject, label_height=0.15):
    labels = VGroup()
    for n, submob in enumerate(mobject):
        label = Integer(n)
        label.set_height(label_height)
        label.move_to(submob)
        label.set_stroke(BLACK, 5, background=True)
        labels.add(label)
    return labels
 def get_transformer(self, **kwargs):
     transform_kwargs = dict(self.default_apply_complex_function_kwargs)
     transform_kwargs.update(kwargs)
     transformer = VGroup()
     if hasattr(self, "plane"):
         self.prepare_for_transformation(self.plane)
         transformer.add(self.plane)
     transformer.add(*self.transformable_mobjects)
     return transformer, transform_kwargs
Example #26
0
 def add_ticks(self):
     ticks = VGroup()
     for x in self.get_tick_range():
         size = self.tick_size
         if x in self.numbers_with_elongated_ticks:
             size *= self.longer_tick_multiple
         ticks.add(self.get_tick(x, size))
     self.add(ticks)
     self.ticks = ticks
Example #27
0
 def add_ticks(self) -> None:
     ticks = VGroup()
     for x in self.get_tick_range():
         size = self.tick_size
         if np.isclose(self.numbers_with_elongated_ticks, x).any():
             size *= self.longer_tick_multiple
         ticks.add(self.get_tick(x, size))
     self.add(ticks)
     self.ticks = ticks
Example #28
0
 def get_parts_from_keys(mobject, keys):
     if isinstance(keys, str):
         keys = [keys]
     result = VGroup()
     for key in keys:
         if not isinstance(key, str):
             raise TypeError(key)
         result.add(*mobject.get_parts_by_string(key))
     return result
Example #29
0
 def gen_chars(self, lines_str_list):
     char_index_counter = 0
     chars = VGroup()
     for line_no in range(lines_str_list.__len__()):
         chars.add(VGroup())
         chars[line_no].add(
             *self.lines_text.chars[char_index_counter:char_index_counter +
                                    lines_str_list[line_no].__len__() + 1])
         char_index_counter += lines_str_list[line_no].__len__() + 1
     return chars
Example #30
0
File: debug.py Project: yk616/manim
def index_labels(mobject: Mobject | np.ndarray,
                 label_height: float = 0.15) -> VGroup:
    labels = VGroup()
    for n, submob in enumerate(mobject):
        label = Integer(n)
        label.set_height(label_height)
        label.move_to(submob)
        label.set_stroke(BLACK, 5, background=True)
        labels.add(label)
    return labels
 def create_lines(self):
     lines = VGroup()
     for angle in np.arange(0, TAU, TAU / self.num_lines):
         line = Line(ORIGIN, self.line_length * RIGHT)
         line.shift((self.flash_radius - self.line_length) * RIGHT)
         line.rotate(angle, about_point=ORIGIN)
         lines.add(line)
     lines.set_stroke(color=self.color, width=self.line_stroke_width)
     lines.add_updater(lambda l: l.move_to(self.point))
     return lines
Example #32
0
 def create_boxes(self):
     pos = MyBoxes(resolution=(9, 18), bottom_size=self.bottom_size, gap=0.15, box_height=0.4)
     boxes = VGroup()
     for i in range(0, 119):
         box = MyBox(pos=pos[self.id_to_pos[i]].get_center(), bottom_size=self.bottom_size,
                     box_height=self.box_height, fill_color=self.fill_color)
         box.reset_color()
         boxes.add(box)
     boxes[0].set_fill(opacity=0)
     self.add(boxes)
Example #33
0
    def bar(self,
            x,
            height,
            width=0.8,
            align='center',
            color=None,
            fill_opacity=None,
            stroke_width=None,
            **kwargs):
        if len(x) != len(height):
            raise ValueError("'x' and 'height' should be equal sized")
        if align == 'center':
            align = ORIGIN
        elif align == 'edge' or align == 'right':
            align = RIGHT
        elif align == 'left':
            align = LEFT
        if color is None:
            color = it.cycle([next(self.default_graph_colors_cycle)])
        else:
            if is_sequence(color):
                color = it.cycle(color)
            else:
                color = it.cycle([color])
        if fill_opacity is None:
            fill_opacity = self.default_bar_opacity
        if stroke_width is None:
            stroke_width = self.default_bar_stroke_width

        bar_sequence = VGroup()
        p_x0, p_y0, p_z0 = self.coords_to_point(0, 0)
        for i in range(len(x)):
            if is_sequence(width):
                bar_width = width[i]
            else:
                bar_width = width
            p_x1, p_y1, p_z1 = self.coords_to_point(x[i], height[i])
            p_x2, p_y2, p_z2 = self.coords_to_point(bar_width, 0)
            bar_height = p_y1 - p_y0
            bar_width = p_x2 - p_x0
            bar_center = (p_x1, p_y0, p_z1)
            bar = Rectangle(
                height=bar_height,
                width=bar_width,
                color=next(color),
                fill_opacity=fill_opacity,
                stroke_width=stroke_width,
                **kwargs,
            ).next_to(bar_center, UP + align, buff=0)
            bar_sequence.add(bar)
        if hasattr(self, "bar_sequences") is False:
            self.bar_sequences = VGroup()
        self.bar_sequences.add(bar_sequence)
        self.add(self.bar_sequences)
        return bar_sequence
Example #34
0
class Axes(VGroup, CoordinateSystem):
    CONFIG = {
        "axis_config": {
            "include_tip": True,
        },
        "x_axis_config": {},
        "y_axis_config": {
            "line_to_number_direction": LEFT,
        },
    }

    def __init__(self, x_range=None, y_range=None, **kwargs):
        VGroup.__init__(self, **kwargs)
        self.x_axis = self.create_axis(
            x_range or self.x_range,
            self.x_axis_config,
            self.width,
        )
        self.y_axis = self.create_axis(y_range or self.y_range,
                                       self.y_axis_config, self.height)
        self.y_axis.rotate(90 * DEGREES, about_point=ORIGIN)
        # Add as a separate group in case various other
        # mobjects are added to self, as for example in
        # NumberPlane below
        self.axes = VGroup(self.x_axis, self.y_axis)
        self.add(*self.axes)
        self.center()

    def create_axis(self, range_terms, axis_config, length):
        new_config = merge_dicts_recursively(self.axis_config, axis_config)
        new_config["width"] = length
        axis = NumberLine(range_terms, **new_config)
        axis.shift(-axis.n2p(0))
        return axis

    def coords_to_point(self, *coords):
        origin = self.x_axis.number_to_point(0)
        result = np.array(origin)
        for axis, coord in zip(self.get_axes(), coords):
            result += (axis.number_to_point(coord) - origin)
        return result

    def point_to_coords(self, point):
        return tuple([axis.point_to_number(point) for axis in self.get_axes()])

    def get_axes(self):
        return self.axes

    def add_coordinate_labels(self, x_values=None, y_values=None):
        axes = self.get_axes()
        self.coordinate_labels = VGroup()
        for axis, values in zip(axes, [x_values, y_values]):
            numbers = axis.add_numbers(values, excluding=[0])
            self.coordinate_labels.add(numbers)
        return self.coordinate_labels
Example #35
0
 def pop_tips(self):
     start, end = self.get_start_and_end()
     result = VGroup()
     if self.has_tip():
         result.add(self.tip)
         self.remove(self.tip)
     if self.has_start_tip():
         result.add(self.start_tip)
         self.remove(self.start_tip)
     self.put_start_and_end_on(start, end)
     return result
Example #36
0
 def get_tips(self):
     """
     Returns a VGroup (collection of VMobjects) containing
     the TipableVMObject instance's tips.
     """
     result = VGroup()
     if hasattr(self, "tip"):
         result.add(self.tip)
     if hasattr(self, "start_tip"):
         result.add(self.start_tip)
     return result
Example #37
0
 def pop_tips(self):
     start, end = self.get_start_and_end()
     result = VGroup()
     if self.has_tip():
         result.add(self.tip)
         self.remove(self.tip)
     if self.has_start_tip():
         result.add(self.start_tip)
         self.remove(self.start_tip)
     self.put_start_and_end_on(start, end)
     return result
Example #38
0
 def get_number_mob(self, num):
     result = VGroup()
     place = 0
     max_place = self.max_place
     while place < max_place:
         digit = TexMobject(str(self.get_place_num(num, place)))
         if place >= len(self.digit_place_colors):
             self.digit_place_colors += self.digit_place_colors
         digit.set_color(self.digit_place_colors[place])
         digit.scale(self.num_scale_factor)
         digit.next_to(result, LEFT, buff=SMALL_BUFF, aligned_edge=DOWN)
         result.add(digit)
         place += 1
     return result
Example #39
0
    def get_riemann_rectangles(
        self,
        graph,
        x_min=None,
        x_max=None,
        dx=0.1,
        input_sample_type="left",
        stroke_width=1,
        stroke_color=BLACK,
        fill_opacity=1,
        start_color=None,
        end_color=None,
        show_signed_area=True,
        width_scale_factor=1.001
    ):
        x_min = x_min if x_min is not None else self.x_min
        x_max = x_max if x_max is not None else self.x_max
        if start_color is None:
            start_color = self.default_riemann_start_color
        if end_color is None:
            end_color = self.default_riemann_end_color
        rectangles = VGroup()
        x_range = np.arange(x_min, x_max, dx)
        colors = color_gradient([start_color, end_color], len(x_range))
        for x, color in zip(x_range, colors):
            if input_sample_type == "left":
                sample_input = x
            elif input_sample_type == "right":
                sample_input = x + dx
            elif input_sample_type == "center":
                sample_input = x + 0.5 * dx
            else:
                raise Exception("Invalid input sample type")
            graph_point = self.input_to_graph_point(sample_input, graph)
            points = VGroup(*list(map(VectorizedPoint, [
                self.coords_to_point(x, 0),
                self.coords_to_point(x + width_scale_factor * dx, 0),
                graph_point
            ])))

            rect = Rectangle()
            rect.replace(points, stretch=True)
            if graph_point[1] < self.graph_origin[1] and show_signed_area:
                fill_color = invert_color(color)
            else:
                fill_color = color
            rect.set_fill(fill_color, opacity=fill_opacity)
            rect.set_stroke(stroke_color, width=stroke_width)
            rectangles.add(rect)
        return rectangles
Example #40
0
    def get_division_along_dimension(self, p_list, dim, colors, vect):
        p_list = self.complete_p_list(p_list)
        colors = color_gradient(colors, len(p_list))

        last_point = self.get_edge_center(-vect)
        parts = VGroup()
        for factor, color in zip(p_list, colors):
            part = SampleSpace()
            part.set_fill(color, 1)
            part.replace(self, stretch=True)
            part.stretch(factor, dim)
            part.move_to(last_point, -vect)
            last_point = part.get_edge_center(vect)
            parts.add(part)
        return parts
Example #41
0
    def get_number_design(self, value, symbol):
        num = int(value)
        n_rows = {
            2: 2,
            3: 3,
            4: 2,
            5: 2,
            6: 3,
            7: 3,
            8: 3,
            9: 4,
            10: 4,
        }[num]
        n_cols = 1 if num in [2, 3] else 2
        insertion_indices = {
            5: [0],
            7: [0],
            8: [0, 1],
            9: [1],
            10: [0, 2],
        }.get(num, [])

        top = self.get_top() + symbol.get_height() * DOWN
        bottom = self.get_bottom() + symbol.get_height() * UP
        column_points = [
            interpolate(top, bottom, alpha)
            for alpha in np.linspace(0, 1, n_rows)
        ]

        design = VGroup(*[
            symbol.copy().move_to(point)
            for point in column_points
        ])
        if n_cols == 2:
            space = 0.2 * self.get_width()
            column_copy = design.copy().shift(space * RIGHT)
            design.shift(space * LEFT)
            design.add(*column_copy)
        design.add(*[
            symbol.copy().move_to(
                center_of_mass(column_points[i:i + 2])
            )
            for i in insertion_indices
        ])
        for symbol in design:
            if symbol.get_center()[1] < self.get_center()[1]:
                symbol.rotate_in_place(np.pi)
        return design
Example #42
0
    def get_animation_integral_bounds_change(
        self,
        graph,
        new_t_min,
        new_t_max,
        fade_close_to_origin=True,
        run_time=1.0
    ):
        curr_t_min = self.x_axis.point_to_number(self.area.get_left())
        curr_t_max = self.x_axis.point_to_number(self.area.get_right())
        if new_t_min is None:
            new_t_min = curr_t_min
        if new_t_max is None:
            new_t_max = curr_t_max

        group = VGroup(self.area)
        group.add(self.left_v_line)
        group.add(self.left_T_label_group)
        group.add(self.right_v_line)
        group.add(self.right_T_label_group)

        def update_group(group, alpha):
            area, left_v_line, left_T_label, right_v_line, right_T_label = group
            t_min = interpolate(curr_t_min, new_t_min, alpha)
            t_max = interpolate(curr_t_max, new_t_max, alpha)
            new_area = self.get_area(graph, t_min, t_max)

            new_left_v_line = self.get_vertical_line_to_graph(
                t_min, graph
            )
            new_left_v_line.set_color(left_v_line.get_color())
            left_T_label.move_to(new_left_v_line.get_bottom(), UP)

            new_right_v_line = self.get_vertical_line_to_graph(
                t_max, graph
            )
            new_right_v_line.set_color(right_v_line.get_color())
            right_T_label.move_to(new_right_v_line.get_bottom(), UP)

            # Fade close to 0
            if fade_close_to_origin:
                if len(left_T_label) > 0:
                    left_T_label[0].set_fill(opacity=min(1, np.abs(t_min)))
                if len(right_T_label) > 0:
                    right_T_label[0].set_fill(opacity=min(1, np.abs(t_max)))

            Transform(area, new_area).update(1)
            Transform(left_v_line, new_left_v_line).update(1)
            Transform(right_v_line, new_right_v_line).update(1)
            return group

        return UpdateFromAlphaFunc(group, update_group, run_time=run_time)
Example #43
0
def get_det_text(matrix, determinant=None, background_rect=False, initial_scale_factor=2):
    parens = TexMobject("(", ")")
    parens.scale(initial_scale_factor)
    parens.stretch_to_fit_height(matrix.get_height())
    l_paren, r_paren = parens.split()
    l_paren.next_to(matrix, LEFT, buff=0.1)
    r_paren.next_to(matrix, RIGHT, buff=0.1)
    det = TextMobject("det")
    det.scale(initial_scale_factor)
    det.next_to(l_paren, LEFT, buff=0.1)
    if background_rect:
        det.add_background_rectangle()
    det_text = VGroup(det, l_paren, r_paren)
    if determinant is not None:
        eq = TexMobject("=")
        eq.next_to(r_paren, RIGHT, buff=0.1)
        result = TexMobject(str(determinant))
        result.next_to(eq, RIGHT, buff=0.2)
        det_text.add(eq, result)
    return det_text
Example #44
0
 def __init__(self, focal_point, **kwargs):
     digest_config(self, kwargs)
     circles = VGroup()
     for x in range(self.n_circles):
         circle = Circle(
             radius=self.big_radius,
             stroke_color=BLACK,
             stroke_width=0,
         )
         circle.add_updater(
             lambda c: c.move_to(focal_point)
         )
         circle.save_state()
         circle.set_width(self.small_radius * 2)
         circle.set_stroke(self.color, self.start_stroke_width)
         circles.add(circle)
     animations = [
         Restore(circle)
         for circle in circles
     ]
     super().__init__(*animations, **kwargs)
Example #45
0
    def add_bars(self, values):
        buff = float(self.width) / (2 * len(values) + 1)
        bars = VGroup()
        for i, value in enumerate(values):
            bar = Rectangle(
                height=(value / self.max_value) * self.height,
                width=buff,
                stroke_width=self.bar_stroke_width,
                fill_opacity=self.bar_fill_opacity,
            )
            bar.move_to((2 * i + 1) * buff * RIGHT, DOWN + LEFT)
            bars.add(bar)
        bars.set_color_by_gradient(*self.bar_colors)

        bar_labels = VGroup()
        for bar, name in zip(bars, self.bar_names):
            label = TexMobject(str(name))
            label.scale(self.bar_label_scale_val)
            label.next_to(bar, DOWN, SMALL_BUFF)
            bar_labels.add(label)

        self.add(bars, bar_labels)
        self.bars = bars
        self.bar_labels = bar_labels
Example #46
0
 def move_tip_to(self, point):
     mover = VGroup(self)
     if self.content is not None:
         mover.add(self.content)
     mover.shift(point - self.get_tip())
     return self
Example #47
0
    def get_secant_slope_group(
        self,
        x, graph,
        dx=None,
        dx_line_color=None,
        df_line_color=None,
        dx_label=None,
        df_label=None,
        include_secant_line=True,
        secant_line_color=None,
        secant_line_length=10,
    ):
        """
        Resulting group is of the form VGroup(
            dx_line,
            df_line,
            dx_label, (if applicable)
            df_label, (if applicable)
            secant_line, (if applicable)
        )
        with attributes of those names.
        """
        kwargs = locals()
        kwargs.pop("self")
        group = VGroup()
        group.kwargs = kwargs

        dx = dx or float(self.x_max - self.x_min) / 10
        dx_line_color = dx_line_color or self.default_input_color
        df_line_color = df_line_color or graph.get_color()

        p1 = self.input_to_graph_point(x, graph)
        p2 = self.input_to_graph_point(x + dx, graph)
        interim_point = p2[0] * RIGHT + p1[1] * UP

        group.dx_line = Line(
            p1, interim_point,
            color=dx_line_color
        )
        group.df_line = Line(
            interim_point, p2,
            color=df_line_color
        )
        group.add(group.dx_line, group.df_line)

        labels = VGroup()
        if dx_label is not None:
            group.dx_label = TexMobject(dx_label)
            labels.add(group.dx_label)
            group.add(group.dx_label)
        if df_label is not None:
            group.df_label = TexMobject(df_label)
            labels.add(group.df_label)
            group.add(group.df_label)

        if len(labels) > 0:
            max_width = 0.8 * group.dx_line.get_width()
            max_height = 0.8 * group.df_line.get_height()
            if labels.get_width() > max_width:
                labels.set_width(max_width)
            if labels.get_height() > max_height:
                labels.set_height(max_height)

        if dx_label is not None:
            group.dx_label.next_to(
                group.dx_line,
                np.sign(dx) * DOWN,
                buff=group.dx_label.get_height() / 2
            )
            group.dx_label.set_color(group.dx_line.get_color())

        if df_label is not None:
            group.df_label.next_to(
                group.df_line,
                np.sign(dx) * RIGHT,
                buff=group.df_label.get_height() / 2
            )
            group.df_label.set_color(group.df_line.get_color())

        if include_secant_line:
            secant_line_color = secant_line_color or self.default_derivative_color
            group.secant_line = Line(p1, p2, color=secant_line_color)
            group.secant_line.scale_in_place(
                secant_line_length / group.secant_line.get_length()
            )
            group.add(group.secant_line)

        return group
Example #48
0
class CountingScene(Scene):
    CONFIG = {
        "digit_place_colors": [YELLOW, MAROON_B, RED, GREEN, BLUE, PURPLE_D],
        "counting_dot_starting_position": (FRAME_X_RADIUS - 1) * RIGHT + (FRAME_Y_RADIUS - 1) * UP,
        "count_dot_starting_radius": 0.5,
        "dot_configuration_height": 2,
        "ones_configuration_location": UP + 2 * RIGHT,
        "num_scale_factor": 2,
        "num_start_location": 2 * DOWN,
    }

    def setup(self):
        self.dots = VGroup()
        self.number = 0
        self.max_place = 0
        self.number_mob = VGroup(TexMobject(str(self.number)))
        self.number_mob.scale(self.num_scale_factor)
        self.number_mob.shift(self.num_start_location)

        self.dot_templates = []
        self.dot_template_iterators = []
        self.curr_configurations = []

        self.arrows = VGroup()

        self.add(self.number_mob)

    def get_template_configuration(self, place):
        # This should probably be replaced for non-base-10 counting scenes
        down_right = (0.5) * RIGHT + (np.sqrt(3) / 2) * DOWN
        result = []
        for down_right_steps in range(5):
            for left_steps in range(down_right_steps):
                result.append(
                    down_right_steps * down_right + left_steps * LEFT
                )
        return reversed(result[:self.get_place_max(place)])

    def get_dot_template(self, place):
        # This should be replaced for non-base-10 counting scenes
        dots = VGroup(*[
            Dot(
                point,
                radius=0.25,
                fill_opacity=0,
                stroke_width=2,
                stroke_color=WHITE,
            )
            for point in self.get_template_configuration(place)
        ])
        dots.set_height(self.dot_configuration_height)
        return dots

    def add_configuration(self):
        new_template = self.get_dot_template(len(self.dot_templates))
        new_template.move_to(self.ones_configuration_location)
        left_vect = (new_template.get_width() + LARGE_BUFF) * LEFT
        new_template.shift(
            left_vect * len(self.dot_templates)
        )
        self.dot_templates.append(new_template)
        self.dot_template_iterators.append(
            it.cycle(new_template)
        )
        self.curr_configurations.append(VGroup())

    def count(self, max_val, run_time_per_anim=1):
        for x in range(max_val):
            self.increment(run_time_per_anim)

    def increment(self, run_time_per_anim=1):
        moving_dot = Dot(
            self.counting_dot_starting_position,
            radius=self.count_dot_starting_radius,
            color=self.digit_place_colors[0],
        )
        moving_dot.generate_target()
        moving_dot.set_fill(opacity=0)
        kwargs = {
            "run_time": run_time_per_anim
        }

        continue_rolling_over = True
        first_move = True
        place = 0
        while continue_rolling_over:
            added_anims = []
            if first_move:
                added_anims += self.get_digit_increment_animations()
                first_move = False
            moving_dot.target.replace(
                next(self.dot_template_iterators[place])
            )
            self.play(MoveToTarget(moving_dot), *added_anims, **kwargs)
            self.curr_configurations[place].add(moving_dot)

            if len(self.curr_configurations[place].split()) == self.get_place_max(place):
                full_configuration = self.curr_configurations[place]
                self.curr_configurations[place] = VGroup()
                place += 1
                center = full_configuration.get_center_of_mass()
                radius = 0.6 * max(
                    full_configuration.get_width(),
                    full_configuration.get_height(),
                )
                circle = Circle(
                    radius=radius,
                    stroke_width=0,
                    fill_color=self.digit_place_colors[place],
                    fill_opacity=0.5,
                )
                circle.move_to(center)
                moving_dot = VGroup(circle, full_configuration)
                moving_dot.generate_target()
                moving_dot[0].set_fill(opacity=0)
            else:
                continue_rolling_over = False

    def get_digit_increment_animations(self):
        result = []
        self.number += 1
        is_next_digit = self.is_next_digit()
        if is_next_digit:
            self.max_place += 1
        new_number_mob = self.get_number_mob(self.number)
        new_number_mob.move_to(self.number_mob, RIGHT)
        if is_next_digit:
            self.add_configuration()
            place = len(new_number_mob.split()) - 1
            result.append(FadeIn(self.dot_templates[place]))
            arrow = Arrow(
                new_number_mob[place].get_top(),
                self.dot_templates[place].get_bottom(),
                color=self.digit_place_colors[place]
            )
            self.arrows.add(arrow)
            result.append(ShowCreation(arrow))
        result.append(Transform(
            self.number_mob, new_number_mob,
            lag_ratio=0.5
        ))
        return result

    def get_number_mob(self, num):
        result = VGroup()
        place = 0
        max_place = self.max_place
        while place < max_place:
            digit = TexMobject(str(self.get_place_num(num, place)))
            if place >= len(self.digit_place_colors):
                self.digit_place_colors += self.digit_place_colors
            digit.set_color(self.digit_place_colors[place])
            digit.scale(self.num_scale_factor)
            digit.next_to(result, LEFT, buff=SMALL_BUFF, aligned_edge=DOWN)
            result.add(digit)
            place += 1
        return result

    def is_next_digit(self):
        return False

    def get_place_num(self, num, place):
        return 0

    def get_place_max(self, place):
        return 0
Example #49
0
    def add_spikes(self):
        layers = VGroup()
        radii = np.linspace(
            self.outer_radius,
            self.pupil_radius,
            self.n_spike_layers,
            endpoint=False,
        )
        radii[:2] = radii[1::-1]  # Swap first two
        radii[-1] = interpolate(
            radii[-1], self.pupil_radius, 0.25
        )

        for radius in radii:
            tip_angle = self.spike_angle
            half_base = radius * np.tan(tip_angle)
            triangle, right_half_triangle = [
                Polygon(
                    radius * UP,
                    half_base * RIGHT,
                    vertex3,
                    fill_opacity=1,
                    stroke_width=0,
                )
                for vertex3 in (half_base * LEFT, ORIGIN,)
            ]
            left_half_triangle = right_half_triangle.copy()
            left_half_triangle.flip(UP, about_point=ORIGIN)

            n_spikes = self.n_spikes
            full_spikes = [
                triangle.copy().rotate(
                    -angle,
                    about_point=ORIGIN
                )
                for angle in np.linspace(
                    0, TAU, n_spikes, endpoint=False
                )
            ]
            index = (3 * n_spikes) // 4
            if radius == radii[0]:
                layer = VGroup(*full_spikes)
                layer.rotate(
                    -TAU / n_spikes / 2,
                    about_point=ORIGIN
                )
                layer.brown_index = index
            else:
                half_spikes = [
                    right_half_triangle.copy(),
                    left_half_triangle.copy().rotate(
                        90 * DEGREES, about_point=ORIGIN,
                    ),
                    right_half_triangle.copy().rotate(
                        90 * DEGREES, about_point=ORIGIN,
                    ),
                    left_half_triangle.copy()
                ]
                layer = VGroup(*it.chain(
                    half_spikes[:1],
                    full_spikes[1:index],
                    half_spikes[1:3],
                    full_spikes[index + 1:],
                    half_spikes[3:],
                ))
                layer.brown_index = index + 1

            layers.add(layer)

        # Color spikes
        blues = self.blue_spike_colors
        browns = self.brown_spike_colors
        for layer, blue, brown in zip(layers, blues, browns):
            index = layer.brown_index
            layer[:index].set_color(blue)
            layer[index:].set_color(brown)

        self.spike_layers = layers
        self.add(layers)