Repository navigation
Fix add_points_as_corners not connecting single point to existing path - #4219
Conversation
chopan050
left a comment
There was a problem hiding this comment.
Hi and thanks for the changes!
I'm the author of PR #3765, which optimized many VMobject methods including this one. Originally, .add_points_as_corners() consisted of a for loop repeatedly calling .add_line_to() and destroying/recreating self.points, so I optimized it to do it only once. Unfortunately, I mistranslated some of the logic, causing the issue you're fixing now.
The concept you present is fine. However, if you notice, this new line you add:
start_corners = np.vstack([self.points[-1], points[:-1]])is functionally the same as what's already in the previous if branch:
start_corners = np.empty((num_points, self.dim))
start_corners[0] = self.points[-1]
start_corners[1:] = points[:-1]I prefer using those 3 lines, since np.vstack is, for some reason, quite slow and np.empty is faster.
Therefore, that logic should be instead factored out of the if-else. Instead of having:
if self.has_new_path_started():
# Pop the last point from self.points and
# add it to start_corners
start_corners = np.empty((num_points, self.dim))
start_corners[0] = self.points[-1]
start_corners[1:] = points[:-1]
end_corners = points
self.points = self.points[:-1]
else:
start_corners = np.vstack([self.points[-1], points[:-1]])
end_corners = pointswe could have:
start_corners = np.empty((num_points, self.dim))
start_corners[0] = self.points[-1]
start_corners[1:] = points[:-1]
end_corners = points
if self.has_new_path_started():
# Remove the last point from the new path.
self.points = self.points[:-1]Also, since we're now always using the last point from self, we should bring back the call to .throw_error_if_no_points() at the beginning of this method:
self.throw_error_if_no_points()
points = np.asarray(points).reshape(-1, self.dim)
num_points = points.shape[0]
if num_points == 0:
return self
# the rest...|
Thank you for the detailed explanation and suggestion — I really appreciate it! |
…4750) * Add regression tests for four recent fixes in vectorized_mobject.py Adds four regression tests for fixes that landed without tests in the same PR: * 21cf999 (PR #4630, fixes #3569 + #4629) -- IndexError in `get_nth_subpath` when `path_list` is empty; ensure it always returns a NumPy array. * f6cdb54 (PR #4219) -- `add_points_as_corners` silently dropped a single new point when called on a VMobject whose last subpath was complete. * 3d029c1 (PR #4320, fixes #4255) -- `pointwise_become_partial` cleared the target's points when the source had no cubic curves, surfacing as `Arrow3D.get_start()` / `get_end()` returning the origin after a `Create` animation. * 429f253 (PR #4694) -- `scale(scale_stroke=True)` on a compound VMobject propagated the parent's scaled stroke width to every submobject, overwriting submobjects with their own (e.g. zero) stroke. Each test reproduces the original failing condition at the unit level and asserts the post-fix behavior. Validation: every test was confirmed to fail when the corresponding fix is reverted on the source file, and pass when the fix is restored. 4 tests, ~0.2s runtime. Tests go in the existing files `tests/module/mobject/types/vectorized_mobject/test_vectorized_mobject.py` (three tests, adjacent to their topically-related siblings) and `tests/module/mobject/types/vectorized_mobject/test_stroke.py` (one test, next to the existing `test_stroke_scale`). Co-authored-by: LetMarq <LetMarq@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: THE-RAF <THE-RAF@users.noreply.github.com> Co-authored-by: LetMarq <LetMarq@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>
Overview: What does this pull request change?
Fixes #4218.
Motivation and Explanation: Why and how do your changes improve the library?
add_points_as_corners()did not include the last point of the existing path, causing no line to be added when only one new point was provided.This fix explicitly adds the last point of the existing path as the starting corner of the new segment, ensuring the path is continuous and no segment is skipped.
Links to added or changed documentation pages
Docs related to the issue after this fix: https://manimce--4219.org.readthedocs.build/en/4219/examples.html#pointwithtrace
Reviewer Checklist