def update_group(group, alpha): area, left_v_line, left_T_label, right_v_line, right_T_label = group t_min = interpolate(curr_t_min, new_t_min, alpha) t_max = interpolate(curr_t_max, new_t_max, alpha) new_area = self.get_area(graph, t_min, t_max) new_left_v_line = self.get_vertical_line_to_graph(t_min, graph) new_left_v_line.set_color(left_v_line.get_color()) left_T_label.move_to(new_left_v_line.get_bottom(), UP) new_right_v_line = self.get_vertical_line_to_graph(t_max, graph) new_right_v_line.set_color(right_v_line.get_color()) right_T_label.move_to(new_right_v_line.get_bottom(), UP) # Fade close to 0 if fade_close_to_origin: if len(left_T_label) > 0: left_T_label[0].set_fill(opacity=min(1, np.abs(t_min))) if len(right_T_label) > 0: right_T_label[0].set_fill(opacity=min(1, np.abs(t_max))) Transform(area, new_area).update(1) Transform(left_v_line, new_left_v_line).update(1) Transform(right_v_line, new_right_v_line).update(1) return group
def update_func(group, alpha): dx = interpolate(start_dx, target_dx, alpha) x = interpolate(start_x, target_x, alpha) kwargs = dict(secant_slope_group.kwargs) kwargs["dx"] = dx kwargs["x"] = x new_group = self.get_secant_slope_group(**kwargs) Transform(group, new_group).update(1) return group
def update_submobject(self, submobject, starting_sumobject, alpha): submobject.points[:, :] = starting_sumobject.points submobject.scale(interpolate(1, self.scale_value, there_and_back(alpha)), about_point=self.scale_about_point) submobject.rotate(wiggle(alpha, self.n_wiggles) * self.rotation_angle, about_point=self.rotate_about_point)
def fade_to_no_recurse(self, color, alpha): if self.get_num_points() > 0: start = color_to_rgb(self.get_color()) end = color_to_rgb(color) new_rgb = interpolate(start, end, alpha) self.set_color(Color(rgb=new_rgb), family=False) return self
def straight_path(start_points, end_points, alpha): """ Same function as interpolate, but renamed to reflect intent of being used to determine how a set of points move to another set. For instance, it should be a specific case of path_along_arc """ return interpolate(start_points, end_points, alpha)
def set_points_as_corners(self, points): if len(points) <= 1: return self points = np.array(points) self.set_anchors_and_handles( points, *[ interpolate(points[:-1], points[1:], alpha) for alpha in (1. / 3, 2. / 3) ]) return self
def set_colors_by_radial_gradient(self, center=None, radius=1, inner_color=WHITE, outer_color=BLACK): start_rgba, end_rgba = list(map(color_to_rgba, [start_color, end_color])) if center is None: center = self.get_center() for mob in self.family_members_with_points(): num_points = mob.get_num_points() t = min(1, np.abs(mob.get_center() - center) / radius) mob.rgbas = np.array( [interpolate(start_rgba, end_rgba, t)] * num_points ) return self
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)
def color_gradient(reference_colors, length_of_output): if length_of_output == 0: return reference_colors[0] rgbs = list(map(color_to_rgb, reference_colors)) alphas = np.linspace(0, (len(rgbs) - 1), length_of_output) floors = alphas.astype('int') alphas_mod1 = alphas % 1 # End edge case alphas_mod1[-1] = 1 floors[-1] = len(rgbs) - 2 return [ rgb_to_color(interpolate(rgbs[i], rgbs[i + 1], alpha)) for i, alpha in zip(floors, alphas_mod1) ]
def set_color_by_gradient(self, *colors): self.rgbas = np.array(list(map( color_to_rgba, color_gradient(colors, len(self.points)) ))) return self start_rgba, end_rgba = list(map(color_to_rgba, [start_color, end_color])) for mob in self.family_members_with_points(): num_points = mob.get_num_points() mob.rgbas = np.array([ interpolate(start_rgba, end_rgba, alpha) for alpha in np.arange(num_points) / float(num_points) ]) return self
def interpolate_color(self, mobject1, mobject2, alpha): attrs = [ "fill_rgbas", "stroke_rgbas", "background_stroke_rgbas", "stroke_width", "background_stroke_width", "sheen_direction", "sheen", ] for attr in attrs: setattr( self, attr, interpolate(getattr(mobject1, attr), getattr(mobject2, attr), alpha)) if alpha == 1.0: setattr(self, attr, getattr(mobject2, attr))
def get_number_design(self, value, symbol): num = int(value) n_rows = { 2: 2, 3: 3, 4: 2, 5: 2, 6: 3, 7: 3, 8: 3, 9: 4, 10: 4, }[num] n_cols = 1 if num in [2, 3] else 2 insertion_indices = { 5: [0], 7: [0], 8: [0, 1], 9: [1], 10: [0, 2], }.get(num, []) top = self.get_top() + symbol.get_height() * DOWN bottom = self.get_bottom() + symbol.get_height() * UP column_points = [ interpolate(top, bottom, alpha) for alpha in np.linspace(0, 1, n_rows) ] design = VGroup( *[symbol.copy().move_to(point) for point in column_points]) if n_cols == 2: space = 0.2 * self.get_width() column_copy = design.copy().shift(space * RIGHT) design.shift(space * LEFT) design.add(*column_copy) design.add(*[ symbol.copy().move_to(center_of_mass(column_points[i:i + 2])) for i in insertion_indices ]) for symbol in design: if symbol.get_center()[1] < self.get_center()[1]: symbol.rotate_in_place(np.pi) return design
def fractalification_iteration(vmobject, dimension=1.05, num_inserted_anchors_range=list(range(1, 4))): num_points = vmobject.get_num_points() if num_points > 0: # original_anchors = vmobject.get_anchors() original_anchors = [ vmobject.point_from_proportion(x) for x in np.linspace(0, 1 - 1. / num_points, num_points) ] new_anchors = [] for p1, p2, in zip(original_anchors, original_anchors[1:]): num_inserts = random.choice(num_inserted_anchors_range) inserted_points = [ interpolate(p1, p2, alpha) for alpha in np.linspace(0, 1, num_inserts + 2)[1:-1] ] mass_scaling_factor = 1. / (num_inserts + 1) length_scaling_factor = mass_scaling_factor**(1. / dimension) target_length = get_norm(p1 - p2) * length_scaling_factor curr_length = get_norm(p1 - p2) * mass_scaling_factor # offset^2 + curr_length^2 = target_length^2 offset_len = np.sqrt(target_length**2 - curr_length**2) unit_vect = (p1 - p2) / get_norm(p1 - p2) offset_unit_vect = rotate_vector(unit_vect, np.pi / 2) inserted_points = [ point + u * offset_len * offset_unit_vect for u, point in zip(it.cycle([-1, 1]), inserted_points) ] new_anchors += [p1] + inserted_points new_anchors.append(original_anchors[-1]) vmobject.set_points_as_corners(new_anchors) vmobject.submobjects = [ fractalification_iteration(submob, dimension, num_inserted_anchors_range) for submob in vmobject.submobjects ] return vmobject
def update_submobject(self, submobject, starting_submobject, alpha): submobject.pointwise_become_partial(starting_submobject, 0, min(2 * alpha, 1)) if alpha < 0.5: if self.stroke_color: color = self.stroke_color elif starting_submobject.stroke_width > 0: color = starting_submobject.get_stroke_color() else: color = starting_submobject.get_color() submobject.set_stroke(color, width=self.stroke_width) submobject.set_fill(opacity=0) else: if not self.reached_halfway_point_before: self.reached_halfway_point_before = True submobject.points = np.array(starting_submobject.points) width, opacity = [ interpolate(start, end, 2 * alpha - 1) for start, end in [(self.stroke_width, starting_submobject.get_stroke_width()), (0, starting_submobject.get_fill_opacity())] ] submobject.set_stroke(width=width) submobject.set_fill(opacity=opacity)
def update_submobject(self, submobject, starting_submobject, alpha): submobject.set_stroke(opacity=interpolate( 0, starting_submobject.get_stroke_opacity(), alpha)) submobject.set_fill(opacity=interpolate( 0, starting_submobject.get_fill_opacity(), alpha))
def fade_to(self, color, alpha): self.rgbas = interpolate(self.rgbas, color_to_rgba(color), alpha) for mob in self.submobjects: mob.fade_to(color, alpha) return self
def interpolate_color(self, mobject1, mobject2, alpha): assert (mobject1.pixel_array.shape == mobject2.pixel_array.shape) self.pixel_array = interpolate(mobject1.pixel_array, mobject2.pixel_array, alpha).astype(self.pixel_array_dtype)
def interpolate_color(self, mobject1, mobject2, alpha): self.rgbas = interpolate( mobject1.rgbas, mobject2.rgbas, alpha )
def parameterized_function(alpha): x = interpolate(x_min, x_max, alpha) y = func(x) if not np.isfinite(y): y = self.y_max return self.coords_to_point(x, y)
def interpolate_color(color1, color2, alpha): rgb = interpolate(color_to_rgb(color1), color_to_rgb(color2), alpha) return rgb_to_color(rgb)
def random_bright_color(): color = random_color() curr_rgb = color_to_rgb(color) new_rgb = interpolate(curr_rgb, np.ones(len(curr_rgb)), 0.5) return Color(rgb=new_rgb)
def add_spikes(self): layers = VGroup() radii = np.linspace( self.outer_radius, self.pupil_radius, self.n_spike_layers, endpoint=False, ) radii[:2] = radii[1::-1] # Swap first two radii[-1] = interpolate(radii[-1], self.pupil_radius, 0.25) for radius in radii: tip_angle = self.spike_angle half_base = radius * np.tan(tip_angle) triangle, right_half_triangle = [ Polygon( radius * UP, half_base * RIGHT, vertex3, fill_opacity=1, stroke_width=0, ) for vertex3 in ( half_base * LEFT, ORIGIN, ) ] left_half_triangle = right_half_triangle.copy() left_half_triangle.flip(UP, about_point=ORIGIN) n_spikes = self.n_spikes full_spikes = [ triangle.copy().rotate(-angle, about_point=ORIGIN) for angle in np.linspace(0, TAU, n_spikes, endpoint=False) ] index = (3 * n_spikes) // 4 if radius == radii[0]: layer = VGroup(*full_spikes) layer.rotate(-TAU / n_spikes / 2, about_point=ORIGIN) layer.brown_index = index else: half_spikes = [ right_half_triangle.copy(), left_half_triangle.copy().rotate( 90 * DEGREES, about_point=ORIGIN, ), right_half_triangle.copy().rotate( 90 * DEGREES, about_point=ORIGIN, ), left_half_triangle.copy() ] layer = VGroup(*it.chain( half_spikes[:1], full_spikes[1:index], half_spikes[1:3], full_spikes[index + 1:], half_spikes[3:], )) layer.brown_index = index + 1 layers.add(layer) # Color spikes blues = self.blue_spike_colors browns = self.brown_spike_colors for layer, blue, brown in zip(layers, blues, browns): index = layer.brown_index layer[:index].set_color(blue) layer[index:].set_color(brown) self.spike_layers = layers self.add(layers)