예제 #1
0
파일: frame.py 프로젝트: coallaoh/manim
 def __init__(self, **kwargs):
     digest_config(self, kwargs)
     Rectangle.__init__(
         self,
         width=self.aspect_ratio * self.height,
         height=self.height,
         **kwargs
     )
예제 #2
0
파일: drawings.py 프로젝트: coallaoh/manim
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        body = Cube(side_length=1)
        for dim, scale_factor in enumerate(self.body_dimensions):
            body.stretch(scale_factor, dim=dim)
        body.set_width(self.width)
        body.set_fill(self.shaded_body_color, opacity=1)
        body.sort(lambda p: p[2])
        body[-1].set_fill(self.body_color)
        screen_plate = body.copy()
        keyboard = VGroup(*[
            VGroup(*[
                Square(**self.key_color_kwargs)
                for x in range(12 - y % 2)
            ]).arrange(RIGHT, buff=SMALL_BUFF)
            for y in range(4)
        ]).arrange(DOWN, buff=MED_SMALL_BUFF)
        keyboard.stretch_to_fit_width(
            self.keyboard_width_to_body_width * body.get_width(),
        )
        keyboard.stretch_to_fit_height(
            self.keyboard_height_to_body_height * body.get_height(),
        )
        keyboard.next_to(body, OUT, buff=0.1 * SMALL_BUFF)
        keyboard.shift(MED_SMALL_BUFF * UP)
        body.add(keyboard)

        screen_plate.stretch(self.screen_thickness /
                             self.body_dimensions[2], dim=2)
        screen = Rectangle(
            stroke_width=0,
            fill_color=BLACK,
            fill_opacity=1,
        )
        screen.replace(screen_plate, stretch=True)
        screen.scale_in_place(self.screen_width_to_screen_plate_width)
        screen.next_to(screen_plate, OUT, buff=0.1 * SMALL_BUFF)
        screen_plate.add(screen)
        screen_plate.next_to(body, UP, buff=0)
        screen_plate.rotate(
            self.open_angle, RIGHT,
            about_point=screen_plate.get_bottom()
        )
        self.screen_plate = screen_plate
        self.screen = screen

        axis = Line(
            body.get_corner(UP + LEFT + OUT),
            body.get_corner(UP + RIGHT + OUT),
            color=BLACK,
            stroke_width=2
        )
        self.axis = axis

        self.add(body, screen_plate, axis)
        self.rotate(5 * np.pi / 12, LEFT, about_point=ORIGIN)
        self.rotate(np.pi / 6, DOWN, about_point=ORIGIN)
예제 #3
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
예제 #4
0
파일: drawings.py 프로젝트: coallaoh/manim
    def get_face_card_design(self, value, symbol):
        from for_3b1b_videos.pi_creature import PiCreature
        sub_rect = Rectangle(
            stroke_color=BLACK,
            fill_opacity=0,
            height=0.9 * self.get_height(),
            width=0.6 * self.get_width(),
        )
        sub_rect.move_to(self)

        # pi_color = average_color(symbol.get_color(), GREY)
        pi_color = symbol.get_color()
        pi_mode = {
            "J": "plain",
            "Q": "thinking",
            "K": "hooray"
        }[value]
        pi_creature = PiCreature(
            mode=pi_mode,
            color=pi_color,
        )
        pi_creature.set_width(0.8 * sub_rect.get_width())
        if value in ["Q", "K"]:
            prefix = "king" if value == "K" else "queen"
            crown = SVGMobject(file_name=prefix + "_crown")
            crown.set_stroke(width=0)
            crown.set_fill(YELLOW, 1)
            crown.stretch_to_fit_width(0.5 * sub_rect.get_width())
            crown.stretch_to_fit_height(0.17 * sub_rect.get_height())
            crown.move_to(pi_creature.eyes.get_center(), DOWN)
            pi_creature.add_to_back(crown)
            to_top_buff = 0
        else:
            to_top_buff = SMALL_BUFF * sub_rect.get_height()
        pi_creature.next_to(sub_rect.get_top(), DOWN, to_top_buff)
        # pi_creature.shift(0.05*sub_rect.get_width()*RIGHT)

        pi_copy = pi_creature.copy()
        pi_copy.rotate(np.pi, about_point=sub_rect.get_center())

        return VGroup(sub_rect, pi_creature, pi_copy)
예제 #5
0
    def rect_to_mobject(self, rect_element):
        fill_color = rect_element.getAttribute("fill")
        stroke_color = rect_element.getAttribute("stroke")
        stroke_width = rect_element.getAttribute("stroke-width")
        corner_radius = rect_element.getAttribute("rx")

        # input preprocessing
        if fill_color in ["", "none", "#FFF", "#FFFFFF"] or Color(fill_color) == Color(WHITE):
            opacity = 0
            fill_color = BLACK  # shdn't be necessary but avoids error msgs
        if fill_color in ["#000", "#000000"]:
            fill_color = WHITE
        if stroke_color in ["", "none", "#FFF", "#FFFFFF"] or Color(stroke_color) == Color(WHITE):
            stroke_width = 0
            stroke_color = BLACK
        if stroke_color in ["#000", "#000000"]:
            stroke_color = WHITE
        if stroke_width in ["", "none", "0"]:
            stroke_width = 0

        if corner_radius in ["", "0", "none"]:
            corner_radius = 0

        corner_radius = float(corner_radius)

        if corner_radius == 0:
            mob = Rectangle(
                width=self.attribute_to_float(
                    rect_element.getAttribute("width")
                ),
                height=self.attribute_to_float(
                    rect_element.getAttribute("height")
                ),
                stroke_width=stroke_width,
                stroke_color=stroke_color,
                fill_color=fill_color,
                fill_opacity=opacity
            )
        else:
            mob = RoundedRectangle(
                width=self.attribute_to_float(
                    rect_element.getAttribute("width")
                ),
                height=self.attribute_to_float(
                    rect_element.getAttribute("height")
                ),
                stroke_width=stroke_width,
                stroke_color=stroke_color,
                fill_color=fill_color,
                fill_opacity=opacity,
                corner_radius=corner_radius
            )

        mob.shift(mob.get_center() - mob.get_corner(UP + LEFT))
        return mob
예제 #6
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
예제 #7
0
파일: interactive.py 프로젝트: yk616/manim
 def __init__(self, value: bool = True, **kwargs):
     digest_config(self, kwargs)
     self.box = Rectangle(**self.rect_kwargs)
     self.box_content = self.get_checkmark() if value else self.get_cross()
     super().__init__(value, self.box, self.box_content, **kwargs)
     self.add_mouse_press_listner(self.on_mouse_press)
예제 #8
0
파일: frame.py 프로젝트: Tarang74/manim
 def __init__(self, **kwargs):
     digest_config(self, kwargs)
     Rectangle.__init__(self,
                        width=self.aspect_ratio * self.height,
                        height=self.height,
                        **kwargs)
예제 #9
0
파일: frame.py 프로젝트: Tarang74/manim
 def __init__(self, **kwargs):
     Rectangle.__init__(self, **kwargs)
     self.set_width(self.aspect_ratio * self.get_height(), stretch=True)
예제 #10
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
    ):
        """
        Riemman rectangles.

        Parameters
        ----------
        graph : VMobject
            Graph from ``get_graph``
        x_min : float
            TODO
        x_max : float
            TODO
        dx : float
            TODO
        input_sample_type : str
            Can be ``"left"``, ``"center"``, ``"right"``
        """
        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
예제 #11
0
    def construct(self):
        # Add title
        title = self.title = TextMobject("Clicky Stuffs")
        title.scale(1.5)
        title.to_edge(UP, buff=MED_SMALL_BUFF)

        pi_creatures = VGroup(Randolph(), Mortimer())
        for pi, vect in zip(pi_creatures, [LEFT, RIGHT]):
            pi.set_height(title.get_height())
            pi.change_mode("thinking")
            pi.look(DOWN)
            pi.next_to(title, vect, buff=MED_LARGE_BUFF)
        self.add(title, pi_creatures)

        # Set the top of the screen
        logo_box = Square(side_length=2.5)
        logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF)

        black_rect = Rectangle(
            fill_color=BLACK,
            fill_opacity=1,
            stroke_width=3,
            stroke_color=BLACK,
            width=FRAME_WIDTH,
            height=0.6 * FRAME_HEIGHT,
        )
        black_rect.to_edge(UP, buff=0)
        line = DashedLine(FRAME_X_RADIUS * LEFT, FRAME_X_RADIUS * RIGHT)
        line.move_to(ORIGIN)

        # Add thanks
        thanks = TextMobject(self.thanks_words)
        thanks.scale(0.9)
        thanks.next_to(black_rect.get_bottom(), UP, SMALL_BUFF)
        thanks.set_color(YELLOW)
        underline = Line(LEFT, RIGHT)
        underline.match_width(thanks)
        underline.scale(1.1)
        underline.next_to(thanks, DOWN, SMALL_BUFF)
        thanks.add(underline)

        # Build name list
        with open("manimlib/files/patrons.txt", 'r') as fp:
            names = [
                self.modify_patron_name(name.strip())
                for name in fp.readlines()
            ]

        if self.randomize_order:
            random.shuffle(names)
        else:
            names.sort()

        name_labels = VGroup(*map(TextMobject, names))
        name_labels.scale(self.patron_scale_val)
        for label in name_labels:
            if label.get_width() > self.max_patron_width:
                label.set_width(self.max_patron_width)
        columns = VGroup(*[
            VGroup(*name_labels[i::self.n_patron_columns])
            for i in range(self.n_patron_columns)
        ])
        column_x_spacing = 0.5 + max([c.get_width() for c in columns])

        for i, column in enumerate(columns):
            for n, name in enumerate(column):
                name.shift(n * self.name_y_spacing * DOWN)
                name.align_to(ORIGIN, LEFT)
            column.move_to(i * column_x_spacing * RIGHT, UL)
        columns.center()

        max_width = FRAME_WIDTH - 1
        if columns.get_width() > max_width:
            columns.set_width(max_width)
        underline.match_width(columns)
        columns.next_to(underline, DOWN, buff=3)

        # Set movement
        columns.generate_target()
        distance = columns.get_height() + 2
        wait_time = self.scroll_time
        frame = self.camera.frame
        frame_shift = ApplyMethod(
            frame.shift,
            distance * DOWN,
            run_time=wait_time,
            rate_func=linear,
        )
        blink_anims = []
        blank_mob = Mobject()
        for x in range(wait_time):
            if random.random() < 0.25:
                blink_anims.append(Blink(random.choice(pi_creatures)))
            else:
                blink_anims.append(Animation(blank_mob))
        blinks = Succession(*blink_anims)

        static_group = VGroup(black_rect, line, thanks, pi_creatures, title)
        static_group.fix_in_frame()
        self.add(columns, static_group)
        self.play(frame_shift, blinks)
    def scroll_through_patrons(self):
        logo_box = Square(side_length=2.5)
        logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF)
        total_width = FRAME_X_RADIUS - logo_box.get_right()[0]

        black_rect = Rectangle(
            fill_color=BLACK,
            fill_opacity=1,
            stroke_width=3,
            stroke_color=BLACK,
            width=FRAME_WIDTH,
            height=0.6 * FRAME_HEIGHT,
        )
        black_rect.to_edge(UP, buff=0)
        line = DashedLine(FRAME_X_RADIUS * LEFT, FRAME_X_RADIUS * RIGHT)
        line.move_to(ORIGIN)

        thanks = TextMobject(self.thanks_words)
        thanks.scale(0.9)
        thanks.next_to(black_rect.get_bottom(), UP, SMALL_BUFF)
        thanks.set_color(YELLOW)
        underline = Line(LEFT, RIGHT)
        underline.match_width(thanks)
        underline.scale(1.1)
        underline.next_to(thanks, DOWN, SMALL_BUFF)
        thanks.add(underline)

        patrons = VGroup(*list(map(TextMobject, self.specific_patrons)))
        patrons.scale(self.patron_scale_val)
        for patron in patrons:
            if patron.get_width() > self.max_patron_width:
                patron.set_width(self.max_patron_width)
        columns = VGroup(*[
            VGroup(*patrons[i::self.n_patron_columns])
            for i in range(self.n_patron_columns)
        ])
        for column in columns:
            for n, name in enumerate(column):
                name.shift(n * self.name_y_spacing * DOWN)
        columns.arrange(
            RIGHT,
            buff=LARGE_BUFF,
            aligned_edge=UP,
        )
        if columns.get_width() > self.max_patron_width:
            columns.set_width(total_width - 1)

        thanks.to_edge(RIGHT)
        columns.next_to(thanks, DOWN, 3 * LARGE_BUFF)

        columns.generate_target()
        columns.target.move_to(2 * DOWN, DOWN)
        columns.target.align_to(thanks, alignment_vect=RIGHT)
        vect = columns.target.get_center() - columns.get_center()
        distance = get_norm(vect)
        wait_time = 20
        always_shift(columns,
                     direction=normalize(vect),
                     rate=(distance / wait_time))

        self.add(columns, black_rect, line, thanks)
        self.wait(wait_time)
예제 #13
0
    def hist(self,
             x,
             bins=None,
             bin_range=None,
             density=None,
             weights=None,
             cumulative=False,
             histtype='bar',
             align='mid',
             orientation='vertical',
             rwidth=None,
             log=False,
             color=None,
             label=None,
             stacked=False,
             normed=None,
             fill_opacity=None,
             stroke_width=None,
             **kwargs):
        if bins is None:
            bins = self.default_hist_bins
        if bin_range is None:
            bin_range = (min(x), max(x))
        if density is None:
            density = self.default_hist_density
        if align == 'mid':
            align = ORIGIN
        elif align == 'right':
            align = RIGHT
        elif align == 'left':
            align = LEFT
        if rwidth is None:
            rwidth = self.default_hist_rwidth
        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

        data, bin_edges = np.histogram(
            x,
            bins=bins,
            range=bin_range,
            weights=weights,
            density=density,
        )

        histogram = VGroup()
        for i in range(len(bin_edges) - 1):
            x0, y0, z0 = self.coords_to_point(bin_edges[i], 0)
            x1, y1, z1 = self.coords_to_point(bin_edges[i + 1], data[i])
            bin_width = x1 - x0
            bin_center = (x0, y0, z0) + bin_width / 2 * (RIGHT + align)
            bar_height = y1 - y0
            bar_width = rwidth * bin_width
            bar = Rectangle(
                height=bar_height,
                width=bar_width,
                color=next(color),
                fill_opacity=fill_opacity,
                stroke_width=stroke_width,
                **kwargs,
            ).next_to(bin_center, UP, buff=0)
            histogram.add(bar)
        if hasattr(self, "hist_sequences") is False:
            self.hist_sequences = VGroup()
        self.hist_sequences.add(histogram)
        self.add(self.hist_sequences)
        return data, bin_edges, histogram
예제 #14
0
파일: interactive.py 프로젝트: yk616/manim
class ControlPanel(Group):
    CONFIG = {
        "panel_kwargs": {
            "width": FRAME_WIDTH / 4,
            "height": MED_SMALL_BUFF + FRAME_HEIGHT,
            "fill_color": GREY_C,
            "fill_opacity": 1.0,
            "stroke_width": 0.0
        },
        "opener_kwargs": {
            "width": FRAME_WIDTH / 8,
            "height": 0.5,
            "fill_color": GREY_C,
            "fill_opacity": 1.0
        },
        "opener_text_kwargs": {
            "text": "Control Panel",
            "font_size": 20
        }
    }

    def __init__(self, *controls: ControlMobject, **kwargs):
        digest_config(self, kwargs)

        self.panel = Rectangle(**self.panel_kwargs)
        self.panel.to_corner(UP + LEFT, buff=0)
        self.panel.shift(self.panel.get_height() * UP)
        self.panel.add_mouse_scroll_listner(self.panel_on_mouse_scroll)

        self.panel_opener_rect = Rectangle(**self.opener_kwargs)
        self.panel_info_text = Text(**self.opener_text_kwargs)
        self.panel_info_text.move_to(self.panel_opener_rect)

        self.panel_opener = Group(self.panel_opener_rect, self.panel_info_text)
        self.panel_opener.next_to(self.panel, DOWN, aligned_edge=DOWN)
        self.panel_opener.add_mouse_drag_listner(self.panel_opener_on_mouse_drag)

        self.controls = Group(*controls)
        self.controls.arrange(DOWN, center=False, aligned_edge=ORIGIN)
        self.controls.move_to(self.panel)

        super().__init__(
            self.panel, self.panel_opener,
            self.controls,
            **kwargs
        )

        self.move_panel_and_controls_to_panel_opener()
        self.fix_in_frame()

    def move_panel_and_controls_to_panel_opener(self) -> None:
        self.panel.next_to(
            self.panel_opener_rect,
            direction=UP,
            buff=0
        )

        controls_old_x = self.controls.get_x()
        self.controls.next_to(
            self.panel_opener_rect,
            direction=UP,
            buff=MED_SMALL_BUFF
        )

        self.controls.set_x(controls_old_x)

    def add_controls(self, *new_controls: ControlMobject) -> None:
        self.controls.add(*new_controls)
        self.move_panel_and_controls_to_panel_opener()

    def remove_controls(self, *controls_to_remove: ControlMobject) -> None:
        self.controls.remove(*controls_to_remove)
        self.move_panel_and_controls_to_panel_opener()

    def open_panel(self):
        panel_opener_x = self.panel_opener.get_x()
        self.panel_opener.to_corner(DOWN + LEFT, buff=0.0)
        self.panel_opener.set_x(panel_opener_x)
        self.move_panel_and_controls_to_panel_opener()
        return self

    def close_panel(self):
        panel_opener_x = self.panel_opener.get_x()
        self.panel_opener.to_corner(UP + LEFT, buff=0.0)
        self.panel_opener.set_x(panel_opener_x)
        self.move_panel_and_controls_to_panel_opener()
        return self

    def panel_opener_on_mouse_drag(self, mob, event_data: dict[str, np.ndarray]) -> bool:
        point = event_data["point"]
        self.panel_opener.match_y(Dot(point))
        self.move_panel_and_controls_to_panel_opener()
        return False

    def panel_on_mouse_scroll(self, mob, event_data: dict[str, np.ndarray]) -> bool:
        offset = event_data["offset"]
        factor = 10 * offset[1]
        self.controls.set_y(self.controls.get_y() + factor)
        return False
예제 #15
0
파일: interactive.py 프로젝트: yk616/manim
class ColorSliders(Group):
    CONFIG = {
        "sliders_kwargs": {},
        "rect_kwargs": {
            "width": 2.0,
            "height": 0.5,
            "stroke_opacity": 1.0
        },
        "background_grid_kwargs": {
            "colors": [GREY_A, GREY_C],
            "single_square_len": 0.1
        },
        "sliders_buff": MED_LARGE_BUFF,
        "default_rgb_value": 255,
        "default_a_value": 1,
    }

    def __init__(self, **kwargs):
        digest_config(self, kwargs)

        rgb_kwargs = {"value": self.default_rgb_value, "min_value": 0, "max_value": 255, "step": 1}
        a_kwargs = {"value": self.default_a_value, "min_value": 0, "max_value": 1, "step": 0.04}

        self.r_slider = LinearNumberSlider(**self.sliders_kwargs, **rgb_kwargs)
        self.g_slider = LinearNumberSlider(**self.sliders_kwargs, **rgb_kwargs)
        self.b_slider = LinearNumberSlider(**self.sliders_kwargs, **rgb_kwargs)
        self.a_slider = LinearNumberSlider(**self.sliders_kwargs, **a_kwargs)
        self.sliders = Group(
            self.r_slider,
            self.g_slider,
            self.b_slider,
            self.a_slider
        )
        self.sliders.arrange(DOWN, buff=self.sliders_buff)

        self.r_slider.slider.set_color(RED)
        self.g_slider.slider.set_color(GREEN)
        self.b_slider.slider.set_color(BLUE)
        self.a_slider.slider.set_color_by_gradient([BLACK, WHITE])

        self.selected_color_box = Rectangle(**self.rect_kwargs)
        self.selected_color_box.add_updater(
            lambda mob: mob.set_fill(
                self.get_picked_color(), self.get_picked_opacity()
            )
        )
        self.background = self.get_background()

        super().__init__(
            Group(self.background, self.selected_color_box).fix_in_frame(),
            self.sliders,
            **kwargs
        )

        self.arrange(DOWN)

    def get_background(self) -> VGroup:
        single_square_len = self.background_grid_kwargs["single_square_len"]
        colors = self.background_grid_kwargs["colors"]
        width = self.rect_kwargs["width"]
        height = self.rect_kwargs["height"]
        rows = int(height / single_square_len)
        cols = int(width / single_square_len)
        cols = (cols + 1) if (cols % 2 == 0) else cols

        single_square = Square(single_square_len)
        grid = single_square.get_grid(n_rows=rows, n_cols=cols, buff=0.0)
        grid.stretch_to_fit_width(width)
        grid.stretch_to_fit_height(height)
        grid.move_to(self.selected_color_box)

        for idx, square in enumerate(grid):
            assert(isinstance(square, Square))
            square.set_stroke(width=0.0, opacity=0.0)
            square.set_fill(colors[idx % len(colors)], 1.0)

        return grid

    def set_value(self, r: float, g: float, b: float, a: float):
        self.r_slider.set_value(r)
        self.g_slider.set_value(g)
        self.b_slider.set_value(b)
        self.a_slider.set_value(a)

    def get_value(self) -> np.ndarary:
        r = self.r_slider.get_value() / 255
        g = self.g_slider.get_value() / 255
        b = self.b_slider.get_value() / 255
        alpha = self.a_slider.get_value()
        return color_to_rgba(rgb_to_color((r, g, b)), alpha=alpha)

    def get_picked_color(self) -> str:
        rgba = self.get_value()
        return rgb_to_hex(rgba[:3])

    def get_picked_opacity(self) -> float:
        rgba = self.get_value()
        return rgba[3]
    def construct(self):
        self._main_title()

        text_one = TextMobject("Given a list of items sold")
        text_two: TextMobject = TextMobject(
            "Randomly choose items matching this distribution")
        text_two.next_to(text_one, DOWN)
        number_line = NumberLine(
            numbers_with_elongated_ticks=[0, 1],
            include_numbers=True,
            x_min=0,
            x_max=1,
            unit_size=10,
            tick_frequency=0.1,
            # decimal_number_config={"num_decimal_places": 1},
            numbers_to_show=[0, 1])
        number_line.next_to(text_two, UP)

        self.play(ShowCreation(text_one))
        self.wait()
        self.play(ShowCreation(text_two))
        self.wait(4)

        apples_text = TextMobject("Apples:")
        apples_text.set_color(self._apple_colour)

        apples_text.to_edge(UP)
        apples_text.align_to(text_two, LEFT)

        apple_count_text = TextMobject(f"{self._apple_count}")
        apple_count_text.set_color(self._apple_colour)
        apple_count_text.next_to(apples_text, RIGHT)

        banana_text = TextMobject("Bananas:")
        banana_text.set_color(self._banana_colour)

        banana_text.next_to(apples_text, DOWN)
        banana_text.align_to(apples_text, LEFT)

        banana_count_text = TextMobject(f"{self._banana_count}")
        banana_count_text.set_color(self._banana_colour)
        banana_count_text.next_to(banana_text, RIGHT)

        self.play(Transform(text_one, apples_text))
        self.play(ShowCreation(apple_count_text))
        self.play(ShowCreation(banana_text), ShowCreation(banana_count_text))

        banana_bar = Rectangle(
            height=0.4,
            width=number_line.point_to_number(self._banana_fraction * 10) *
            (number_line.number_to_point(1)[0]),
            color=self._banana_colour,
            fill_color=self._banana_colour,
            fill_opacity=0.75)
        banana_bar.next_to(banana_count_text, RIGHT + RIGHT)

        apple_bar = Rectangle(
            height=0.4,
            width=number_line.point_to_number(self._apple_fraction * 10) *
            (number_line.number_to_point(1)[0]),
            color=self._apple_colour,
            fill_color=self._apple_colour,
            fill_opacity=0.75)
        apple_bar.next_to(banana_bar, UP)
        apple_bar.align_to(banana_bar, LEFT)

        self.play(FadeIn(apple_bar), FadeIn(banana_bar))

        self.wait(1.5)

        apple_fraction_text = TextMobject("$\\frac{" + str(self._apple_count) +
                                          "}{" + str(self._apple_count +
                                                     self._banana_count) +
                                          "} = " + str(self._apple_fraction) +
                                          "$")
        apple_fraction_text.next_to(apple_bar, RIGHT)

        banana_fraction_text = TextMobject("$\\frac{" +
                                           str(self._banana_count) + "}{" +
                                           str(self._apple_count +
                                               self._banana_count) + "} = " +
                                           str(self._banana_fraction) + "$")
        banana_fraction_text.next_to(banana_bar, RIGHT)

        self.play(ShowCreation(apple_fraction_text))
        self.play(ShowCreation(banana_fraction_text))

        self.wait(2)

        number_line_map_text = TextMobject(
            "Map these counts to values between 0 and 1")
        number_line_map_text.next_to(text_two, UP)
        self.play(ShowCreation(number_line_map_text))

        self.wait(3)
        self.play(Transform(number_line_map_text, number_line))

        apple_num_ln_bar = Rectangle(
            height=0.4,
            # width=1 - self._apple_fraction * (number_line.number_to_point(1)[0]),
            width=number_line.point_to_number(self._apple_fraction * 10) *
            (number_line.number_to_point(1)[0]),
            color=self._apple_colour,
            fill_color=self._apple_colour,
            fill_opacity=0.25)
        apple_num_ln_bar.move_to(apple_bar, LEFT)
        self.add(apple_num_ln_bar)
        self.wait(2)
        self.play(
            ApplyMethod(apple_num_ln_bar.move_to,
                        number_line.number_to_point(0), LEFT))

        banana_num_ln_bar = Rectangle(
            height=0.4,
            width=number_line.point_to_number(self._banana_fraction * 10) *
            (number_line.number_to_point(1)[0]),
            color=self._banana_colour,
            fill_color=self._banana_colour,
            fill_opacity=0.25)
        banana_num_ln_bar.move_to(banana_bar, LEFT)
        self.add(banana_num_ln_bar)
        self.wait(2)
        self.play(
            ApplyMethod(banana_num_ln_bar.move_to,
                        number_line.number_to_point(1), RIGHT))

        text_scale: float = 0.75
        get_rnd_full = TextMobject(
            "Get a random number $n$ between 0 and 1 (uniform distribution)")

        get_apple_text = TextMobject(
            f"Apple\\quad if $n <= {self._apple_fraction}$",
            tex_to_color_map={"Apple": self._apple_colour})
        get_banana_text = TextMobject(
            f"Banana\\quad if $n > {self._apple_fraction}$",
            tex_to_color_map={"Banana": self._banana_colour})

        get_rnd_full.scale(text_scale)
        get_rnd_full.next_to(text_two, DOWN)
        get_banana_text.next_to(get_apple_text, DOWN)
        step_group = VGroup(get_apple_text, get_banana_text)

        brace = Brace(step_group, LEFT)
        step_text_d = brace.get_text("$n \\sim U(0, 1)$")
        step_text_d.scale(text_scale)
        step_text_d.next_to(get_rnd_full, DOWN + DOWN)
        step_text_d.shift(LEFT)
        brace.next_to(step_text_d, RIGHT)

        step_group.scale(text_scale)
        step_group.next_to(step_text_d, RIGHT + RIGHT + RIGHT)

        self.wait(2)
        self.play(ShowCreation(get_rnd_full))
        self.wait(2)
        self.play(ShowCreation(step_text_d))
        self.wait(2)

        self.play(GrowFromCenter(brace))
        self.wait()
        self.play(ShowCreation(get_apple_text))
        self.wait(2)
        self.play(ShowCreation(get_banana_text))

        # random_nos_to_draw = 10
        # main_arrow = Arrow(ORIGIN, DOWN * 1.3)
        # helper_arrow = Arrow(ORIGIN, LEFT * 1.3)
        #
        # for i in range(random_nos_to_draw):
        #   num: float = np.random.random_sample(1)
        #   point = number_line.number_to_point(num)
        #   arrow_colour = self._apple_colour if num <= self._apple_fraction else self._banana_colour
        #   arrow_recipient = get_apple_text if num <= self._apple_fraction else get_banana_text
        #
        #   main_arrow.set_color(arrow_colour)
        #
        #   if i == 0:
        #     main_arrow.next_to(point, UP)
        #     helper_arrow.next_to(arrow_recipient, RIGHT)
        #     self.play(GrowArrow(main_arrow), GrowArrow(helper_arrow))
        #   else:
        #     self.play(ApplyMethod(helper_arrow.next_to, arrow_recipient, RIGHT),
        #               ApplyMethod(main_arrow.next_to, point, UP))
        #   self.wait()
        #
        # self.play(FadeOut(main_arrow), FadeOut(helper_arrow))
        self.wait()
예제 #17
0
파일: frame.py 프로젝트: vini84200/manim
 def generate_points(self):
     self.width = self.width_to_height_ratio * self.height
     Rectangle.generate_points(self)
예제 #18
0
파일: frame.py 프로젝트: coallaoh/manim
 def __init__(self, **kwargs):
     Rectangle.__init__(self, **kwargs)
     self.set_width(
         self.aspect_ratio * self.get_height(),
         stretch=True
     )
예제 #19
0
파일: interactive.py 프로젝트: yk616/manim
class Textbox(ControlMobject):
    CONFIG = {
        "value_type": np.dtype(object),

        "box_kwargs": {
            "width": 2.0,
            "height": 1.0,
            "fill_color": WHITE,
            "fill_opacity": 1.0,
        },
        "text_kwargs": {
            "color": BLUE
        },
        "text_buff": MED_SMALL_BUFF,
        "isInitiallyActive": False,
        "active_color": BLUE,
        "deactive_color": RED,
    }

    def __init__(self, value: str = "", **kwargs):
        digest_config(self, kwargs)
        self.isActive = self.isInitiallyActive
        self.box = Rectangle(**self.box_kwargs)
        self.box.add_mouse_press_listner(self.box_on_mouse_press)
        self.text = Text(value, **self.text_kwargs)
        super().__init__(value, self.box, self.text, **kwargs)
        self.update_text(value)
        self.active_anim(self.isActive)
        self.add_key_press_listner(self.on_key_press)

    def set_value_anim(self, value: str) -> None:
        self.update_text(value)

    def update_text(self, value: str) -> None:
        text = self.text
        self.remove(text)
        text.__init__(value, **self.text_kwargs)
        height = text.get_height()
        text.set_width(self.box.get_width() - 2 * self.text_buff)
        if text.get_height() > height:
            text.set_height(height)
        text.add_updater(lambda mob: mob.move_to(self.box))
        text.fix_in_frame()
        self.add(text)

    def active_anim(self, isActive: bool) -> None:
        if isActive:
            self.box.set_stroke(self.active_color)
        else:
            self.box.set_stroke(self.deactive_color)

    def box_on_mouse_press(self, mob, event_data) -> bool:
        self.isActive = not self.isActive
        self.active_anim(self.isActive)
        return False

    def on_key_press(self, mob: Mobject, event_data: dict[str, int]) -> bool | None:
        symbol = event_data["symbol"]
        modifiers = event_data["modifiers"]
        char = chr(symbol)
        if mob.isActive:
            old_value = mob.get_value()
            new_value = old_value
            if char.isalnum():
                if (modifiers & PygletWindowKeys.MOD_SHIFT) or (modifiers & PygletWindowKeys.MOD_CAPSLOCK):
                    new_value = old_value + char.upper()
                else:
                    new_value = old_value + char.lower()
            elif symbol in [PygletWindowKeys.SPACE]:
                new_value = old_value + char
            elif symbol == PygletWindowKeys.TAB:
                new_value = old_value + '\t'
            elif symbol == PygletWindowKeys.BACKSPACE:
                new_value = old_value[:-1] or ''
            mob.set_value(new_value)
            return False
예제 #20
0
    def scroll_through_patrons(self):
        logo_box = Square(side_length=2.5)
        logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF)

        black_rect = Rectangle(
            fill_color=BLACK,
            fill_opacity=1,
            stroke_width=3,
            stroke_color=BLACK,
            width=FRAME_WIDTH,
            height=0.6 * FRAME_HEIGHT,
        )
        black_rect.to_edge(UP, buff=0)
        line = DashedLine(FRAME_X_RADIUS * LEFT, FRAME_X_RADIUS * RIGHT)
        line.move_to(ORIGIN)

        thanks = TextMobject(self.thanks_words)
        thanks.scale(0.9)
        thanks.next_to(black_rect.get_bottom(), UP, SMALL_BUFF)
        thanks.set_color(YELLOW)
        underline = Line(LEFT, RIGHT)
        underline.match_width(thanks)
        underline.scale(1.1)
        underline.next_to(thanks, DOWN, SMALL_BUFF)
        thanks.add(underline)

        changed_patron_names = list(
            map(
                self.modify_patron_name,
                self.specific_patrons,
            ))
        changed_patron_names.sort()
        patrons = VGroup(*map(
            TextMobject,
            changed_patron_names,
        ))
        patrons.scale(self.patron_scale_val)
        for patron in patrons:
            if patron.get_width() > self.max_patron_width:
                patron.set_width(self.max_patron_width)
        columns = VGroup(*[
            VGroup(*patrons[i::self.n_patron_columns])
            for i in range(self.n_patron_columns)
        ])
        column_x_spacing = 0.5 + max([c.get_width() for c in columns])

        for i, column in enumerate(columns):
            for n, name in enumerate(column):
                name.shift(n * self.name_y_spacing * DOWN)
                name.align_to(ORIGIN, LEFT)
            column.move_to(i * column_x_spacing * RIGHT, UL)
        columns.center()

        max_width = FRAME_WIDTH - 1
        if columns.get_width() > max_width:
            columns.set_width(max_width)
        underline.match_width(columns)
        # thanks.to_edge(RIGHT, buff=MED_SMALL_BUFF)
        columns.next_to(underline, DOWN, buff=4)

        columns.generate_target()
        columns.target.to_edge(DOWN, buff=4)
        vect = columns.target.get_center() - columns.get_center()
        distance = get_norm(vect)
        wait_time = 20
        always_shift(columns,
                     direction=normalize(vect),
                     rate=(distance / wait_time))

        self.add(columns, black_rect, line, thanks)
        self.wait(wait_time)
예제 #21
0
파일: interactive.py 프로젝트: yk616/manim
 def __init__(self, value: bool = True, **kwargs):
     digest_config(self, kwargs)
     self.box = Rectangle(**self.rect_kwargs)
     super().__init__(value, self.box, **kwargs)
     self.add_mouse_press_listner(self.on_mouse_press)
예제 #22
0
 def __init__(self, mobject, **kwargs):
     digest_config(self, kwargs)
     kwargs["width"] = mobject.get_width() + 2 * self.buff
     kwargs["height"] = mobject.get_height() + 2 * self.buff
     Rectangle.__init__(self, **kwargs)
     self.move_to(mobject)
예제 #23
0
 def __init__(self, mobject, **kwargs):
     digest_config(self, kwargs)
     kwargs["width"] = mobject.get_width() + 2 * self.buff
     kwargs["height"] = mobject.get_height() + 2 * self.buff
     Rectangle.__init__(self, **kwargs)
     self.move_to(mobject)
    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):
        """
        This method returns the VGroup() of the Riemann Rectangles for
        a particular curve.

        Parameters
        ----------
        graph (ParametricFunction)
            The graph whose area needs to be approximated
            by the Riemann Rectangles.
        
        x_min Union[int,float]
            The lower bound from which to start adding rectangles
        
        x_max Union[int,float]
            The upper bound where the rectangles stop.
        
        dx Union[int,float]
            The smallest change in x-values that is 
            considered significant.
        
        input_sample_type str
            Can be any of "left", "right" or "center
        
        stroke_width : Union[int, float]
            The stroke_width of the border of the rectangles.
        
        stroke_color : str
            The string of hex colour of the rectangle's border.

        fill_opacity Union[int, float]
            The opacity of the rectangles.

        start_color : str,
            The hex starting colour for the rectangles,
            this will, if end_color is a different colour,
            make a nice gradient.
        
        end_color : str,
            The hex ending colour for the rectangles,
            this will, if start_color is a different colour,
            make a nice gradient.
        
        show_signed_area : bool (True)
            Whether or not to indicate -ve area if curve dips below
            x-axis.
        
        width_scale_factor : Union[int, float]
            How much the width of the rectangles are scaled by when transforming.
        
        Returns
        -------
        VGroup
            A VGroup containing the Riemann Rectangles.

        """
        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
예제 #25
0
class Checkbox(ContolMobject):
    CONFIG = {
        "value_type": np.dtype(bool),
        "rect_kwargs": {
            "width": 0.5,
            "height": 0.5,
            "fill_opacity": 0.0
        },
        "checkmark_kwargs": {
            "stroke_color": GREEN,
            "stroke_width": 6,
        },
        "cross_kwargs": {
            "stroke_color": RED,
            "stroke_width": 6,
        },
        "box_content_buff": SMALL_BUFF
    }

    def __init__(self, value=True, **kwargs):
        digest_config(self, kwargs)
        self.box = Rectangle(**self.rect_kwargs)
        self.box_content = self.get_checkmark() if value else self.get_cross()
        super().__init__(value, self.box, self.box_content, **kwargs)

    def assert_value(self, value):
        assert (isinstance(value, bool))

    def toggle_value(self):
        super().set_value(not self.get_value())

    def set_value_anim(self, value):
        if value:
            self.box_content.become(self.get_checkmark())
        else:
            self.box_content.become(self.get_cross())

    def on_mouse_press(self, point, button, mods):
        self.toggle_value()
        return False

    # Helper methods

    def get_checkmark(self):
        checkmark = VGroup(
            Line(UP / 2 + 2 * LEFT, DOWN + LEFT, **self.checkmark_kwargs),
            Line(DOWN + LEFT, UP + RIGHT, **self.checkmark_kwargs))

        checkmark.stretch_to_fit_width(self.box.get_width())
        checkmark.stretch_to_fit_height(self.box.get_height())
        checkmark.scale(0.5)
        checkmark.move_to(self.box)
        return checkmark

    def get_cross(self):
        cross = VGroup(Line(UP + LEFT, DOWN + RIGHT, **self.cross_kwargs),
                       Line(UP + RIGHT, DOWN + LEFT, **self.cross_kwargs))

        cross.stretch_to_fit_width(self.box.get_width())
        cross.stretch_to_fit_height(self.box.get_height())
        cross.scale(0.5)
        cross.move_to(self.box)
        return cross
예제 #26
0
    def scroll_through_patrons(self):
        logo_box = Square(side_length=2.5)
        logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF)
        total_width = FRAME_X_RADIUS - logo_box.get_right()[0]

        black_rect = Rectangle(
            fill_color=BLACK,
            fill_opacity=1,
            stroke_width=3,
            stroke_color=BLACK,
            width=FRAME_WIDTH,
            height=0.6 * FRAME_HEIGHT,
        )
        black_rect.to_edge(UP, buff=0)
        line = DashedLine(FRAME_X_RADIUS * LEFT, FRAME_X_RADIUS * RIGHT)
        line.move_to(ORIGIN)

        thanks = TextMobject(self.thanks_words)
        thanks.scale(0.9)
        thanks.next_to(black_rect.get_bottom(), UP, SMALL_BUFF)
        thanks.set_color(YELLOW)
        underline = Line(LEFT, RIGHT)
        underline.match_width(thanks)
        underline.scale(1.1)
        underline.next_to(thanks, DOWN, SMALL_BUFF)
        thanks.add(underline)

        changed_patron_names = map(
            self.modify_patron_name,
            self.specific_patrons,
        )
        patrons = VGroup(*map(
            TextMobject,
            changed_patron_names,
        ))
        patrons.scale(self.patron_scale_val)
        for patron in patrons:
            if patron.get_width() > self.max_patron_width:
                patron.set_width(self.max_patron_width)
        columns = VGroup(*[
            VGroup(*patrons[i::self.n_patron_columns])
            for i in range(self.n_patron_columns)
        ])
        for column in columns:
            for n, name in enumerate(column):
                name.shift(n * self.name_y_spacing * DOWN)
        columns.arrange(
            RIGHT, buff=LARGE_BUFF,
            aligned_edge=UP,
        )
        if columns.get_width() > self.max_patron_width:
            columns.set_width(total_width - 1)

        thanks.to_edge(RIGHT, buff=MED_SMALL_BUFF)
        columns.next_to(underline, DOWN, buff=2)

        columns.generate_target()
        columns.target.to_edge(DOWN, buff=2)
        vect = columns.target.get_center() - columns.get_center()
        distance = get_norm(vect)
        wait_time = 20
        always_shift(
            columns,
            direction=normalize(vect),
            rate=(distance / wait_time)
        )

        self.add(columns, black_rect, line, thanks)
        self.wait(wait_time)