Skip to content

Rework positioning - #4944

Draft
GniLudio wants to merge 14 commits into
ManimCommunity:mainfrom
GniLudio:rework-positioning
Draft

Rework positioning#4944
GniLudio wants to merge 14 commits into
ManimCommunity:mainfrom
GniLudio:rework-positioning

Conversation

@GniLudio

@GniLudio GniLudio commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Overview: What does this pull request change?

Cleans up and moves the positioning methods from Mobject into a separate class.

This PR is still work in progress. Opened already, so I can get some feedback on the Positionable class.

PR #4923 was a proof of concept for this.

Motivation and Explanation: Why and how do your changes improve the library?

  • Cleans up positioning methods.
  • Deprecates methods with the same purpose.
  • Easier extensibility.
  • Better separation of concerns.
  • Reduces size of the mobject class.

Discussion

Mobjects with no points

Should the methods have explicit handling for mobjects with no points?

Matching methods

Currently, setters always have a separate match_* method to replicate another mobject. Instead of declaring separate methods, it would be quite easy to integrate that directly into the setter methods. The move_to method already does it that way, as there isn't a match_position method.

# Setter and match methods
def set_x(self, x: float, **kwargs) -> Self:
    ...
def match_x(self, mobject: Positionable, kwargs) -> Self:
    return self.set_x(
        x=self.get_x(**kwargs), 
        **kwargs,
    )

# Combined
def set_x(self, x: float | Positionable, **kwargs) -> Self:
    if isinstance(x, Positionable):
        return self.set_x(self.get_x(**kwargs), **kwargs)
    ...

In-between critical points

Currently, get_critical_point is restricted by np.sign(direction), as that preserves the old behavior.

Is there a reason to keep that restriction?

Without the restriction, things like get_critical_point(0.5*DL) and `get_critical_point(2*RIGHT) would be possible.

Hierarchy

This is the current method hierarchy. Any suggestions on how to improve this?

Excluding deprecated methods
  • apply_array_function
    • apply_function
      • apply_complex_function
    • apply_matrix
      • rotate
        • flip
    • scale
      • scale_to_fit
        • scale_to_fit_(width|height|depth)
      • set_dim_size
        • match_dim_size
        • set_(width|height|depth)
          • match_(width|height|depth)
      • stretch
        • stretch_to_fit
          • stretch_to_fit_(width|height|depth)
  • get_boundary_point
  • get_bounding_box
    • get_critical_point
      • get_(center|bottom|top|left|right|nadir|zenith)
    • is_off_screen
  • get_coord
    • get_(x|y|z)
  • get_dim_size
    • get_(width|height|depth)
  • get_center_of_mass
  • match_points
  • set_coord
    • match_coord
    • set_(x|y|z)
      • match_(x|y|z)
  • shift
    • align_on_border
      • to_corner
      • to_edge
    • align_to
    • move_to
      • center
    • next_to
Including deprecated methods
  • apply_array_function
    • apply_function
      • apply_complex_function
    • apply_matrix
      • rotate
        • flip
        • pose_at_angle - deprecated
        • rotate_about_origin - deprecated
    • apply_points_function_about_point - deprecated
    • scale
      • scale_to_fit
        • scale_to_fit_(width|height|depth)
      • set_dim_size
        • match_dim_size
        • set_(width|height|depth)
          • width|height|depth - deprecated
          • match_(width|height|depth)
        • rescale_to_fit - deprecated
      • stretch
        • stretch_about_point - deprecated
        • stretch_to_fit
          • stretch_to_fit_(width|height|depth)
  • get_boundary_point
  • get_bounding_box
    • get_critical_point
      • get_(center|bottom|top|left|right|nadir|zenith)
      • get_corner|get_edge_center - deprecated
    • is_off_screen
  • get_coord
    • get_(x|y|z)
  • get_dim_size
    • length_over_dim - deprecated
    • get_(width|height|depth)
      • width|height|depth - deprecated
  • get_extremum_along_dim - deprecated
  • get_center_of_mass
  • match_points
  • reduce_across_dimension - deprecated
  • set_coord
    • match_coord
    • set_(x|y|z)
      • match_(x|y|z)
  • shift
    • align_on_border
      • to_corner
      • to_edge
        • shift_onto_screen
    • align_to
    • move_to
      • apply_function_to_position - deprecated
      • center
    • next_to

Further Information and Comments

Test

The test.py checks whether any method behavior differs between the Mobject and Positionable class.
The test can be run using python test.py.

Changes

Surprisingly, cleaning up the implementations made all methods faster.
But keep in mind that the test is completely randomized and only includes up to 100 points.

Attribute Description Speed
align_on_border added frame parameter 1.52x
align_to 1.31x
apply_array_function new
replacement for apply_points_function_about_point
-
apply_complex_function - x
apply_function - x
apply_function_to_position deprecated - use move_to(function(self.get_center())) instead x
apply_matrix - x
apply_points_function_about_point deprecated - use apply_array_function instead x
center - 2.02x
depth deprecated - use get_depth instead 2.03x
depth deprecated - use set_depth instead 2.00x
flip - 1.23x
get_bottom - 1.83x
get_boundary_point - 1.23x
get_bounding_box new -
get_center - 2.12x
get_center_of_mass - 4.78x
get_coord - 1.63x
get_corner deprecated - use get_critical_point instead 1.40x
get_critical_point - 1.43x
get_depth new - replacement for depth -
get_dim_size new -
get_edge_center deprecated - use get_critical_point instead 1.42x
get_extremum_along_dim deprecated 1.19x
get_height new - replacement for height -
get_left - 1.82x
get_nadir - 1.82x
get_right - 1.92x
get_top - 1.92x
get_width new - replacement for width -
get_x - 1.56x
get_y - 1.60x
get_z - 1.62x
get_zenith - 1.90x
height deprecated - use get_height instead 1.98x
height deprecated - use set_height instead 1.97x
is_off_screen - 7.42x
length_over_dim deprecated - use get_dim_size instead 1.95x
match_coord 2.54x
match_depth made kwargs explicit 2.04x
match_dim_size made kwargs explicit 2.07x
match_height made kwargs explicit 2.04x
match_points removed copy_submobjects parameter 6.22x
match_width made kwargs explicit 2.06x
match_x 2.48x
match_y 2.52x
match_z 2.48x
move_to 1.64x
next_to implementation without submobject logic 1.53x
pose_at_angle deprecated
made kwargs explicit
1.24x
reduce_across_dimension - x
rescale_to_fit made kwargs explicit 1.66x
rotate removed unused kwargs parameter 1.28x
rotate_about_origin deprecated - use rotate instead 1.21x
scale supports scaling by a 3D vector 1.56x
scale_to_fit new -
scale_to_fit_depth made kwargs explicit 1.80x
scale_to_fit_height made kwargs explicit 1.81x
scale_to_fit_width made kwargs explicit 1.81x
set_coord 2.15x
set_depth new - replacement for depth -
set_dim_size new - replacement for rescale_to_fit -
set_height new - replacement for height -
set_width new - replacement for width -
set_x 2.11x
set_y 2.12x
set_z 2.16x
shift changed vararg *vectors to vector 2.61x
shift_onto_screen deprecated - made kwargs explicit 1.78x
stretch - 1.27x
stretch_about_point deprecated - use stretch instead 1.22x
stretch_to_fit new -
stretch_to_fit_depth made kwargs explicit 1.52x
stretch_to_fit_height made kwargs explicit 1.56x
stretch_to_fit_width made kwargs explicit 1.54x
to_corner 1.50x
to_edge 1.54x
width deprecated - use get_width instead 2.00x
width deprecated - use set_width instead 1.99x

Reviewer Checklist

  • The PR title is descriptive enough for the changelog, and the PR is labeled correctly
  • If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
  • If applicable: newly added functions and classes are tested

@GniLudio
GniLudio marked this pull request as draft August 19, 2026 22:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant