Created and optimized Bézier splitting functions such as partial_bezier_points() in manim.utils.bezier
#3766
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Related PR: #3281
The original algorithm in
partial_bezier_points()made a lot of calls tobezier(), making multiple redundant intermediate calculations that could've been reused for the other Béziers.Instead, in the n-th degree case I calculate all of the necessary points in a single pass, improving from O(n³) to O(n²) time:
Even more, the process can be encoded as a matrix multiplication, which is what I did for the simple cases (up to cubic curves), giving around 10x speedup:
This rewritten function can now replace
partial_quadratic_bezier_points().I applied the exact same process for creating
split_bezier()andsubdivide_bezier(), which are very similar and use essentially the same algorithm, and can also be encoded as matrix multiplications. Moreover,subdivide_bezier()creates memos for each generated matrix, to reuse them in future calls to the function. Currentlysplit_bezier()isn't being used anywhere (originallysubdivide_quadratic_bezier()usedsplit_quadratic_bezier()), but I still leave it there because its docstring is useful and it might be used in the future for something else.I also created
bezier_remap(), based onquadratic_bezier_remap(), which usessubdivide_bezier(). I noticed thatVMobject.insert_n_curves_to_point_list()uses an algorithm that could've been a call tobezier_remap(), so I used that instead.All of this is thoroughly documented in docstrings, being the most important one the
split_bezier()docstring, where the algorithm is explained in depth. The other docstrings are based on this explanation.I also added many tests for many different cases.
Reviewer Checklist