示例#1
0
    def scale(self, factor, **kwargs):
        if self.get_length() == 0:
            return self

        has_tip = self.has_tip()
        has_start_tip = self.has_start_tip()
        if has_tip or has_start_tip:
            old_tips = self.pop_tips()

        VMobject.scale(self, factor, **kwargs)
        self.set_stroke_width_from_length()

        # So horribly confusing, must redo
        if has_tip:
            self.add_tip()
            old_tips[0].points[:, :] = self.tip.points
            self.remove(self.tip)
            self.tip = old_tips[0]
            self.add(self.tip)
        if has_start_tip:
            self.add_tip(at_start=True)
            old_tips[1].points[:, :] = self.start_tip.points
            self.remove(self.start_tip)
            self.start_tip = old_tips[1]
            self.add(self.start_tip)
        return self
示例#2
0
 def init_colors(self):
     VMobject.init_colors(self)
     internal_pis = [
         pi
         for pi in self.get_family()
         if isinstance(pi, PiCreature)
     ]
     random.seed(self.random_seed)
     for pi in reversed(internal_pis):
         color = random.choice(self.colors)
         pi.set_color(color)
         pi.set_stroke(color, width=0)
示例#3
0
    def init_points(self) -> None:
        uv_surface = self.uv_surface

        full_nu, full_nv = uv_surface.resolution
        part_nu, part_nv = self.resolution
        # 'indices' are treated as floats. Later, there will be
        # an interpolation between the floor and ceiling of these
        # indices
        u_indices = np.linspace(0, full_nu - 1, part_nu)
        v_indices = np.linspace(0, full_nv - 1, part_nv)

        points, du_points, dv_points = uv_surface.get_surface_points_and_nudged_points(
        )
        normals = uv_surface.get_unit_normals()
        nudge = self.normal_nudge
        nudged_points = points + nudge * normals

        for ui in u_indices:
            path = VMobject()
            low_ui = full_nv * int(math.floor(ui))
            high_ui = full_nv * int(math.ceil(ui))
            path.set_points_smoothly(
                interpolate(nudged_points[low_ui:low_ui + full_nv],
                            nudged_points[high_ui:high_ui + full_nv], ui % 1))
            self.add(path)
        for vi in v_indices:
            path = VMobject()
            path.set_points_smoothly(
                interpolate(nudged_points[int(math.floor(vi))::full_nv],
                            nudged_points[int(math.ceil(vi))::full_nv],
                            vi % 1))
            self.add(path)
示例#4
0
    def scale(self, factor, **kwargs):
        has_tip = self.has_tip()
        has_start_tip = self.has_start_tip()
        if has_tip or has_start_tip:
            self.pop_tips()

        VMobject.scale(self, factor, **kwargs)
        self.set_stroke_width_from_length()

        if has_tip:
            self.add_tip()
        if has_start_tip:
            self.add_tip(at_start=True)
        return self
示例#5
0
 def __init__(self,
              t_func: Callable[[float], np.ndarray],
              t_range: Sequence[float] | None = None,
              **kwargs):
     digest_config(self, kwargs)
     if t_range is not None:
         self.t_range[:len(t_range)] = t_range
     # To be backward compatible with all the scenes specifying t_min, t_max, step_size
     self.t_range = [
         kwargs.get("t_min", self.t_range[0]),
         kwargs.get("t_max", self.t_range[1]),
         kwargs.get("step_size", self.t_range[2]),
     ]
     self.t_func = t_func
     VMobject.__init__(self, **kwargs)
示例#6
0
 def __init__(self, svg_string=None, **kwargs):
     #### EULERTOUR_INIT_START ####
     if not hasattr(self, "args"):
         self.args = serialize_args([])
     if not hasattr(self, "config"):
         self.config = serialize_config({
             'svg_string': svg_string,
             **kwargs,
         })
     #### EULERTOUR_INIT_START ####
     digest_config(self, kwargs)
     self.svg_string = svg_string or self.svg_string
     assert (self.svg_string is not None)
     VMobject.__init__(self, **kwargs)
     self.move_into_position()
示例#7
0
 def __init__(self, path_string, **kwargs):
     #### EULERTOUR_INIT_START ####
     if not hasattr(self, "args"):
         self.args = serialize_args([path_string])
     if not hasattr(self, "config"):
         self.config = serialize_config({
             **kwargs,
         })
     if hasattr(self, 'kwargs'):
         self.kwargs = {'path_string': path_string, **kwargs, **self.kwargs}
     else:
         self.kwargs = {'path_string': path_string, **kwargs}
     #### EULERTOUR_INIT_START ####
     digest_locals(self)
     VMobject.__init__(self, **kwargs)
示例#8
0
 def __init__(self, **kwargs):
     #### EULERTOUR_INIT_START ####
     if not hasattr(self, "args"):
         self.args = serialize_args([])
     if not hasattr(self, "config"):
         self.config = serialize_config({
             **kwargs,
         })
     #### EULERTOUR_INIT_START ####
     VMobject.__init__(self, **kwargs)
     self.set_points_as_corners([UP, UP + RIGHT, RIGHT])
     self.set_width(self.width, about_point=ORIGIN)
     self.rotate(self.angle, about_point=ORIGIN)
     #### EULERTOUR_INIT_END ####
     register_mobject(self)
示例#9
0
 def __init__(self, vmobject: VMobject, **kwargs):
     digest_config(self, kwargs)
     max_stroke_width = vmobject.get_stroke_width()
     max_time_width = kwargs.pop("time_width", self.time_width)
     AnimationGroup.__init__(self, *[
         VShowPassingFlash(
             vmobject.copy().set_stroke(width=stroke_width),
             time_width=time_width,
             **kwargs
         )
         for stroke_width, time_width in zip(
             np.linspace(0, max_stroke_width, self.n_segments),
             np.linspace(max_time_width, 0, self.n_segments)
         )
     ])
示例#10
0
    def __init__(self, **kwargs):

        digest_config(self, kwargs)
        self.pdfunction = normal_pdf
        if not self.set_up_the_bot_curve:
            self.num_of_anchor_in_bottom_curve = 0
        #determin x_max and x_min
        side_probability = (1. - self.confidence_interval) / 2
        self.x_max = self.std * (inverse_of_normal_cdf(
            side_probability + self.confidence_interval)) + self.mean
        self.x_min = self.std * (
            inverse_of_normal_cdf(side_probability)) + self.mean

        VMobject.__init__(self, **kwargs)
        self.highest_points = self.get_highest_point()
示例#11
0
 def prtV(self, arg=None):
     from manimlib.mobject.types.vectorized_mobject import VMobject
     if arg is None:
         print(self)
     else:
         print(arg)
     return VMobject()
示例#12
0
文件: brace.py 项目: Akaj-lab/manim
 def shift_brace(self, obj: VMobject | list[VMobject], **kwargs):
     if isinstance(obj, list):
         obj = VMobject(*obj)
     self.brace = Brace(obj, self.brace_direction, **kwargs)
     self.brace.put_at_tip(self.label)
     self.submobjects[0] = self.brace
     return self
示例#13
0
文件: brace.py 项目: coallaoh/manim
    def __init__(self, obj, text, brace_direction=DOWN, **kwargs):
        VMobject.__init__(self, **kwargs)
        self.brace_direction = brace_direction
        if isinstance(obj, list):
            obj = VMobject(*obj)
        self.brace = Brace(obj, brace_direction, **kwargs)

        if isinstance(text, tuple) or isinstance(text, list):
            self.label = self.label_constructor(*text, **kwargs)
        else:
            self.label = self.label_constructor(str(text))
        if self.label_scale != 1:
            self.label.scale(self.label_scale)

        self.brace.put_at_tip(self.label)
        self.submobjects = [self.brace, self.label]
示例#14
0
文件: brace.py 项目: Akaj-lab/manim
    def __init__(self,
                 obj: VMobject | list[VMobject],
                 text: str | Iterable[str],
                 brace_direction: np.ndarray = DOWN,
                 **kwargs) -> None:
        VMobject.__init__(self, **kwargs)
        self.brace_direction = brace_direction
        if isinstance(obj, list):
            obj = VMobject(*obj)
        self.brace = Brace(obj, brace_direction, **kwargs)

        self.label = self.label_constructor(*listify(text), **kwargs)
        self.label.scale(self.label_scale)

        self.brace.put_at_tip(self.label, buff=self.label_buff)
        self.set_submobjects([self.brace, self.label])
示例#15
0
 def set_style_data(self,
                    stroke_color=None,
                    stroke_width=None,
                    fill_color=None,
                    fill_opacity=None,
                    family=True
                    ):
     # Unchangable style, except for fill_opacity
     VMobject.set_style_data(
         self,
         stroke_color=BLACK,
         stroke_width=0,
         fill_color=BLACK,
         fill_opacity=fill_opacity
     )
     return self
示例#16
0
 def __init__(self, start=LEFT, end=RIGHT, **kwargs):
     #### EULERTOUR_INIT_START ####
     if not hasattr(self, "args"):
         self.args = serialize_args([])
     if not hasattr(self, "config"):
         self.config = serialize_config({
             'start': start,
             'end': end,
             **kwargs,
         })
     #### EULERTOUR_INIT_START ####
     digest_config(self, kwargs)
     self.set_start_and_end_attrs(start, end)
     VMobject.__init__(self, **kwargs)
     #### EULERTOUR_INIT_END ####
     register_mobject(self)
示例#17
0
 def get_circle_by_fraction(self, p, q, thres = 1e-6):
     x = p/q
     for circle in self.circles:
         cx = self.axes.point_to_coords(circle.get_center())[0]
         if np.abs(x - cx) < thres:
             return circle
     return VMobject()
示例#18
0
文件: geometry.py 项目: ggarza/manim
    def scale(self, factor, **kwargs):
        has_tip = self.has_tip()
        has_start_tip = self.has_start_tip()
        if has_tip or has_start_tip:
            old_tips = self.pop_tips()

        VMobject.scale(self, factor, **kwargs)
        self.set_stroke_width_from_length()

        if has_tip:
            self.add_tip()
            self.tip.match_style(old_tips[0])
        if has_start_tip:
            self.add_tip(at_start=True)
            self.start_tip.match_style(old_tips[1])
        return self
示例#19
0
 def set_style_data(self,
                    stroke_color=None,
                    stroke_width=None,
                    fill_color=None,
                    fill_opacity=None,
                    family=True
                    ):
     # Unchangable style, except for fill_opacity
     VMobject.set_style_data(
         self,
         stroke_color=BLACK,
         stroke_width=0,
         fill_color=BLACK,
         fill_opacity=fill_opacity
     )
     return self
示例#20
0
 def get_label_by_fraction(self, p, q, thres = 1e-6):
     x = p/q
     for label in self.labels:
         lx = self.axes.point_to_coords(label.get_center())[0]
         if np.abs(x - lx) < thres:
             return label
     return VMobject()
示例#21
0
 def use_to_mobjects(self, use_element):
     # Remove initial "#" character
     ref = use_element.getAttribute("xlink:href")[1:]
     if ref not in self.ref_to_element:
         warnings.warn("%s not recognized" % ref)
         return VMobject()
     return self.get_mobjects_from(self.ref_to_element[ref])
示例#22
0
    def get_mobjects_from(self, element):
        result = []
        if not isinstance(element, minidom.Element):
            return result
        if element.tagName == 'defs':
            self.update_ref_to_element(element)
        elif element.tagName == 'style':
            pass  # TODO, handle style
        elif element.tagName in ['g', 'svg']:
            result += it.chain(*[
                self.get_mobjects_from(child) for child in element.childNodes
            ])
        elif element.tagName == 'path':
            result.append(
                self.path_string_to_mobject(element.getAttribute('d')))
        elif element.tagName == 'use':
            result += self.use_to_mobjects(element)
        elif element.tagName == 'rect':
            result.append(self.rect_to_mobject(element))
        elif element.tagName == 'circle':
            result.append(self.circle_to_mobject(element))
        elif element.tagName == 'ellipse':
            result.append(self.ellipse_to_mobject(element))
        elif element.tagName in ['polygon', 'polyline']:
            result.append(self.polygon_to_mobject(element))
        else:
            pass  # TODO
            # warnings.warn("Unknown element type: " + element.tagName)
        result = [m for m in result if m is not None]
        self.handle_transforms(element, VMobject(*result))
        if len(result) > 1 and not self.unpack_groups:
            result = [VGroup(*result)]

        return result
示例#23
0
    def __init__(self, obj, text, brace_direction=DOWN, **kwargs):
        VMobject.__init__(self, **kwargs)
        self.brace_direction = brace_direction
        if isinstance(obj, list):
            obj = VMobject(*obj)
        self.brace = Brace(obj, brace_direction, **kwargs)

        if isinstance(text, tuple) or isinstance(text, list):
            self.label = self.label_constructor(*text, **kwargs)
        else:
            self.label = self.label_constructor(str(text))
        if self.label_scale != 1:
            self.label.scale(self.label_scale)

        self.brace.put_at_tip(self.label)
        self.submobjects = [self.brace, self.label]
示例#24
0
 def __init__(self, vmobject: VMobject, **kwargs):
     assert(isinstance(vmobject, VMobject))
     self.sm_to_index = dict([
         (hash(sm), 0)
         for sm in vmobject.get_family()
     ])
     super().__init__(vmobject, **kwargs)
示例#25
0
 def __init__(self, start_angle=0, angle=TAU / 4, **kwargs):
     #### EULERTOUR_INIT_START ####
     if not hasattr(self, "args"):
         self.args = serialize_args([])
     if not hasattr(self, "config"):
         self.config = serialize_config({
             'start_angle': start_angle,
             'angle': angle,
             **kwargs,
         })
     #### EULERTOUR_INIT_START ####
     self.start_angle = start_angle
     self.angle = angle
     VMobject.__init__(self, **kwargs)
     #### EULERTOUR_INIT_END ####
     register_mobject(self)
示例#26
0
    def __init__(self, chem, name, name_direction=DOWN, **kwargs):

        VMobject.__init__(self, **kwargs)

        if isinstance(chem, ChemObject):
            self.chem = chem
        else:
            self.chem = ChemObject(chem, **kwargs)

        if isinstance(name, self.label_constructor):
            self.name = name
        else:
            self.name = self.label_constructor(name, **kwargs)

        self.name.next_to(self.chem, name_direction, buff=self.buff)

        self.submobjects = [self.chem, self.name]
示例#27
0
 def set_style_data(
     self,
     stroke_color: ManimColor | None = None,
     stroke_width: float | None = None,
     fill_color: ManimColor | None = None,
     fill_opacity: float | None = None,
     family: bool = True
 ):
     # Unchangeable style, except for fill_opacity
     VMobject.set_style_data(
         self,
         stroke_color=BLACK,
         stroke_width=0,
         fill_color=BLACK,
         fill_opacity=fill_opacity
     )
     return self
示例#28
0
 def add_tip(self, add_at_end=True):
     tip = VMobject(
         close_new_points=True,
         mark_paths_closed=True,
         fill_color=self.color,
         fill_opacity=1,
         stroke_color=self.color,
         stroke_width=0,
     )
     tip.add_at_end = add_at_end
     self.set_tip_points(tip, add_at_end, preserve_normal=False)
     self.add(tip)
     if not hasattr(self, 'tip'):
         self.tip = VGroup()
         self.tip.match_style(tip)
     self.tip.add(tip)
     return tip
示例#29
0
 def __init__(self, tex_string, **kwargs):
     #### EULERTOUR_INIT_START ####
     if not hasattr(self, "args"):
         self.args = serialize_args([tex_string])
     if not hasattr(self, "config"):
         self.config = serialize_config({
             **kwargs,
         })
     if hasattr(self, 'kwargs'):
         self.kwargs = {'tex_string': tex_string, **kwargs, **self.kwargs}
     else:
         self.kwargs = {'tex_string': tex_string, **kwargs}
     #### EULERTOUR_INIT_START ####
     digest_config(self, kwargs)
     assert (isinstance(tex_string, str))
     self.tex_string = tex_string
     VMobject.__init__(self, **kwargs)
示例#30
0
 def generate_points(self):
     if self.order < 0:
         return VMobject()
     tc = TohruCurve(order = self.order)
     kc = KannaCurve(order = self.order)
     kc.shift(tc.get_end() - kc.get_start())
     group = VGroup(tc, kc).center()
     self.add(group)
示例#31
0
 def __init__(self, *vertices, **kwargs):
     VMobject.__init__(self, **kwargs)
     self.set_points_as_corners([*vertices, vertices[0]])
     x, y = [], []
     for i in range(len(vertices)):
         x.append(vertices[i][0])
         y.append(vertices[i][1])
     self.x = np.asfarray(x)
     self.y = np.asfarray(y)
     # Closes the polygon if were open
     if x[0] != x[-1] or y[0] != y[-1]:
         self.x = np.concatenate((self.x, [x[0]]))
         self.y = np.concatenate((self.y, [y[0]]))
     # Forced anti-clockwise coordinates
     if self._det(self.x, self.y) < 0:
         self.x = self.x[::-1]
         self.y = self.y[::-1]
示例#32
0
 def get_displayed(self, mobjects):
     mobjs = self.get_restructured_mobject_list(
         mobjects,
         self.get_restructured_mobject_list(mobjects, self.mobjects))
     if mobjs:
         return VGroup(*mobjs)
     else:
         return VMobject()
示例#33
0
 def draw_lines(self):
     lines = []
     origin = self.coordinate_system.get_origin()
     for point in self.get_start_points():
         points = [point]
         total_arc_len = 0
         time = 0
         for x in range(self.max_time_steps):
             time += self.dt
             last_point = points[-1]
             new_point = last_point + self.dt * (
                 self.point_func(last_point) - origin)
             points.append(new_point)
             total_arc_len += get_norm(new_point - last_point)
             if get_norm(last_point) > self.cutoff_norm:
                 break
             if total_arc_len > self.arc_len:
                 break
         line = VMobject()
         line.virtual_time = time
         step = max(1, int(len(points) / self.n_samples_per_line))
         line.set_points_as_corners(points[::step])
         line.make_approximately_smooth()
         lines.append(line)
     self.set_submobjects(lines)
示例#34
0
 def set_default_config_from_length(self, vmobject: VMobject) -> None:
     length = len(vmobject.family_members_with_points())
     if self.run_time is None:
         if length < 15:
             self.run_time = 1
         else:
             self.run_time = 2
     if self.lag_ratio is None:
         self.lag_ratio = min(4.0 / (length + 1.0), 0.2)
示例#35
0
文件: matrix.py 项目: coallaoh/manim
 def __init__(self, matrix, **kwargs):
     """
     Matrix can either either include numbres, tex_strings,
     or mobjects
     """
     VMobject.__init__(self, **kwargs)
     matrix = np.array(matrix, ndmin=1)
     mob_matrix = self.matrix_to_mob_matrix(matrix)
     self.organize_mob_matrix(mob_matrix)
     self.elements = VGroup(*mob_matrix.flatten())
     self.add(self.elements)
     self.add_brackets()
     self.center()
     self.mob_matrix = mob_matrix
     if self.add_background_rectangles_to_entries:
         for mob in self.elements:
             mob.add_background_rectangle()
     if self.include_background_rectangle:
         self.add_background_rectangle()
示例#36
0
    def show_ghost_movement(self, vector):
        if isinstance(vector, Arrow):
            vector = vector.get_end() - vector.get_start()
        elif len(vector) == 2:
            vector = np.append(np.array(vector), 0.0)
        x_max = int(FRAME_X_RADIUS + abs(vector[0]))
        y_max = int(FRAME_Y_RADIUS + abs(vector[1]))
        dots = VMobject(*[
            Dot(x * RIGHT + y * UP)
            for x in range(-x_max, x_max)
            for y in range(-y_max, y_max)
        ])
        dots.set_fill(BLACK, opacity=0)
        dots_halfway = dots.copy().shift(vector / 2).set_fill(WHITE, 1)
        dots_end = dots.copy().shift(vector)

        self.play(Transform(
            dots, dots_halfway, rate_func=rush_into
        ))
        self.play(Transform(
            dots, dots_end, rate_func=rush_from
        ))
        self.remove(dots)
示例#37
0
    def __init__(self, **kwargs):
        SVGMobject.__init__(self, **kwargs)

        path = self.submobjects[0]
        subpaths = path.get_subpaths()
        path.clear_points()
        for indices in [(0, 1), (2, 3), (4, 6, 7), (5,), (8,)]:
            part = VMobject()
            for index in indices:
                part.append_points(subpaths[index])
            path.add(part)

        self.set_height(self.height)
        self.set_stroke(color=WHITE, width=0)
        self.set_fill(self.color, opacity=1)

        from manimlib.for_3b1b_videos.pi_creature import Randolph
        randy = Randolph(mode="happy")
        randy.set_height(0.6 * self.get_height())
        randy.stretch(0.8, 0)
        randy.look(RIGHT)
        randy.move_to(self)
        randy.shift(0.07 * self.height * (RIGHT + UP))
        self.randy = self.pi_creature = randy
        self.add_to_back(randy)

        orientation_line = Line(self.get_left(), self.get_right())
        orientation_line.set_stroke(width=0)
        self.add(orientation_line)
        self.orientation_line = orientation_line

        for light, color in zip(self.get_lights(), self.light_colors):
            light.set_fill(color, 1)
            light.is_subpath = False

        self.add_treds_to_tires()
示例#38
0
文件: light.py 项目: coallaoh/manim
    def generate_points(self):

        self.add(self.source_point)

        self.lighthouse = Lighthouse()
        self.ambient_light = AmbientLight(
            source_point=VectorizedPoint(location=self.get_source_point()),
            color=self.color,
            num_levels=self.num_levels,
            radius=self.radius,
            opacity_function=self.opacity_function,
            max_opacity=self.max_opacity_ambient
        )
        if self.has_screen():
            self.spotlight = Spotlight(
                source_point=VectorizedPoint(location=self.get_source_point()),
                color=self.color,
                num_levels=self.num_levels,
                radius=self.radius,
                screen=self.screen,
                opacity_function=self.opacity_function,
                max_opacity=self.max_opacity_spotlight,
                camera_mob=self.camera_mob
            )
        else:
            self.spotlight = Spotlight()

        self.shadow = VMobject(fill_color=SHADOW_COLOR,
                               fill_opacity=1.0, stroke_color=BLACK)
        self.lighthouse.next_to(self.get_source_point(), DOWN, buff=0)
        self.ambient_light.move_source_to(self.get_source_point())

        if self.has_screen():
            self.spotlight.move_source_to(self.get_source_point())
            self.update_shadow()

        self.add(self.ambient_light, self.spotlight,
                 self.lighthouse, self.shadow)
示例#39
0
    def __init__(self, func, **kwargs):
        VGroup.__init__(self, **kwargs)
        self.func = func
        dt = self.dt

        start_points = self.get_start_points(
            **self.start_points_generator_config
        )
        for point in start_points:
            points = [point]
            for t in np.arange(0, self.virtual_time, dt):
                last_point = points[-1]
                points.append(last_point + dt * func(last_point))
                if get_norm(last_point) > self.cutoff_norm:
                    break
            line = VMobject()
            step = max(1, int(len(points) / self.n_anchors_per_line))
            line.set_points_smoothly(points[::step])
            self.add(line)

        self.set_stroke(self.stroke_color, self.stroke_width)

        if self.color_by_arc_length:
            len_to_rgb = get_rgb_gradient_function(
                self.min_arc_length,
                self.max_arc_length,
                colors=self.colors,
            )
            for line in self:
                arc_length = line.get_arc_length()
                rgb = len_to_rgb([arc_length])[0]
                color = rgb_to_color(rgb)
                line.set_color(color)
        elif self.color_by_magnitude:
            image_file = get_color_field_image_file(
                lambda p: get_norm(func(p)),
                min_value=self.min_magnitude,
                max_value=self.max_magnitude,
                colors=self.colors,
            )
            self.color_using_background_image(image_file)
示例#40
0
 def __init__(self, *vertices, **kwargs):
     VMobject.__init__(self, **kwargs)
     self.set_points_as_corners(
         [*vertices, vertices[0]]
     )
示例#41
0
 def __init__(self, body, **kwargs):
     VMobject.__init__(self, **kwargs)
     self.body = body
     eyes = self.create_eyes()
     self.become(eyes, copy_submobjects=False)
示例#42
0
 def get_center(self):
     result = VMobject.get_center(self)
     if hasattr(self, "center_offset"):
         result -= self.center_offset
     return result
示例#43
0
 def __init__(self, **kwargs):
     VMobject.__init__(self, **kwargs)
     self.add_iris_back()
     self.add_spikes()
     self.add_pupil()
示例#44
0
 def __init__(self, file_name=None, **kwargs):
     digest_config(self, kwargs)
     self.file_name = file_name or self.file_name
     self.ensure_valid_file()
     VMobject.__init__(self, **kwargs)
     self.move_into_position()
示例#45
0
文件: light.py 项目: coallaoh/manim
    def update_shadow(self):
        point = self.get_source_point()
        projected_screen_points = []
        if not self.has_screen():
            return
        for point in self.screen.get_anchors():
            projected_screen_points.append(self.spotlight.project(point))

        projected_source = project_along_vector(
            self.get_source_point(), self.spotlight.projection_direction())

        projected_point_cloud_3d = np.append(
            projected_screen_points,
            np.reshape(projected_source, (1, 3)),
            axis=0
        )
        # z_to_vector(self.spotlight.projection_direction())
        rotation_matrix = self.rotation_matrix()
        back_rotation_matrix = rotation_matrix.T  # i. e. its inverse

        rotated_point_cloud_3d = np.dot(
            projected_point_cloud_3d, back_rotation_matrix.T)
        # these points now should all have z = 0

        point_cloud_2d = rotated_point_cloud_3d[:, :2]
        # now we can compute the convex hull
        hull_2d = ConvexHull(point_cloud_2d)  # guaranteed to run ccw
        hull = []

        # we also need the projected source point
        source_point_2d = np.dot(self.spotlight.project(
            self.get_source_point()), back_rotation_matrix.T)[:2]

        index = 0
        for point in point_cloud_2d[hull_2d.vertices]:
            if np.all(np.abs(point - source_point_2d) < 1.0e-6):
                source_index = index
                index += 1
                continue
            point_3d = np.array([point[0], point[1], 0])
            hull.append(point_3d)
            index += 1

        hull_mobject = VMobject()
        hull_mobject.set_points_as_corners(hull)
        hull_mobject.apply_matrix(rotation_matrix)

        anchors = hull_mobject.get_anchors()

        # add two control points for the outer cone
        if np.size(anchors) == 0:
            self.shadow.points = []
            return

        ray1 = anchors[source_index - 1] - projected_source
        ray1 = ray1 / get_norm(ray1) * 100

        ray2 = anchors[source_index] - projected_source
        ray2 = ray2 / get_norm(ray2) * 100
        outpoint1 = anchors[source_index - 1] + ray1
        outpoint2 = anchors[source_index] + ray2

        new_anchors = anchors[:source_index]
        new_anchors = np.append(new_anchors, np.array(
            [outpoint1, outpoint2]), axis=0)
        new_anchors = np.append(new_anchors, anchors[source_index:], axis=0)
        self.shadow.set_points_as_corners(new_anchors)

        # shift it closer to the camera so it is in front of the spotlight
        self.shadow.mark_paths_closed = True
示例#46
0
 def __init__(self, start_angle=0, angle=TAU / 4, **kwargs):
     self.start_angle = start_angle
     self.angle = angle
     VMobject.__init__(self, **kwargs)
示例#47
0
 def get_start(self):
     if self.has_start_tip():
         return self.start_tip.get_start()
     else:
         return VMobject.get_start(self)
示例#48
0
文件: light.py 项目: coallaoh/manim
class LightSource(VMobject):
    # combines:
    # a lighthouse
    # an ambient light
    # a spotlight
    # and a shadow
    CONFIG = {
        "source_point": VectorizedPoint(location=ORIGIN, stroke_width=0, fill_opacity=0),
        "color": LIGHT_COLOR,
        "num_levels": 10,
        "radius": 10.0,
        "screen": None,
        "opacity_function": inverse_quadratic(1, 2, 1),
        "max_opacity_ambient": AMBIENT_FULL,
        "max_opacity_spotlight": SPOTLIGHT_FULL,
        "camera_mob": None
    }

    def generate_points(self):

        self.add(self.source_point)

        self.lighthouse = Lighthouse()
        self.ambient_light = AmbientLight(
            source_point=VectorizedPoint(location=self.get_source_point()),
            color=self.color,
            num_levels=self.num_levels,
            radius=self.radius,
            opacity_function=self.opacity_function,
            max_opacity=self.max_opacity_ambient
        )
        if self.has_screen():
            self.spotlight = Spotlight(
                source_point=VectorizedPoint(location=self.get_source_point()),
                color=self.color,
                num_levels=self.num_levels,
                radius=self.radius,
                screen=self.screen,
                opacity_function=self.opacity_function,
                max_opacity=self.max_opacity_spotlight,
                camera_mob=self.camera_mob
            )
        else:
            self.spotlight = Spotlight()

        self.shadow = VMobject(fill_color=SHADOW_COLOR,
                               fill_opacity=1.0, stroke_color=BLACK)
        self.lighthouse.next_to(self.get_source_point(), DOWN, buff=0)
        self.ambient_light.move_source_to(self.get_source_point())

        if self.has_screen():
            self.spotlight.move_source_to(self.get_source_point())
            self.update_shadow()

        self.add(self.ambient_light, self.spotlight,
                 self.lighthouse, self.shadow)

    def has_screen(self):
        if self.screen is None:
            return False
        elif np.size(self.screen.points) == 0:
            return False
        else:
            return True

    def dim_ambient(self):
        self.set_max_opacity_ambient(AMBIENT_DIMMED)

    def set_max_opacity_ambient(self, new_opacity):
        self.max_opacity_ambient = new_opacity
        self.ambient_light.dimming(new_opacity)

    def dim_spotlight(self):
        self.set_max_opacity_spotlight(SPOTLIGHT_DIMMED)

    def set_max_opacity_spotlight(self, new_opacity):
        self.max_opacity_spotlight = new_opacity
        self.spotlight.dimming(new_opacity)

    def set_camera_mob(self, new_cam_mob):
        self.camera_mob = new_cam_mob
        self.spotlight.camera_mob = new_cam_mob

    def set_screen(self, new_screen):
        if self.has_screen():
            self.spotlight.screen = new_screen
        else:
            # Note: See below
            index = self.submobjects.index(self.spotlight)
            # camera_mob = self.spotlight.camera_mob
            self.remove(self.spotlight)
            self.spotlight = Spotlight(
                source_point=VectorizedPoint(location=self.get_source_point()),
                color=self.color,
                num_levels=self.num_levels,
                radius=self.radius,
                screen=new_screen,
                camera_mob=self.camera_mob,
                opacity_function=self.opacity_function,
                max_opacity=self.max_opacity_spotlight,
            )
            self.spotlight.move_source_to(self.get_source_point())

            # Note: This line will make spotlight show up at the end
            # of the submojects list, which can make it show up on
            # top of the shadow. To make it show up in the
            # same spot, you could try the following line,
            # where "index" is what I defined above:
            self.submobjects.insert(index, self.spotlight)
            # self.add(self.spotlight)

        # in any case
        self.screen = new_screen

    def move_source_to(self, point):
        apoint = np.array(point)
        v = apoint - self.get_source_point()
        # Note: As discussed, things stand to behave better if source
        # point is a submobject, so that it automatically interpolates
        # during an animation, and other updates can be defined wrt
        # that source point's location
        self.source_point.set_location(apoint)
        # self.lighthouse.next_to(apoint,DOWN,buff = 0)
        # self.ambient_light.move_source_to(apoint)
        self.lighthouse.shift(v)
        # self.ambient_light.shift(v)
        self.ambient_light.move_source_to(apoint)
        if self.has_screen():
            self.spotlight.move_source_to(apoint)
        self.update()
        return self

    def change_spotlight_opacity_function(self, new_of):
        self.spotlight.change_opacity_function(new_of)

    def set_radius(self, new_radius):
        self.radius = new_radius
        self.ambient_light.radius = new_radius
        self.spotlight.radius = new_radius

    def update(self):
        self.update_lighthouse()
        self.update_ambient()
        self.spotlight.update_sectors()
        self.update_shadow()

    def update_lighthouse(self):
        self.lighthouse.move_to(self.get_source_point())
        # new_lh = Lighthouse()
        # new_lh.move_to(ORIGIN)
        # new_lh.apply_matrix(self.rotation_matrix())
        # new_lh.shift(self.get_source_point())
        # self.lighthouse.submobjects = new_lh.submobjects

    def update_ambient(self):
        new_ambient_light = AmbientLight(
            source_point=VectorizedPoint(location=ORIGIN),
            color=self.color,
            num_levels=self.num_levels,
            radius=self.radius,
            opacity_function=self.opacity_function,
            max_opacity=self.max_opacity_ambient
        )
        new_ambient_light.apply_matrix(self.rotation_matrix())
        new_ambient_light.move_source_to(self.get_source_point())
        self.ambient_light.submobjects = new_ambient_light.submobjects

    def get_source_point(self):
        return self.source_point.get_location()

    def rotation_matrix(self):

        if self.camera_mob is None:
            return np.eye(3)

        phi = self.camera_mob.get_center()[0]
        theta = self.camera_mob.get_center()[1]

        R1 = np.array([
            [1, 0, 0],
            [0, np.cos(phi), -np.sin(phi)],
            [0, np.sin(phi), np.cos(phi)]
        ])

        R2 = np.array([
            [np.cos(theta + TAU / 4), -np.sin(theta + TAU / 4), 0],
            [np.sin(theta + TAU / 4), np.cos(theta + TAU / 4), 0],
            [0, 0, 1]
        ])

        R = np.dot(R2, R1)
        return R

    def update_shadow(self):
        point = self.get_source_point()
        projected_screen_points = []
        if not self.has_screen():
            return
        for point in self.screen.get_anchors():
            projected_screen_points.append(self.spotlight.project(point))

        projected_source = project_along_vector(
            self.get_source_point(), self.spotlight.projection_direction())

        projected_point_cloud_3d = np.append(
            projected_screen_points,
            np.reshape(projected_source, (1, 3)),
            axis=0
        )
        # z_to_vector(self.spotlight.projection_direction())
        rotation_matrix = self.rotation_matrix()
        back_rotation_matrix = rotation_matrix.T  # i. e. its inverse

        rotated_point_cloud_3d = np.dot(
            projected_point_cloud_3d, back_rotation_matrix.T)
        # these points now should all have z = 0

        point_cloud_2d = rotated_point_cloud_3d[:, :2]
        # now we can compute the convex hull
        hull_2d = ConvexHull(point_cloud_2d)  # guaranteed to run ccw
        hull = []

        # we also need the projected source point
        source_point_2d = np.dot(self.spotlight.project(
            self.get_source_point()), back_rotation_matrix.T)[:2]

        index = 0
        for point in point_cloud_2d[hull_2d.vertices]:
            if np.all(np.abs(point - source_point_2d) < 1.0e-6):
                source_index = index
                index += 1
                continue
            point_3d = np.array([point[0], point[1], 0])
            hull.append(point_3d)
            index += 1

        hull_mobject = VMobject()
        hull_mobject.set_points_as_corners(hull)
        hull_mobject.apply_matrix(rotation_matrix)

        anchors = hull_mobject.get_anchors()

        # add two control points for the outer cone
        if np.size(anchors) == 0:
            self.shadow.points = []
            return

        ray1 = anchors[source_index - 1] - projected_source
        ray1 = ray1 / get_norm(ray1) * 100

        ray2 = anchors[source_index] - projected_source
        ray2 = ray2 / get_norm(ray2) * 100
        outpoint1 = anchors[source_index - 1] + ray1
        outpoint2 = anchors[source_index] + ray2

        new_anchors = anchors[:source_index]
        new_anchors = np.append(new_anchors, np.array(
            [outpoint1, outpoint2]), axis=0)
        new_anchors = np.append(new_anchors, anchors[source_index:], axis=0)
        self.shadow.set_points_as_corners(new_anchors)

        # shift it closer to the camera so it is in front of the spotlight
        self.shadow.mark_paths_closed = True
示例#49
0
 def __init__(self, start=LEFT, end=RIGHT, **kwargs):
     digest_config(self, kwargs)
     self.set_start_and_end_attrs(start, end)
     VMobject.__init__(self, **kwargs)
示例#50
0
 def __init__(self, path_string, **kwargs):
     digest_locals(self)
     VMobject.__init__(self, **kwargs)
示例#51
0
 def init_colors(self):
     VMobject.init_colors(self)
     self.set_color_by_gradient(*self.colors)
示例#52
0
 def __init__(self, **kwargs):
     VMobject.__init__(self, **kwargs)
     self.set_points_as_corners([UP, UP + RIGHT, RIGHT])
     self.set_width(self.width, about_point=ORIGIN)
     self.rotate(self.angle, about_point=ORIGIN)
示例#53
0
 def __init__(self, points, **kwargs):
     VMobject.__init__(self, **kwargs)
     self.set_points(points)
示例#54
0
 def init_colors(self):
     VMobject.init_colors(self)
     self.set_color_by_gradient(*self.colors)
     for order in sorted(self.order_to_stroke_width_map.keys()):
         if self.order >= order:
             self.set_stroke(width=self.order_to_stroke_width_map[order])