Ejemplo n.º 1
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=SMALL_BUFF)
        else:
            angle = vector.get_angle()
            if not rotate:
                label.rotate(-angle, about_point=ORIGIN)
            if direction == "left":
                label.shift(-label.get_bottom() + 0.1 * UP)
            else:
                label.shift(-label.get_top() + 0.1 * DOWN)
            label.rotate(angle, about_point=ORIGIN)
            label.shift((vector.get_end() - vector.get_start()) / 2)
        return label
Ejemplo n.º 2
0
 def get_arc_length(self):
     if self.path_arc:
         anchors = self.get_anchors()
         return sum(
             [get_norm(a2 - a1) for a1, a2 in zip(anchors, anchors[1:])])
     else:
         return self.get_length()
Ejemplo n.º 3
0
 def get_vector_movement(self, func):
     for v in self.moving_vectors:
         v.target = Vector(func(v.get_end()), color=v.get_color())
         norm = get_norm(v.target.get_end())
         if norm < 0.1:
             v.target.get_tip().scale_in_place(norm)
     return self.get_piece_movement(self.moving_vectors)
Ejemplo n.º 4
0
 def get_unit_vector(self):
     vect = self.get_vector()
     norm = get_norm(vect)
     if norm == 0:
         # TODO, is this the behavior I want?
         return np.array(ORIGIN)
     return vect / norm
    def __init__(self, start_point, end_point, angle=TAU / 4, **kwargs):
        if angle == 0:
            raise Exception("Arc with zero curve angle: use Line instead.")

        midpoint = 0.5 * (start_point + end_point)
        distance_vector = end_point - start_point
        normal_vector = np.array([-distance_vector[1], distance_vector[0], 0])
        distance = get_norm(normal_vector)
        normal_vector /= distance
        if angle < 0:
            normal_vector *= -1

        radius = distance / 2 / np.sin(0.5 * np.abs(angle))
        length = distance / 2 / np.tan(0.5 * np.abs(angle))
        arc_center = midpoint + length * normal_vector
        w = start_point - arc_center
        if w[0] != 0:
            start_angle = np.arctan2(w[1], w[0])
        else:
            start_angle = np.pi / 2

        Arc.__init__(self,
                     angle,
                     radius=radius,
                     start_angle=start_angle,
                     **kwargs)

        self.move_arc_center_to(arc_center)
Ejemplo n.º 6
0
    def init_style(self):
        if self.color_by_magnitude:
            values_to_rgbs = get_vectorized_rgb_gradient_function(
                *self.magnitude_range,
                self.color_map,
            )
            cs = self.coordinate_system
            for line in self.submobjects:
                norms = [
                    get_norm(self.func(*cs.p2c(point)))
                    for point in line.get_points()
                ]
                rgbs = values_to_rgbs(norms)
                rgbas = np.zeros((len(rgbs), 4))
                rgbas[:, :3] = rgbs
                rgbas[:, 3] = self.stroke_opacity
                line.set_rgba_array(rgbas, "stroke_rgba")
        else:
            self.set_stroke(self.stroke_color, opacity=self.stroke_opacity)

        if self.taper_stroke_width:
            width = [0, self.stroke_width, 0]
        else:
            width = self.stroke_width
        self.set_stroke(width=width)
Ejemplo n.º 7
0
    def init_points(self):
        t_min, t_max = self.t_min, self.t_max
        dt = self.dt

        discontinuities = filter(lambda t: t_min <= t <= t_max,
                                 self.discontinuities)
        discontinuities = np.array(list(discontinuities))
        boundary_times = [
            self.t_min,
            self.t_max,
            *(discontinuities - dt),
            *(discontinuities + dt),
        ]
        boundary_times.sort()
        for t1, t2 in zip(boundary_times[0::2], boundary_times[1::2]):
            # Get an initial sample of points
            t_range = list(np.linspace(t1, t2, self.min_samples + 1))
            samples = [self.function(t) for t in t_range]

            # Take more samples based on the distances between them
            norms = [get_norm(p2 - p1) for p1, p2 in zip(samples, samples[1:])]
            full_t_range = [t1]
            for s1, s2, norm in zip(t_range, t_range[1:], norms):
                n_inserts = int(norm / self.step_size)
                full_t_range += list(np.linspace(s1, s2, n_inserts + 1)[1:])

            points = np.array([self.function(t) for t in full_t_range])
            valid_indices = np.isfinite(points).all(1)
            points = points[valid_indices]
            if len(points) > 0:
                self.start_new_path(points[0])
                self.add_points_as_corners(points[1:])
        self.make_smooth()
        return self
    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, Tex):
            if len(label) == 1:
                label = "\\vec{\\textbf{%s}}" % label
            label = Tex(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=SMALL_BUFF)
        else:
            angle = vector.get_angle()
            if not rotate:
                label.rotate(-angle, about_point=ORIGIN)
            if direction == "left":
                label.shift(-label.get_bottom() + 0.1 * UP)
            else:
                label.shift(-label.get_top() + 0.1 * DOWN)
            label.rotate(angle, about_point=ORIGIN)
            label.shift((vector.get_end() - vector.get_start()) / 2)
        return label
Ejemplo n.º 9
0
    def set_points_by_ends(self,
                           start: np.ndarray,
                           end: np.ndarray,
                           buff: float = 0,
                           path_arc: float = 0):
        vect = end - start
        dist = get_norm(vect)
        if np.isclose(dist, 0):
            self.set_points_as_corners([start, end])
            return self
        if path_arc:
            neg = path_arc < 0
            if neg:
                path_arc = -path_arc
                start, end = end, start
            radius = (dist / 2) / math.sin(path_arc / 2)
            alpha = (PI - path_arc) / 2
            center = start + radius * normalize(
                rotate_vector(end - start, alpha))

            raw_arc_points = Arc.create_quadratic_bezier_points(
                angle=path_arc - 2 * buff / radius,
                start_angle=angle_of_vector(start - center) + buff / radius,
            )
            if neg:
                raw_arc_points = raw_arc_points[::-1]
            self.set_points(center + radius * raw_arc_points)
        else:
            if buff > 0 and dist > 0:
                start = start + vect * (buff / dist)
                end = end - vect * (buff / dist)
            self.set_points_as_corners([start, end])
        return self
 def get_vector_movement(self, func):
     for v in self.moving_vectors:
         v.target = Vector(func(v.get_end()), color=v.get_color())
         norm = get_norm(v.target.get_end())
         if norm < 0.1:
             v.target.get_tip().scale(norm)
     return self.get_piece_movement(self.moving_vectors)
Ejemplo n.º 11
0
 def set_rectangular_stem_points(self):
     start, end = self.get_start_and_end()
     tip_base_points = self.tip[0].get_anchors()[1:3]
     tip_base = center_of_mass(tip_base_points)
     tbp1, tbp2 = tip_base_points
     perp_vect = tbp2 - tbp1
     tip_base_width = get_norm(perp_vect)
     if tip_base_width > 0:
         perp_vect /= tip_base_width
     width = min(
         self.rectangular_stem_width,
         self.max_stem_width_to_tip_width_ratio * tip_base_width,
     )
     if hasattr(self, "second_tip"):
         start = center_of_mass(
             self.second_tip.get_anchors()[1:]
         )
     self.rect.set_points_as_corners([
         tip_base - perp_vect * width / 2,
         start - perp_vect * width / 2,
         start + perp_vect * width / 2,
         tip_base + perp_vect * width / 2,
     ])
     self.stem = self.rect  # Alternate name
     return self
Ejemplo n.º 12
0
 def __init__(self, start: np.ndarray, end: np.ndarray, **kwargs):
     digest_config(self, kwargs)
     axis = end - start
     super().__init__(height=get_norm(axis),
                      radius=self.width / 2,
                      axis=axis)
     self.shift((start + end) / 2)
Ejemplo n.º 13
0
 def get_arc_center(self):
     first_point = self.points[0]
     last_point = self.points[-2]
     v = last_point - first_point
     radial_unit_vector = v / get_norm(v)
     arc_center = first_point - self.inner_radius * radial_unit_vector
     return arc_center
Ejemplo n.º 14
0
    def insert_n_curves_to_point_list(self, n, points):
        nppc = self.n_points_per_curve
        if len(points) == 1:
            return np.repeat(points, nppc * n, 0)

        bezier_groups = self.get_bezier_tuples_from_points(points)
        norms = np.array([
            get_norm(bg[nppc - 1] - bg[0])
            for bg in bezier_groups
        ])
        total_norm = sum(norms)
        # Calculate insertions per curve (ipc)
        if total_norm < 1e-6:
            ipc = [n] + [0] * (len(bezier_groups) - 1)
        else:
            ipc = np.round(n * norms / sum(norms)).astype(int)

        diff = n - sum(ipc)
        for x in range(diff):
            ipc[np.argmin(ipc)] += 1
        for x in range(-diff):
            ipc[np.argmax(ipc)] -= 1

        new_points = []
        for group, n_inserts in zip(bezier_groups, ipc):
            # What was once a single quadratic curve defined
            # by "group" will now be broken into n_inserts + 1
            # smaller quadratic curves
            alphas = np.linspace(0, 1, n_inserts + 2)
            for a1, a2 in zip(alphas, alphas[1:]):
                new_points += partial_quadratic_bezier_points(group, a1, a2)
        return np.vstack(new_points)
Ejemplo n.º 15
0
 def put_start_and_end_on(self, start, end):
     curr_start, curr_end = self.get_start_and_end()
     curr_vect = curr_end - curr_start
     if np.all(curr_vect == 0):
         raise Exception("Cannot position endpoints of closed loop")
     target_vect = end - start
     self.scale(
         get_norm(target_vect) / get_norm(curr_vect),
         about_point=curr_start,
     )
     self.rotate(
         angle_of_vector(target_vect) -
         angle_of_vector(curr_vect),
         about_point=curr_start
     )
     self.shift(start - curr_start)
     return self
Ejemplo n.º 16
0
 def look(self, direction):
     norm = get_norm(direction)
     if norm == 0:
         return
     direction /= norm
     self.purposeful_looking_direction = direction
     for pupil, eye in zip(self.pupils.split(), self.eyes.split()):
         c = eye.get_center()
         right = eye.get_right() - c
         up = eye.get_top() - c
         vect = direction[0] * right + direction[1] * up
         v_norm = get_norm(vect)
         p_radius = 0.5 * pupil.get_width()
         vect *= (v_norm - 0.75 * p_radius) / v_norm
         pupil.move_to(c + vect)
     self.pupils[1].align_to(self.pupils[0], DOWN)
     return self
Ejemplo n.º 17
0
 def handle_resizing(self, point: np.ndarray):
     if not hasattr(self, "scale_about_point"):
         return
     vect = point - self.scale_about_point
     if self.window.is_key_pressed(CTRL_SYMBOL):
         for i in (0, 1):
             scalar = vect[i] / self.scale_ref_vect[i]
             self.selection.rescale_to_fit(
                 scalar * [self.scale_ref_width, self.scale_ref_height][i],
                 dim=i,
                 about_point=self.scale_about_point,
                 stretch=True,
             )
     else:
         scalar = get_norm(vect) / get_norm(self.scale_ref_vect)
         self.selection.set_width(scalar * self.scale_ref_width,
                                  about_point=self.scale_about_point)
Ejemplo n.º 18
0
 def put_start_and_end_on(self, start, end):
     curr_start, curr_end = self.get_start_and_end()
     curr_vect = curr_end - curr_start
     if np.all(curr_vect == 0):
         raise Exception("Cannot position endpoints of closed loop")
     target_vect = end - start
     self.scale(
         get_norm(target_vect) / get_norm(curr_vect),
         about_point=curr_start,
     )
     self.rotate(
         angle_of_vector(target_vect) -
         angle_of_vector(curr_vect),
         about_point=curr_start
     )
     self.shift(start - curr_start)
     return self
Ejemplo n.º 19
0
 def look(self, direction):
     norm = get_norm(direction)
     if norm == 0:
         return
     direction /= norm
     self.purposeful_looking_direction = direction
     for pupil, eye in zip(self.pupils.split(), self.eyes.split()):
         c = eye.get_center()
         right = eye.get_right() - c
         up = eye.get_top() - c
         vect = direction[0] * right + direction[1] * up
         v_norm = get_norm(vect)
         p_radius = 0.5 * pupil.get_width()
         vect *= (v_norm - 0.75 * p_radius) / v_norm
         pupil.move_to(c + vect)
     self.pupils[1].align_to(self.pupils[0], DOWN)
     return self
Ejemplo n.º 20
0
 def get_normal_vector(self):
     p0, p1, p2 = self.tip[0].get_anchors()[:3]
     result = np.cross(p2 - p1, p1 - p0)
     norm = get_norm(result)
     if norm == 0:
         return self.normal_vector
     else:
         return result / norm
Ejemplo n.º 21
0
    def __init__(self, func, **kwargs):
        if not hasattr(self, "args"):
            self.args = serialize_args([func])
        if not hasattr(self, "config"):
            self.config = serialize_config({
                **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)
Ejemplo n.º 22
0
 def get_arc_length(self, n_sample_points=None):
     if n_sample_points is None:
         n_sample_points = 4 * self.get_num_curves() + 1
     points = np.array(
         [self.point_from_proportion(a) for a in np.linspace(0, 1, n_sample_points)]
     )
     diffs = points[1:] - points[:-1]
     norms = np.array([get_norm(d) for d in diffs])
     return norms.sum()
Ejemplo n.º 23
0
 def add_tip(self):
     start, end = self.main_line.get_start_and_end()
     vect = (end - start) / get_norm(end - start)
     arrow = Arrow(start, end + MED_SMALL_BUFF * vect, buff=0)
     tip = arrow.tip
     tip.set_stroke(width=self.get_stroke_width())
     tip.set_color(self.color)
     self.tip = tip
     self.add(tip)
Ejemplo n.º 24
0
    def get_vector_label(self,
                         vector,
                         label,
                         at_tip=False,
                         direction="left",
                         rotate=False,
                         color=None,
                         label_scale_factor=VECTOR_LABEL_SCALE_FACTOR):
        """
        Returns naming labels for the passed vector.

        Parameters
        ----------
        vector
            Vector Object for which to get the label.
        at_tip (bool)
            Whether or not to place the label at the tip of the vector.
        direction (str="left")
            If the label should be on the "left" or right of the vector.
        rotate (bool=False)
            Whether or not to rotate it to align it with the vector.
        color (str)
            The color to give the label.
        label_scale_factor (Union[int,float])
            How much to scale the label by.
        
        Returns
        -------
        TexMobject
            The TexMobject of the label.
        """
        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=SMALL_BUFF)
        else:
            angle = vector.get_angle()
            if not rotate:
                label.rotate(-angle, about_point=ORIGIN)
            if direction == "left":
                label.shift(-label.get_bottom() + 0.1 * UP)
            else:
                label.shift(-label.get_top() + 0.1 * DOWN)
            label.rotate(angle, about_point=ORIGIN)
            label.shift((vector.get_end() - vector.get_start()) / 2)
        return label
Ejemplo n.º 25
0
def path_along_arc(arc_angle, axis=OUT):
    """
    If vect is vector from start to end, [vect[:,1], -vect[:,0]] is
    perpendicular to vect in the left direction.
    """
    if abs(arc_angle) < STRAIGHT_PATH_THRESHOLD:
        return straight_path
    if get_norm(axis) == 0:
        axis = OUT
    unit_axis = axis / get_norm(axis)

    def path(start_points, end_points, alpha):
        vects = end_points - start_points
        centers = start_points + 0.5 * vects
        if arc_angle != np.pi:
            centers += np.cross(unit_axis, vects / 2.0) / np.tan(arc_angle / 2)
        rot_matrix = rotation_matrix(alpha * arc_angle, unit_axis)
        return centers + np.dot(start_points - centers, rot_matrix.T)
    return path
    def get_length(self):
        """
        Get length

        Returns
        -------
            Lenght of the line : float
        """
        start, end = self.get_start_and_end()
        return get_norm(start - end)
Ejemplo n.º 27
0
 def __init__(self, car, target_point, **kwargs):
     assert isinstance(car, Car)
     ApplyMethod.__init__(self, car.move_to, target_point, **kwargs)
     displacement = self.target_mobject.get_right(
     ) - self.starting_mobject.get_right()
     distance = get_norm(displacement)
     if not self.moving_forward:
         distance *= -1
     tire_radius = car.get_tires()[0].get_width() / 2
     self.total_tire_radians = -distance / tire_radius
Ejemplo n.º 28
0
 def on_mouse_motion(self, point: np.ndarray, d_point: np.ndarray) -> None:
     super().on_mouse_motion(point, d_point)
     # Move selection
     if self.window.is_key_pressed(ord("g")):
         self.selection.move_to(point - self.mouse_to_selection)
     # Move selection restricted to horizontal
     elif self.window.is_key_pressed(ord("h")):
         self.selection.set_x((point - self.mouse_to_selection)[0])
     # Move selection restricted to vertical
     elif self.window.is_key_pressed(ord("v")):
         self.selection.set_y((point - self.mouse_to_selection)[1])
     # Scale selection
     elif self.window.is_key_pressed(ord("t")):
         # TODO, allow for scaling about the opposite corner
         vect = point - self.scale_about_point
         scalar = get_norm(vect) / get_norm(self.scale_ref_vect)
         self.selection.set_width(
             scalar * self.scale_ref_width,
             about_point=self.scale_about_point
         )
Ejemplo n.º 29
0
 def begin(self):
     super().begin()
     car = self.mobject
     distance = get_norm(op.sub(
         self.target_mobject.get_right(),
         self.starting_mobject.get_right(),
     ))
     if not self.moving_forward:
         distance *= -1
     tire_radius = car.get_tires()[0].get_width() / 2
     self.total_tire_radians = -distance / tire_radius
Ejemplo n.º 30
0
 def put_start_and_end_on(self, start, end):
     curr_start, curr_end = self.get_start_and_end()
     if np.all(curr_start == curr_end):
         # TODO, any problems with resetting
         # these attrs?
         self.start = start
         self.end = end
         self.generate_points()
     curr_vect = curr_end - curr_start
     if np.all(curr_vect == 0):
         raise Exception("Cannot position endpoints of closed loop")
     target_vect = end - start
     self.scale(
         get_norm(target_vect) / get_norm(curr_vect),
         about_point=curr_start,
     )
     self.rotate(angle_of_vector(target_vect) - angle_of_vector(curr_vect),
                 about_point=curr_start)
     self.shift(start - curr_start)
     return self
Ejemplo n.º 31
0
    def set_submobject_colors_by_radial_gradient(self, center=None, radius=1, inner_color=WHITE, outer_color=BLACK):
        if center is None:
            center = self.get_center()

        for mob in self.family_members_with_points():
            t = get_norm(mob.get_center() - center) / radius
            t = min(t, 1)
            mob_color = interpolate_color(inner_color, outer_color, t)
            mob.set_color(mob_color, family=False)

        return self
Ejemplo n.º 32
0
 def draw_lines(self):
     lines = []
     for point in self.get_start_points():
         points = [point]
         total_arc_len = 0
         # for t in np.arange(0, self.virtual_time, self.dt):
         for x in range(self.max_time_steps):
             last_point = points[-1]
             new_point = last_point + self.dt * self.point_func(last_point)
             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()
         step = max(1, int(len(points) / self.n_samples_per_line))
         line.set_points_smoothly(points[::step])
         lines.append(line)
     self.set_submobjects(lines)
Ejemplo n.º 33
0
 def begin(self):
     super().begin()
     car = self.mobject
     distance = get_norm(op.sub(
         self.target_mobject.get_right(),
         self.starting_mobject.get_right(),
     ))
     if not self.moving_forward:
         distance *= -1
     tire_radius = car.get_tires()[0].get_width() / 2
     self.total_tire_radians = -distance / tire_radius
Ejemplo n.º 34
0
 def interpolate_mobject(self, alpha):
     alpha_left = self.rec_rate(alpha)
     alpha_right = 1 - self.rec_rate(1 - alpha)
     self.left = interpolate(self.mob_left, self.mob_right, alpha_left)
     self.right = interpolate(self.mob_left, self.mob_right, alpha_right)
     self.mobject.become(
         Rectangle(
             width=get_norm(self.right - self.left),
             height=self.height,
             **self.rectangle_config,
         ).move_to((self.left + self.right) / 2))
Ejemplo n.º 35
0
def path_along_arc(arc_angle, axis=OUT):
    """
    If vect is vector from start to end, [vect[:,1], -vect[:,0]] is
    perpendicular to vect in the left direction.
    """
    if abs(arc_angle) < STRAIGHT_PATH_THRESHOLD:
        return straight_path
    if get_norm(axis) == 0:
        axis = OUT
    unit_axis = axis / get_norm(axis)

    def path(start_points, end_points, alpha):
        vects = end_points - start_points
        centers = start_points + 0.5 * vects
        if arc_angle != np.pi:
            centers += np.cross(unit_axis, vects / 2.0) / np.tan(arc_angle / 2)
        rot_matrix = rotation_matrix(alpha * arc_angle, unit_axis)
        return centers + np.dot(start_points - centers, rot_matrix.T)

    return path
Ejemplo n.º 36
0
    def set_submobject_colors_by_radial_gradient(self, center=None, radius=1, inner_color=WHITE, outer_color=BLACK):
        if center is None:
            center = self.get_center()

        for mob in self.family_members_with_points():
            t = get_norm(mob.get_center() - center) / radius
            t = min(t, 1)
            mob_color = interpolate_color(inner_color, outer_color, t)
            mob.set_color(mob_color, family=False)

        return self
Ejemplo n.º 37
0
 def add_line(self, start, end, color=None):
     start, end = list(map(np.array, [start, end]))
     length = get_norm(end - start)
     if length == 0:
         points = [start]
     else:
         epsilon = self.epsilon / length
         points = [
             interpolate(start, end, t) for t in np.arange(0, 1, epsilon)
         ]
     self.add_points(points, color=color)
Ejemplo n.º 38
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)
Ejemplo n.º 39
0
 def add_line(self, start, end, color=None):
     start, end = list(map(np.array, [start, end]))
     length = get_norm(end - start)
     if length == 0:
         points = [start]
     else:
         epsilon = self.epsilon / length
         points = [
             interpolate(start, end, t)
             for t in np.arange(0, 1, epsilon)
         ]
     self.add_points(points, color=color)
Ejemplo n.º 40
0
def get_3d_vmob_unit_normal(vmob, point_index):
    n_points = vmob.get_num_points()
    if len(vmob.get_anchors()) <= 2:
        return np.array(UP)
    i = point_index
    im3 = i - 3 if i > 2 else (n_points - 4)
    ip3 = i + 3 if i < (n_points - 3) else 3
    unit_normal = get_unit_normal(
        vmob.points[ip3] - vmob.points[i],
        vmob.points[im3] - vmob.points[i],
    )
    if get_norm(unit_normal) == 0:
        return np.array(UP)
    return unit_normal
Ejemplo n.º 41
0
 def get_vector(self, point, **kwargs):
     output = np.array(self.func(point))
     norm = get_norm(output)
     if norm == 0:
         output *= 0
     else:
         output *= self.length_func(norm) / norm
     vector_config = dict(self.vector_config)
     vector_config.update(kwargs)
     vect = Vector(output, **vector_config)
     vect.shift(point)
     fill_color = rgb_to_color(
         self.rgb_gradient_function(np.array([norm]))[0]
     )
     vect.set_color(fill_color)
     return vect
Ejemplo n.º 42
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)
Ejemplo n.º 43
0
 def func(point):
     centered = point + vect
     return radius * centered / get_norm(centered)
Ejemplo n.º 44
0
 def get_length(self):
     return get_norm(self.get_vector())
Ejemplo n.º 45
0
 def get_length(self):
     start, end = self.get_start_and_end()
     return get_norm(start - end)
Ejemplo n.º 46
0
 def get_direction(self):
     vect = self.get_tip() - self.get_center()
     return vect / get_norm(vect)