diff --git a/manim/mobject/text/numbers.py b/manim/mobject/text/numbers.py index cd2372c543..0173cc6de5 100644 --- a/manim/mobject/text/numbers.py +++ b/manim/mobject/text/numbers.py @@ -16,6 +16,7 @@ from manim.mobject.types.vectorized_mobject import VMobject from manim.mobject.value_tracker import ValueTracker from manim.typing import Vector3DLike +from manim.utils.space_ops import angle_between_vectors string_to_mob_map: dict[str, SingleStringMathTex] = {} @@ -290,10 +291,22 @@ def set_value(self, number: float) -> Self: old_font_size = self.font_size move_to_point = self.get_edge_center(self.edge_to_fix) old_submobjects = self.submobjects + direction = self.get_right() - self.get_center() + rotation_angle = ( + angle_between_vectors(RIGHT, direction) + if np.linalg.norm(direction) > 1e-8 + else 0 + ) + if abs(rotation_angle) > 1e-8: + measure = self.copy() + measure.rotate(-rotation_angle, about_point=measure.get_center()) + old_font_size = measure.font_size self._set_submobjects_from_number(number) self.font_size = old_font_size self.move_to(move_to_point, self.edge_to_fix) + if abs(rotation_angle) > 1e-8: + self.rotate(rotation_angle, about_point=self.get_center()) for sm1, sm2 in zip(self.submobjects, old_submobjects, strict=False): sm1.match_style(sm2) diff --git a/tests/module/mobject/text/test_numbers.py b/tests/module/mobject/text/test_numbers.py index 7e46e83dea..a923429de0 100644 --- a/tests/module/mobject/text/test_numbers.py +++ b/tests/module/mobject/text/test_numbers.py @@ -1,6 +1,7 @@ from __future__ import annotations -from manim import RED, DecimalNumber, Integer +from manim import DEGREES, RED, RIGHT, DecimalNumber, Integer +from manim.utils.space_ops import angle_between_vectors def test_font_size(): @@ -38,6 +39,27 @@ def test_set_value_size(): assert round(num.height, 12) == round(test_num.height, 12) +def test_set_value_preserves_rotation(): + """Test that set_value keeps rotation applied to the number.""" + num = DecimalNumber(0, font_size=48) + num.rotate(45 * DEGREES) + direction = num.get_right() - num.get_center() + angle_before = angle_between_vectors(RIGHT, direction) + + num.set_value(1) + + direction = num.get_right() - num.get_center() + angle_after = angle_between_vectors(RIGHT, direction) + assert angle_before == angle_after + + +def test_set_value_preserves_font_size_when_rotated(): + num = DecimalNumber(0, font_size=48) + num.rotate(45 * DEGREES) + num.set_value(1) + assert num._font_size == 48 + + def test_color_when_number_of_digits_changes(): """Test that all digits of an Integer are colored correctly when the number of digits changes.