diff --git a/docs/source/guides/index.rst b/docs/source/guides/index.rst index 0f0a92b98d..5be0184647 100644 --- a/docs/source/guides/index.rst +++ b/docs/source/guides/index.rst @@ -8,5 +8,6 @@ Thematic Guides configuration deep_dive + units using_text add_voiceovers diff --git a/docs/source/guides/units.rst b/docs/source/guides/units.rst new file mode 100644 index 0000000000..42807c6eb0 --- /dev/null +++ b/docs/source/guides/units.rst @@ -0,0 +1,84 @@ +Units +##### + +Manim uses *Manim units* for lengths in a scene. The visible frame is +``config.frame_width`` Manim units wide and ``config.frame_height`` Manim units +tall. The :mod:`manim.utils.unit` module provides helpers for converting common +measurements into these scene units. + +The helpers are exposed through the ``unit`` namespace: + +.. code-block:: pycon + + >>> from manim import * + >>> 50 * unit.Pixels + 0.37037037037037035 + >>> 90 * unit.Degrees + 1.5707963267948966 + >>> 10 * unit.Percent(X_AXIS) + 1.4222222222222223 + +Pixels +****** + +``unit.Pixels`` converts a number of screen pixels to Manim units. This is +useful when a value should stay tied to the rendered pixel resolution instead of +to a mathematical coordinate. + +.. code-block:: pycon + + >>> from manim import * + >>> config.pixel_width + 1920 + >>> config.frame_width + 14.222222222222221 + >>> 50 * unit.Pixels + 0.37037037037037035 + +The conversion depends on the current frame and pixel configuration, so changing +``config.frame_width`` or ``config.pixel_width`` changes the value returned by +``unit.Pixels``. + +Degrees +******* + +Angles in Manim are given in radians. ``unit.Degrees`` converts degrees to +radians: + +.. code-block:: pycon + + >>> from manim import * + >>> 45 * unit.Degrees + 0.7853981633974483 + >>> 180 * unit.Degrees == PI + True + +Percent +******* + +``unit.Percent`` converts a percentage of the current frame width or height to +Manim units. Pass ``X_AXIS`` to use ``config.frame_width`` and ``Y_AXIS`` to use +``config.frame_height``: + +.. code-block:: pycon + + >>> from manim import * + >>> 10 * unit.Percent(X_AXIS) + 1.4222222222222223 + >>> 25 * unit.Percent(Y_AXIS) + 2.0 + +The Z axis does not have a frame length, so ``unit.Percent(Z_AXIS)`` is not +defined. + +Munits +****** + +``unit.Munits`` represents a Manim unit directly. It is equal to ``1`` and can +be used when mixing explicit unit conversions in the same expression: + +.. code-block:: pycon + + >>> from manim import * + >>> 3 * unit.Munits + 3 diff --git a/docs/source/reference_index/utilities_misc.rst b/docs/source/reference_index/utilities_misc.rst index bda1cf4961..f6877bcff4 100644 --- a/docs/source/reference_index/utilities_misc.rst +++ b/docs/source/reference_index/utilities_misc.rst @@ -32,4 +32,5 @@ Module Index ~utils.tex ~utils.tex_file_writing ~utils.tex_templates + ~utils.unit typing diff --git a/manim/utils/unit.py b/manim/utils/unit.py index c4755f0191..67053b992a 100644 --- a/manim/utils/unit.py +++ b/manim/utils/unit.py @@ -1,4 +1,4 @@ -"""Implement the Unit class.""" +"""Helpers for converting common scalar units to Manim units.""" from __future__ import annotations @@ -11,6 +11,8 @@ class _PixelUnits: + """Convert pixel lengths to Manim units.""" + def __mul__(self, val: float) -> float: return val * config.frame_width / config.pixel_width @@ -19,6 +21,16 @@ def __rmul__(self, val: float) -> float: class Percent: + """Convert percentages of the frame width or height to Manim units. + + Parameters + ---------- + axis + Use :data:`~manim.constants.X_AXIS` for percentages of + ``config.frame_width`` or :data:`~manim.constants.Y_AXIS` for + percentages of ``config.frame_height``. + """ + def __init__(self, axis: Vector3D) -> None: if np.array_equal(axis, constants.X_AXIS): self.length = config.frame_width