Beispiel #1
0
 def get_graph_label(
     self,
     graph,
     label="f(x)",
     x_val=None,
     direction=consts.RIGHT,
     buff=consts.MED_SMALL_BUFF,
     color=None,
 ):
     label = TexMobject(label)
     color = color or graph.get_color()
     label.set_color(color)
     if x_val is None:
         # Search from right to left
         for x in np.linspace(self.x_max, self.x_min, 100):
             point = self.input_to_graph_point(x, graph)
             if point[1] < consts.FRAME_Y_RADIUS:
                 break
         x_val = x
     label.next_to(
         self.input_to_graph_point(x_val, graph),
         direction,
         buff=buff
     )
     label.shift_onto_screen()
     return label
Beispiel #2
0
    def __init__(self, mobject, direction=consts.DOWN, **kwargs):
        digest_config(self, kwargs, locals())
        angle = -np.arctan2(*direction[:2]) + np.pi
        mobject.rotate(-angle, about_point=consts.ORIGIN)
        left = mobject.get_corner(consts.DOWN + consts.LEFT)
        right = mobject.get_corner(consts.DOWN + consts.RIGHT)
        target_width = right[0] - left[0]

        # Adding int(target_width) qquads gives approximately the right width
        num_quads = np.clip(
            int(self.width_multiplier * target_width),
            self.min_num_quads, self.max_num_quads
        )
        tex_string = "\\underbrace{%s}" % (num_quads * "\\qquad")
        TexMobject.__init__(self, tex_string, **kwargs)
        self.tip_point_index = np.argmin(self.get_all_points()[:, 1])
        self.stretch_to_fit_width(target_width)
        self.shift(left - self.get_corner(consts.UP + consts.LEFT) + self.buff * consts.DOWN)
        for mob in mobject, self:
            mob.rotate(angle, about_point=consts.ORIGIN)
Beispiel #3
0
    def add_T_label(self, x_val, side=consts.RIGHT, label=None, color=Color('WHITE'), animated=False, **kwargs):
        triangle = RegularPolygon(n=3, start_angle=np.pi / 2)
        triangle.set_height(consts.MED_SMALL_BUFF)
        triangle.move_to(self.coords_to_point(x_val, 0), consts.UP)
        triangle.set_fill(color, 1)
        triangle.set_stroke(width=0)
        if label is None:
            T_label = TexMobject(self.variable_point_label, fill_color=color)
        else:
            T_label = TexMobject(label, fill_color=color)

        T_label.next_to(triangle, consts.DOWN)
        v_line = self.get_vertical_line_to_graph(
            x_val, self.v_graph,
            color=Color('YELLOW')
        )

        if animated:
            self.play(
                DrawBorderThenFill(triangle),
                ShowCreation(v_line),
                Write(T_label, run_time=1),
                **kwargs
            )

        if np.all(side == consts.LEFT):
            self.left_T_label_group = VGroup(T_label, triangle)
            self.left_v_line = v_line
            self.add(self.left_T_label_group, self.left_v_line)
        elif np.all(side == consts.RIGHT):
            self.right_T_label_group = VGroup(T_label, triangle)
            self.right_v_line = v_line
            self.add(self.right_T_label_group, self.right_v_line)
Beispiel #4
0
    def generate_points(self):
        start_angle = np.pi / 2 + self.arc_angle / 2
        end_angle = np.pi / 2 - self.arc_angle / 2
        self.add(Arc(
            start_angle=start_angle,
            angle=-self.arc_angle
        ))
        tick_angle_range = np.linspace(start_angle, end_angle, self.num_ticks)
        for index, angle in enumerate(tick_angle_range):
            vect = rotate_vector(consts.RIGHT, angle)
            tick = Line((1 - self.tick_length) * vect, vect)
            label = TexMobject(str(10 * index))
            label.set_height(self.tick_length)
            label.shift((1 + self.tick_length) * vect)
            self.add(tick, label)

        needle = Polygon(
            consts.LEFT, consts.UP, consts.RIGHT,
            stroke_width=0,
            fill_opacity=1,
            fill_color=self.needle_color
        )
        needle.stretch_to_fit_width(self.needle_width)
        needle.stretch_to_fit_height(self.needle_height)
        needle.rotate(start_angle - np.pi / 2, about_point=consts.ORIGIN)
        self.add(needle)
        self.needle = needle

        self.center_offset = self.get_center()
Beispiel #5
0
    def get_subdivision_braces_and_labels(self,
                                          parts,
                                          labels,
                                          direction,
                                          buff=consts.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)
Beispiel #6
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 * consts.RIGHT,
                        consts.DOWN + consts.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, consts.DOWN, consts.SMALL_BUFF)
            bar_labels.add(label)

        self.add(bars, bar_labels)
        self.bars = bars
        self.bar_labels = bar_labels
Beispiel #7
0
    def add_axes(self):
        x_axis = Line(self.tick_width * consts.LEFT / 2,
                      self.width * consts.RIGHT)
        y_axis = Line(consts.MED_LARGE_BUFF * consts.DOWN,
                      self.height * consts.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(consts.LEFT, consts.RIGHT)
            tick.set_width(self.tick_width)
            tick.move_to(y * consts.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, consts.LEFT, consts.SMALL_BUFF)
                labels.add(label)
            self.y_axis_labels = labels
            self.add(labels)
Beispiel #8
0
 def add_brackets(self):
     bracket_pair = TexMobject("\\big[", "\\big]")
     bracket_pair.scale(2)
     bracket_pair.stretch_to_fit_height(
         self.get_height() + 2 * self.bracket_v_buff
     )
     l_bracket, r_bracket = bracket_pair.split()
     l_bracket.next_to(self, consts.LEFT, self.bracket_h_buff)
     r_bracket.next_to(self, consts.RIGHT, self.bracket_h_buff)
     self.add(l_bracket, r_bracket)
     self.brackets = VGroup(l_bracket, r_bracket)
     return self
Beispiel #9
0
 def get_axis_label(self,
                    label_tex,
                    axis,
                    edge,
                    direction,
                    buff=consts.MED_SMALL_BUFF):
     label = TexMobject(label_tex)
     label.next_to(axis.get_edge_center(edge), direction, buff=buff)
     label.shift_onto_screen(buff=consts.MED_SMALL_BUFF)
     return label
Beispiel #10
0
def matrix_to_mobject(matrix):
    return TexMobject(matrix_to_tex_string(matrix))
Beispiel #11
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, consts.LEFT, buff=0.1)
    r_paren.next_to(matrix, consts.RIGHT, buff=0.1)
    det = TextMobject("det")
    det.scale(initial_scale_factor)
    det.next_to(l_paren, consts.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, consts.RIGHT, buff=0.1)
        result = TexMobject(str(determinant))
        result.next_to(eq, consts.RIGHT, buff=0.2)
        det_text.add(eq, result)
    return det_text
Beispiel #12
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] * consts.RIGHT + p1[1] * consts.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) * consts.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) * consts.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
Beispiel #13
0
 def get_tex(self, *tex, **kwargs):
     tex_mob = TexMobject(*tex)
     self.put_at_tip(tex_mob, **kwargs)
     return tex_mob
Beispiel #14
0
    def get_vector_label(self, vector, label,
                         at_tip=False,
                         direction="left",
                         rotate=False,
                         color=None,
                         label_scale_factor=VECTOR_LABEL_SCALE_FACTOR):
        if not isinstance(label, TexMobject):
            if len(label) == 1:
                label = "\\vec{\\textbf{%s}}" % label
            label = TexMobject(label)
            if color is None:
                color = vector.get_color()
            label.set_color(color)
        label.scale(label_scale_factor)
        label.add_background_rectangle()

        if at_tip:
            vect = vector.get_vector()
            vect /= get_norm(vect)
            label.next_to(vector.get_end(), vect, buff=consts.SMALL_BUFF)
        else:
            angle = vector.get_angle()
            if not rotate:
                label.rotate(-angle, about_point=consts.ORIGIN)
            if direction == "left":
                label.shift(-label.get_bottom() + 0.1 * consts.UP)
            else:
                label.shift(-label.get_top() + 0.1 * consts.DOWN)
            label.rotate(angle, about_point=consts.ORIGIN)
            label.shift((vector.get_end() - vector.get_start()) / 2)
        return label