Skip to content

Move mobject positioning methods into own class - #4944

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

Move mobject positioning methods into own class#4944
GniLudio wants to merge 69 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?

Moves the Mobject positioning methods into their own class. Additionally, cleans up a lot of implementations.

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

  • Better separation of concerns
  • Cleans up implementations
  • Easier extensibility and maintainability
  • Renderer-independent
  • Performance improvements

Key Changes

  • Code Quality
    • Moves positioning methods into a separate class
    • Streamlines structure
    • Cleans up implementations
  • Usability
    • Improves performance (see test below)
    • Adds setter methods for all parameters
    • Adds docstrings to all methods
    • Deprecates some methods
    • All setter allow passing another object for the value
    • Declares kwargs explicitly (breaking change)
    • Adjusts some parameter names (breaking change)

Structure

A brief overview of the class structure:

  • Applying Functions
    • get_family
    • apply_(to_family|array_function|function|complex_function)
    • reduce_points
  • Transformations
    • translate, rotate, scale, stretch, apply_matrix
  • General
    • (get|set)_position
      • (get|set)_(center|left|right|bottom|top|nadir|zenith)
    • (get|set)_coordinate
      • (get|set)_(x|y|z)
    • (get|set)_dim_size
      • (get|set)_(width|height|depth)
  • Specialized
    • align_on_border, align_to, ...

Deprecations

There are several methods that were renamed or have more powerful alternatives now. For compatibility reason, they are redirect to the renamed/alternative method marked as deprecated for now. For some of these it probably makes sense to have the redirect without deprecating them, like move_to and shift.
Feel free to make suggestions...

List
Method Redirects to
apply_function_to_position set_position(function(self.get_position()))
apply_points_function_about_point apply_array_function
depth (get|set)_depth
get_corner get_position
get_coord get_coordinate
get_critical_point get_position
get_edge_center get_position
height (get|set)_height
length_over_dim get_dim_size
match_coord set_coord
match_dim_size set_dim_size
match_depth set_depth
match_points set_points
match_x set_x
match_y set_y
match_z set_z
match_width set_width
match_height set_height
move_to set_position
rotate_about_origin rotate
rescale_to_fit set_dim_size
set_coord set_coordinate
shift translate
stretch_about_point stretch
to_corner align_on_border
to_edge align_on_border
width (get|set)_width

TODOs

  • The next_to method belongs also inside Positionable, but the implementation requires access to the submobjects. Feel free to make suggestions on how to handle this.
  • Once the list of deprecated and alias methods has been finalized, the deprecation annotations should be added and usages of the deprecated methods should be removed from the code base.
  • I plan to use Positionable for OpenGLMobject in a following PR, so that the diff of this PR stays reasonable.

Test & Benchmark

I used randomized testing to ensure that no behavior was modified. The test succeeds for all (tested) methods and outputs a speed comparison.

Point Count align_on_border align_to center depth (get) depth (set) flip get_bottom get_center get_center_of_mass get_coord get_corner get_critical_point get_edge_center get_extremum_along_dim get_left get_nadir get_right get_top get_x get_y get_z get_zenith height (get) height (set) is_off_screen length_over_dim match_coord match_depth match_dim_size match_height match_points match_width match_x match_y match_z move_to pose_at_angle rescale_to_fit rotate rotate_about_origin scale scale_to_fit_depth scale_to_fit_height scale_to_fit_width set_coord set_x set_y set_z shift shift_onto_screen stretch stretch_about_point stretch_to_fit_depth stretch_to_fit_height stretch_to_fit_width to_corner to_edge width (get) width (set)
10 1.6x 1.4x 1.9x 0.71x 1.4x 0.97x 2.0x 2.1x 4.6x 1.4x 1.9x 2.0x 2.0x 1.5x 2.0x 2.0x 2.1x 2.0x 1.5x 1.5x 1.5x 2.1x 0.71x 1.4x 10.1x 0.74x 2.1x 1.4x 1.3x 1.3x 2.7x 1.3x 2.1x 2.0x 1.9x 1.8x 0.94x 1.0x 1.2x 1.0x 1.0x 1.0x 0.96x 1.0x 1.5x 1.6x 1.6x 1.6x 1.8x 1.8x 1.1x 1.0x 0.94x 0.97x 0.99x 1.4x 1.6x 0.71x 1.4x
100 1.6x 1.5x 1.9x 2.1x 1.7x 0.94x 2.0x 2.0x 4.0x 1.4x 2.0x 2.0x 2.0x 1.5x 2.0x 2.0x 2.0x 2.0x 1.5x 1.6x 1.8x 2.0x 2.0x 1.6x 10.1x 2.0x 1.9x 1.7x 1.6x 1.7x 3.4x 1.6x 1.8x 1.9x 2.0x 1.8x 0.93x 1.4x 1.2x 1.1x 1.0x 1.4x 1.4x 1.4x 1.5x 1.6x 1.6x 1.6x 1.7x 1.7x 1.1x 0.98x 1.4x 1.5x 1.4x 1.6x 1.6x 2.1x 1.7x
1000 1.5x 1.5x 1.7x 12.2x 3.1x 0.95x 1.8x 1.8x 1.9x 1.3x 1.7x 1.8x 1.8x 1.4x 1.8x 1.8x 1.8x 1.8x 1.4x 1.6x 1.4x 1.9x 11.3x 2.6x 8.8x 9.1x 1.7x 3.5x 3.6x 3.5x 3.4x 3.6x 1.7x 1.8x 1.7x 1.7x 0.95x 3.8x 1.1x 1.2x 1.0x 3.5x 4.0x 3.5x 1.4x 1.4x 1.4x 1.4x 1.4x 1.6x 1.1x 1.0x 3.8x 3.7x 3.8x 1.4x 1.4x 12.2x 3.1x
10000 1.2x 2.0x 1.3x 34.7x 5.2x 0.98x 1.3x 1.3x 0.42x 1.2x 1.3x 1.3x 1.3x 1.2x 1.3x 1.3x 1.4x 1.3x 1.2x 1.3x 1.1x 1.3x 35.5x 5.0x 6.3x 31.8x 1.3x 7.0x 6.3x 6.7x 3.1x 6.6x 1.3x 1.3x 1.3x 1.3x 0.96x 6.8x 1.0x 1.9x 1.1x 6.6x 7.2x 6.8x 1.2x 1.3x 1.2x 1.2x 1.2x 1.3x 1.1x 1.0x 7.0x 6.8x 6.9x 1.2x 1.3x 36.4x 5.6x
100000 1.6x 3.1x 1.5x 20.1x 5.1x 0.92x 1.0x 1.1x 0.50x 1.0x 1.1x 1.1x 1.1x 1.0x 1.1x 1.0x 1.1x 1.1x 1.0x 1.0x 1.1x 1.1x 19.7x 5.2x 3.4x 21.1x 1.7x 5.7x 5.7x 5.6x 1.2x 5.7x 1.7x 1.7x 1.7x 1.6x 0.93x 5.8x 0.94x 1.6x 1.4x 5.8x 5.8x 5.7x 1.7x 1.7x 1.8x 1.7x 2.0x 1.7x 1.0x 1.00x 5.5x 5.6x 5.6x 1.6x 1.6x 22.7x 5.3x
Point Count align_on_border align_to center depth (get) depth (set) flip get_bottom get_center get_center_of_mass get_coord get_corner get_critical_point get_edge_center get_extremum_along_dim get_left get_nadir get_right get_top get_x get_y get_z get_zenith height (get) height (set) is_off_screen length_over_dim match_coord match_depth match_dim_size match_height match_points match_width match_x match_y match_z move_to pose_at_angle rescale_to_fit rotate rotate_about_origin scale scale_to_fit_depth scale_to_fit_height scale_to_fit_width set_coord set_x set_y set_z shift shift_onto_screen stretch stretch_about_point stretch_to_fit_depth stretch_to_fit_height stretch_to_fit_width to_corner to_edge width (get) width (set)
10 2.06 -0.78ms 1.56 -0.44ms 2.23 -1.03ms 0.27 +0.11ms 2.84 -0.84ms 2.45 +0.07ms 1.44 -0.72ms 1.66 -0.86ms 1.76 -1.38ms 0.38 -0.11ms 1.19 -0.57ms 1.18 -0.60ms 1.26 -0.62ms 0.36 -0.11ms 1.49 -0.74ms 1.46 -0.74ms 1.51 -0.79ms 1.55 -0.78ms 0.44 -0.15ms 0.45 -0.15ms 0.44 -0.15ms 1.59 -0.83ms 0.25 +0.10ms 3.18 -0.98ms 5.94 -5.35ms 0.28 +0.10ms 1.60 -0.82ms 2.26 -0.67ms 1.95 -0.47ms 2.04 -0.45ms 0.60 -0.38ms 1.99 -0.50ms 1.57 -0.83ms 1.38 -0.70ms 1.56 -0.75ms 1.86 -0.80ms 2.50 +0.17ms 1.18 -0.05ms 3.59 -0.49ms 2.20 -0.06ms 0.70 -0.02ms 1.11 -0.00ms 1.08 +0.04ms 1.46 -0.07ms 0.78 -0.27ms 0.80 -0.29ms 0.81 -0.30ms 0.87 -0.31ms 0.36 -0.17ms 14.89 -6.39ms 0.70 -0.05ms 0.57 -0.01ms 1.09 +0.07ms 1.05 +0.03ms 1.04 +0.01ms 2.19 -0.64ms 1.98 -0.72ms 0.25 +0.10ms 2.51 -0.75ms
100 1.99 -0.71ms 1.73 -0.56ms 2.54 -1.20ms 0.74 -0.39ms 3.26 -1.29ms 2.26 +0.15ms 1.47 -0.73ms 1.69 -0.86ms 1.64 -1.23ms 0.36 -0.11ms 1.15 -0.57ms 1.18 -0.58ms 1.21 -0.60ms 0.35 -0.11ms 1.47 -0.73ms 1.52 -0.76ms 1.61 -0.81ms 1.49 -0.76ms 0.44 -0.15ms 0.44 -0.16ms 0.54 -0.24ms 1.83 -0.93ms 0.76 -0.38ms 3.68 -1.41ms 6.11 -5.51ms 0.78 -0.39ms 1.35 -0.65ms 2.76 -1.14ms 2.33 -0.88ms 2.45 -0.98ms 0.54 -0.38ms 2.47 -0.92ms 1.39 -0.60ms 1.34 -0.65ms 1.37 -0.67ms 1.76 -0.81ms 2.32 +0.19ms 1.65 -0.49ms 3.58 -0.50ms 2.44 -0.22ms 0.73 -0.03ms 1.52 -0.46ms 1.63 -0.49ms 1.73 -0.49ms 0.80 -0.28ms 0.83 -0.30ms 0.81 -0.30ms 0.80 -0.31ms 0.35 -0.15ms 15.20 -6.47ms 0.86 -0.10ms 0.64 +0.01ms 1.70 -0.51ms 1.74 -0.54ms 1.51 -0.44ms 1.97 -0.73ms 2.00 -0.74ms 0.76 -0.40ms 3.11 -1.23ms
1000 2.63 -0.86ms 2.52 -0.81ms 2.86 -1.13ms 5.59 -5.13ms 9.53 -6.42ms 3.06 +0.17ms 1.73 -0.76ms 1.98 -0.87ms 1.86 -0.89ms 0.41 -0.10ms 1.33 -0.55ms 1.35 -0.60ms 1.33 -0.57ms 0.40 -0.11ms 1.74 -0.75ms 1.72 -0.75ms 1.72 -0.77ms 1.74 -0.80ms 0.53 -0.16ms 0.76 -0.29ms 0.53 -0.16ms 2.26 -1.07ms 5.57 -5.07ms 10.54 -6.46ms 6.94 -6.15ms 5.80 -5.16ms 2.16 -0.88ms 8.36 -6.00ms 8.50 -6.11ms 8.44 -6.01ms 0.58 -0.41ms 8.51 -6.13ms 1.97 -0.81ms 1.90 -0.84ms 1.91 -0.79ms 2.49 -1.03ms 3.42 +0.16ms 6.97 -5.16ms 5.12 -0.59ms 2.93 -0.44ms 1.37 -0.03ms 8.03 -5.73ms 7.60 -5.68ms 8.16 -5.83ms 1.24 -0.35ms 1.24 -0.36ms 1.20 -0.35ms 1.25 -0.38ms 0.70 -0.19ms 18.83 -6.80ms 1.59 -0.15ms 1.26 -0.04ms 7.01 -5.18ms 7.59 -5.56ms 7.56 -5.58ms 2.59 -0.80ms 2.73 -0.81ms 5.53 -5.08ms 9.51 -6.44ms
10000 7.70 -1.51ms 11.90 -5.93ms 9.41 -2.16ms 51.69 -50.20ms 68.47 -55.36ms 12.86 +0.30ms 3.62 -0.77ms 4.16 -0.94ms 2.69 +3.67ms 0.93 -0.12ms 2.62 -0.67ms 2.72 -0.66ms 2.66 -0.63ms 0.94 -0.14ms 3.69 -0.83ms 3.65 -0.84ms 4.09 -1.12ms 3.71 -0.89ms 1.33 -0.21ms 1.90 -0.40ms 1.38 -0.17ms 4.09 -1.01ms 52.34 -50.87ms 69.64 -55.59ms 14.69 -12.37ms 55.45 -53.71ms 6.04 -1.51ms 64.38 -55.18ms 67.28 -56.53ms 65.40 -55.66ms 0.69 -0.46ms 65.16 -55.35ms 6.29 -1.54ms 6.16 -1.59ms 6.10 -1.52ms 7.56 -1.64ms 13.31 +0.59ms 61.92 -52.87ms 15.79 -0.29ms 12.88 -5.98ms 8.76 -0.52ms 66.91 -56.85ms 63.41 -54.64ms 65.36 -55.68ms 5.51 -0.99ms 5.47 -1.10ms 5.34 -0.96ms 5.48 -1.03ms 4.17 -0.80ms 50.69 -10.37ms 7.92 -0.43ms 7.10 -0.11ms 59.46 -50.97ms 62.72 -53.54ms 64.71 -55.27ms 7.93 -1.53ms 8.33 -1.93ms 52.40 -50.96ms 69.73 -57.29ms
100000 122.35 -46.43ms 243.06 -165.73ms 134.97 -47.68ms 495.26 -470.57ms 647.17 -520.99ms 168.51 +14.39ms 36.99 -1.61ms 41.74 -2.77ms 29.39 +29.64ms 16.43 -0.48ms 34.14 -2.49ms 31.38 -2.26ms 31.12 -1.97ms 18.92 -0.44ms 39.66 -2.72ms 35.74 -1.67ms 38.30 -3.27ms 37.32 -3.12ms 20.90 -0.53ms 25.37 -0.95ms 26.22 -1.59ms 39.54 -2.73ms 508.55 -482.71ms 666.19 -537.53ms 110.35 -78.20ms 530.25 -505.11ms 107.61 -45.06ms 609.82 -502.03ms 623.66 -513.68ms 618.19 -507.76ms 9.05 -1.55ms 623.44 -514.09ms 109.98 -46.95ms 107.32 -45.62ms 106.39 -45.10ms 119.82 -46.09ms 167.97 +12.08ms 621.35 -513.35ms 190.79 +11.40ms 160.39 -62.72ms 132.80 -40.39ms 647.71 -535.95ms 642.56 -531.30ms 630.18 -520.57ms 103.09 -43.36ms 105.81 -45.00ms 106.40 -45.84ms 107.02 -45.46ms 93.33 -45.79ms 548.61 -216.55ms 93.25 -1.24ms 90.69 +0.24ms 588.88 -482.62ms 596.08 -488.73ms 597.14 -490.25ms 115.86 -43.07ms 117.91 -43.53ms 499.93 -477.88ms 658.35 -534.13ms

These speedups are a nice to have, but are hardly noticeable in real-world use-cases. For example the Lissajous benchmark got less than a 1% speedup (521s -> 517s). The only significant change is the improvements to length_over_dim (and the width/height/depth respectively) on mobjects with a very large amount of points.

To run the test yourself, switch to the main branch, download the positionable.py and test.py and run the test.py.

uv add pandas[output-formatting]
curl.exe --create-dirs -o positionable.py "https://raw.githubusercontent.com/GniLudio/manim/refs/heads/rework-positioning/manim/mobject/abstract/positionable.py"
curl -o test.py "https://github.com/user-attachments/files/31552117/test.py"
python test.py

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
Comment thread manim/mobject/abstract/positionable.py Fixed
Comment thread manim/mobject/geometry/line.py Fixed
Comment thread manim/mobject/types/vectorized_mobject.py Fixed
Comment thread manim/mobject/abstract/positionable.py Fixed
Comment thread manim/mobject/abstract/positionable.py Fixed
Comment thread manim/mobject/abstract/positionable.py Fixed
@GniLudio
GniLudio marked this pull request as draft August 25, 2026 09:19
@GniLudio
GniLudio marked this pull request as ready for review August 28, 2026 11:36
@GniLudio GniLudio changed the title Rework positioning Separate mobject positioning methods into own class Aug 28, 2026
@GniLudio GniLudio changed the title Separate mobject positioning methods into own class Move mobject positioning methods into own class Aug 28, 2026
@GniLudio GniLudio added documentation Improvements or additions to documentation enhancement Additions and improvements in general refactor Refactor or redesign of existing code maintenance refactoring, typos, removing clutter/dead code, and other code quality improvements performance labels Aug 28, 2026
@GniLudio
GniLudio marked this pull request as draft August 30, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement Additions and improvements in general maintenance refactoring, typos, removing clutter/dead code, and other code quality improvements performance refactor Refactor or redesign of existing code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants