Skip to content
53 changes: 13 additions & 40 deletions manim/mobject/opengl/opengl_vectorized_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
from manim.renderer.shader_wrapper import ShaderWrapper
from manim.utils.bezier import (
bezier,
bezier_remap,
get_quadratic_approximation_of_cubic,
get_smooth_cubic_bezier_handle_points,
integer_interpolate,
interpolate,
partial_quadratic_bezier_points,
partial_bezier_points,
proportions_along_bezier_curve_for_point,
quadratic_bezier_remap,
)
from manim.utils.color import BLACK, WHITE, ManimColor, ParsableManimColor
from manim.utils.config_ops import _Data
Expand Down Expand Up @@ -555,7 +555,7 @@ def subdivide_sharp_curves(self, angle_threshold=30 * DEGREES, recurse=True):
alphas = np.linspace(0, 1, n + 1)
new_points.extend(
[
partial_quadratic_bezier_points(tup, a1, a2)
partial_bezier_points(tup, a1, a2)
for a1, a2 in zip(alphas, alphas[1:])
],
)
Expand Down Expand Up @@ -1275,33 +1275,12 @@ def insert_n_curves_to_point_list(self, n: int, points: np.ndarray) -> np.ndarra
if len(points) == 1:
return np.repeat(points, nppc * n, 0)

bezier_groups = self.get_bezier_tuples_from_points(points)
norms = np.array([np.linalg.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 _ in range(diff):
ipc[np.argmin(ipc)] += 1
for _ in range(-diff):
ipc[np.argmax(ipc)] -= 1

new_length = sum(x + 1 for x in ipc)
new_points = np.empty((new_length, nppc, 3))
i = 0
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[i] = partial_quadratic_bezier_points(group, a1, a2)
i = i + 1
return np.vstack(new_points)
bezier_tuples = self.get_bezier_tuples_from_points(points)
current_number_of_curves = len(bezier_tuples)
new_number_of_curves = current_number_of_curves + n
new_bezier_tuples = bezier_remap(bezier_tuples, new_number_of_curves)
new_points = new_bezier_tuples.reshape(-1, 3)
return new_points

def interpolate(self, mobject1, mobject2, alpha, *args, **kwargs):
super().interpolate(mobject1, mobject2, alpha, *args, **kwargs)
Expand Down Expand Up @@ -1354,32 +1333,26 @@ def pointwise_become_partial(
return self
if lower_index == upper_index:
self.append_points(
partial_quadratic_bezier_points(
partial_bezier_points(
bezier_triplets[lower_index],
lower_residue,
upper_residue,
),
)
else:
self.append_points(
partial_quadratic_bezier_points(
bezier_triplets[lower_index], lower_residue, 1
),
partial_bezier_points(bezier_triplets[lower_index], lower_residue, 1),
)
inner_points = bezier_triplets[lower_index + 1 : upper_index]
if len(inner_points) > 0:
if remap:
new_triplets = quadratic_bezier_remap(
inner_points, num_quadratics - 2
)
new_triplets = bezier_remap(inner_points, num_quadratics - 2)
else:
new_triplets = bezier_triplets

self.append_points(np.asarray(new_triplets).reshape(-1, 3))
self.append_points(
partial_quadratic_bezier_points(
bezier_triplets[upper_index], 0, upper_residue
),
partial_bezier_points(bezier_triplets[upper_index], 0, upper_residue),
)
return self

Expand Down
40 changes: 6 additions & 34 deletions manim/mobject/types/vectorized_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
)
from manim.utils.bezier import (
bezier,
bezier_remap,
get_smooth_handle_points,
integer_interpolate,
interpolate,
Expand Down Expand Up @@ -1693,40 +1694,11 @@ def insert_n_curves_to_point_list(
if len(points) == 1:
nppcc = self.n_points_per_cubic_curve
return np.repeat(points, nppcc * n, 0)
bezier_quads = self.get_cubic_bezier_tuples_from_points(points)
curr_num = len(bezier_quads)
target_num = curr_num + n
# This is an array with values ranging from 0
# up to curr_num, with repeats such that
# it's total length is target_num. For example,
# with curr_num = 10, target_num = 15, this would
# be [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9]
repeat_indices = (np.arange(target_num, dtype="i") * curr_num) // target_num

# If the nth term of this list is k, it means
# that the nth curve of our path should be split
# into k pieces.
# In the above example our array had the following elements
# [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9]
# We have two 0s, one 1, two 2s and so on.
# The split factors array would hence be:
# [2, 1, 2, 1, 2, 1, 2, 1, 2, 1]
split_factors = np.zeros(curr_num, dtype="i")
for val in repeat_indices:
split_factors[val] += 1

new_points = np.zeros((0, self.dim))
for quad, sf in zip(bezier_quads, split_factors):
# What was once a single cubic curve defined
# by "quad" will now be broken into sf
# smaller cubic curves
alphas = np.linspace(0, 1, sf + 1)
for a1, a2 in zip(alphas, alphas[1:]):
new_points = np.append(
new_points,
partial_bezier_points(quad, a1, a2),
axis=0,
)
bezier_tuples = self.get_cubic_bezier_tuples_from_points(points)
current_number_of_curves = len(bezier_tuples)
new_number_of_curves = current_number_of_curves + n
new_bezier_tuples = bezier_remap(bezier_tuples, new_number_of_curves)
new_points = new_bezier_tuples.reshape(-1, 3)
return new_points

def align_rgbas(self, vmobject: VMobject) -> Self:
Expand Down
Loading
Loading