Skip to content

Commit

Permalink
Fix VMobject.add_points_as_corners() to return self and safely ha…
Browse files Browse the repository at this point in the history
…ndle empty `points` parameter (ManimCommunity#4091)

* Fix VMobject.add_points_as_corners() to return self and safely handle case where no points are passed

* Add test_vmobject_add_points_as_corners()

* assert np.allclose() -> np.testing.assert_allclose()
  • Loading branch information
chopan050 authored Jan 5, 2025
1 parent 17d4a7f commit 7879fe4
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
11 changes: 7 additions & 4 deletions manim/mobject/types/vectorized_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,7 @@ def close_path(self) -> None:
if not self.is_closed():
self.add_line_to(self.get_subpaths()[-1][0])

def add_points_as_corners(self, points: Point3DLike_Array) -> Point3D_Array:
def add_points_as_corners(self, points: Point3DLike_Array) -> Self:
"""Append multiple straight lines at the end of
:attr:`VMobject.points`, which connect the given ``points`` in order
starting from the end of the current path. These ``points`` would be
Expand All @@ -1058,10 +1058,14 @@ def add_points_as_corners(self, points: Point3DLike_Array) -> Point3D_Array:
path.
"""
points = np.asarray(points).reshape(-1, self.dim)
num_points = points.shape[0]
if num_points == 0:
return self

if self.has_new_path_started():
# Pop the last point from self.points and
# add it to start_corners
start_corners = np.empty((len(points), self.dim))
start_corners = np.empty((num_points, self.dim))
start_corners[0] = self.points[-1]
start_corners[1:] = points[:-1]
end_corners = points
Expand All @@ -1078,8 +1082,7 @@ def add_points_as_corners(self, points: Point3DLike_Array) -> Point3D_Array:
new_points[i::nppcc] = interpolate(start_corners, end_corners, t)

self.append_points(new_points)
# TODO: shouldn't this method return self instead of points?
return points
return self

def set_points_as_corners(self, points: Point3DLike_Array) -> Self:
"""Given an array of points, set them as corners of the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,37 @@ def test_vmobject_add():
assert len(obj.submobjects) == 1


def test_vmobject_add_points_as_corners():
points = np.array(
[
[2, 0, 0],
[1, 1, 0],
[-1, 1, 0],
[-2, 0, 0],
[-1, -1, 0],
[1, -1, 0],
[2, 0, 0],
]
)

# Test that add_points_as_corners(points) is equivalent to calling
# add_line_to(point) for every point in points.
obj1 = VMobject().start_new_path(points[0]).add_points_as_corners(points[1:])
obj2 = VMobject().start_new_path(points[0])
for point in points[1:]:
obj2.add_line_to(point)
np.testing.assert_allclose(obj1.points, obj2.points)

# Test that passing an array with no points does nothing.
obj3 = VMobject().start_new_path(points[0])
points3_old = obj3.points.copy()
obj3.add_points_as_corners([])
np.testing.assert_allclose(points3_old, obj3.points)

obj3.add_points_as_corners(points[1:]).add_points_as_corners([])
np.testing.assert_allclose(obj1.points, obj3.points)


def test_vmobject_point_from_proportion():
obj = VMobject()

Expand Down

0 comments on commit 7879fe4

Please sign in to comment.