Skip to content

Commit 2dba485

Browse files
authored
Slight performance improvement for :class:.ArrowVectorField and Bezier curve computation (#2727)
* perf(bezier) added explicit definitions of quadratic and cubic in bezier.py * perf(vectorized_mobject): replaced apply_along_axis with direct call to linalg.norm * perf(vector_field): removed unnecessary calls to self.add and added get_vectors (multiple vectors at once) * perf(iterables): removed duplicate calls to len(list) in make_even * revert: removed get_vectors * fix(get_vector): use asarray for point * quickfix(vector_field): removed point asarray
1 parent 9148c66 commit 2dba485

File tree

4 files changed

+30
-7
lines changed

4 files changed

+30
-7
lines changed

manim/mobject/types/vectorized_mobject.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,7 @@ def get_nth_curve_length_pieces(
11021102
curve = self.get_nth_curve_function(n)
11031103
points = np.array([curve(a) for a in np.linspace(0, 1, sample_points)])
11041104
diffs = points[1:] - points[:-1]
1105-
norms = np.apply_along_axis(np.linalg.norm, 1, diffs)
1105+
norms = np.linalg.norm(diffs, axis=1)
11061106

11071107
return norms
11081108

manim/mobject/vector_field.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -575,8 +575,12 @@ def __init__(
575575
x_range = np.arange(*self.x_range)
576576
y_range = np.arange(*self.y_range)
577577
z_range = np.arange(*self.z_range)
578-
for x, y, z in it.product(x_range, y_range, z_range):
579-
self.add(self.get_vector(x * RIGHT + y * UP + z * OUT))
578+
self.add(
579+
*[
580+
self.get_vector(x * RIGHT + y * UP + z * OUT)
581+
for x, y, z in it.product(x_range, y_range, z_range)
582+
]
583+
)
580584
self.set_opacity(self.opacity)
581585

582586
def get_vector(self, point: np.ndarray):
@@ -594,7 +598,7 @@ def get_vector(self, point: np.ndarray):
594598
Additional arguments to be passed to the :class:`~.Vector` constructor
595599
596600
"""
597-
output = np.array(self.func(point))
601+
output = np.asarray(self.func(point))
598602
norm = np.linalg.norm(output)
599603
if norm != 0:
600604
output *= self.length_func(norm) / norm

manim/utils/bezier.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,23 @@ def bezier(
4646
function describing the bezier curve.
4747
"""
4848
n = len(points) - 1
49+
50+
# Cubic Bezier curve
51+
if n == 3:
52+
return (
53+
lambda t: (1 - t) ** 3 * points[0]
54+
+ 3 * t * (1 - t) ** 2 * points[1]
55+
+ 3 * (1 - t) * t**2 * points[2]
56+
+ t**3 * points[3]
57+
)
58+
# Quadratic Bezier curve
59+
if n == 2:
60+
return (
61+
lambda t: (1 - t) ** 2 * points[0]
62+
+ 2 * t * (1 - t) * points[1]
63+
+ t**2 * points[2]
64+
)
65+
4966
return lambda t: sum(
5067
((1 - t) ** (n - k)) * (t**k) * choose(n, k) * point
5168
for k, point in enumerate(points)

manim/utils/iterables.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,12 @@ def make_even(iterable_1: Iterable, iterable_2: Iterable) -> tuple[list, list]:
182182
# ([1, 1, 1, 2, 2], [3, 4, 5, 6, 7])
183183
"""
184184
list_1, list_2 = list(iterable_1), list(iterable_2)
185-
length = max(len(list_1), len(list_2))
185+
len_list_1 = len(list_1)
186+
len_list_2 = len(list_2)
187+
length = max(len_list_1, len_list_2)
186188
return (
187-
[list_1[(n * len(list_1)) // length] for n in range(length)],
188-
[list_2[(n * len(list_2)) // length] for n in range(length)],
189+
[list_1[(n * len_list_1) // length] for n in range(length)],
190+
[list_2[(n * len_list_2) // length] for n in range(length)],
189191
)
190192

191193

0 commit comments

Comments
 (0)