Merge branch 'main' into main

This commit is contained in:
Dhruv Jaiswal 2025-11-14 21:56:59 +05:30 committed by GitHub
commit a5b8e8f8ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 92 additions and 6 deletions

View file

@ -84,7 +84,7 @@ SCENE_NOT_FOUND_MESSAGE = """
"""
CHOOSE_NUMBER_MESSAGE = """
Choose number corresponding to desired scene/arguments.
(Use comma separated list for multiple entries)
(Use comma separated list for multiple entries or use "*" to select all scenes.)
Choice(s): """
INVALID_NUMBER_MESSAGE = "Invalid scene numbers have been specified. Aborting."
NO_SCENE_MESSAGE = """

View file

@ -40,6 +40,7 @@ __all__ = [
"CubicBezier",
"ArcPolygon",
"ArcPolygonFromArcs",
"TangentialArc",
]
import itertools
@ -55,6 +56,7 @@ from manim.mobject.types.vectorized_mobject import VGroup, VMobject
from manim.utils.color import BLACK, BLUE, RED, WHITE, ParsableManimColor
from manim.utils.iterables import adjacent_pairs
from manim.utils.space_ops import (
angle_between_vectors,
angle_of_vector,
cartesian_to_spherical,
line_intersection,
@ -66,6 +68,7 @@ if TYPE_CHECKING:
from collections.abc import Iterable
import manim.mobject.geometry.tips as tips
from manim.mobject.geometry.line import Line
from manim.mobject.mobject import Mobject
from manim.mobject.text.tex_mobject import SingleStringMathTex, Tex
from manim.mobject.text.text_mobject import Text
@ -514,6 +517,71 @@ class ArcBetweenPoints(Arc):
self.radius = np.inf
class TangentialArc(ArcBetweenPoints):
"""
Construct an arc that is tangent to two intersecting lines.
You can choose any of the 4 possible corner arcs via the `corner` tuple.
corner = (s1, s2) where each si is ±1 to control direction along each line.
Example
-------
.. manim:: TangentialArcExample
class TangentialArcExample(Scene):
def construct(self):
line1 = DashedLine(start=3 * LEFT, end=3 * RIGHT)
line1.rotate(angle=31 * DEGREES, about_point=ORIGIN)
line2 = DashedLine(start=3 * UP, end=3 * DOWN)
line2.rotate(angle=12 * DEGREES, about_point=ORIGIN)
arc = TangentialArc(line1, line2, radius=2.25, corner=(1, 1), color=TEAL)
self.add(arc, line1, line2)
"""
def __init__(
self,
line1: Line,
line2: Line,
radius: float,
corner: Any = (1, 1),
**kwargs: Any,
):
self.line1 = line1
self.line2 = line2
intersection_point = line_intersection(
[line1.get_start(), line1.get_end()], [line2.get_start(), line2.get_end()]
)
s1, s2 = corner
# Get unit vector for specified directions
unit_vector1 = s1 * line1.get_unit_vector()
unit_vector2 = s2 * line2.get_unit_vector()
corner_angle = angle_between_vectors(unit_vector1, unit_vector2)
tangent_point_distance = radius / np.tan(corner_angle / 2)
# tangent points
tangent_point1 = intersection_point + tangent_point_distance * unit_vector1
tangent_point2 = intersection_point + tangent_point_distance * unit_vector2
cross_product = (
unit_vector1[0] * unit_vector2[1] - unit_vector1[1] * unit_vector2[0]
)
# Determine start and end points based on orientation
if cross_product < 0:
# Counterclockwise orientation - standard order
start_point = tangent_point1
end_point = tangent_point2
else:
# Clockwise orientation - reverse the points
start_point = tangent_point2
end_point = tangent_point1
super().__init__(start=start_point, end=end_point, radius=radius, **kwargs)
class CurvedArrow(ArcBetweenPoints):
def __init__(
self, start_point: Point3DLike, end_point: Point3DLike, **kwargs: Any

View file

@ -121,12 +121,18 @@ def prompt_user_for_choice(scene_classes: list[type[Scene]]) -> list[type[Scene]
user_input = console.input(
f"[log.message] {CHOOSE_NUMBER_MESSAGE} [/log.message]",
)
scene_classes = [
num_to_class[int(num_str)]
for num_str in re.split(r"\s*,\s*", user_input.strip())
if user_input == "*":
selected_scenes_classes = scene_classes
else:
selected_scenes_classes = [
num_to_class[int(num_str)]
for num_str in re.split(r"\s*,\s*", user_input.strip())
]
config["scene_names"] = [
scene_class.__name__ for scene_class in selected_scenes_classes
]
config["scene_names"] = [scene_class.__name__ for scene_class in scene_classes]
return scene_classes
return selected_scenes_classes
except KeyError:
logger.error(INVALID_NUMBER_MESSAGE)
sys.exit(2)

View file

@ -6,8 +6,11 @@ import numpy as np
from manim import (
DEGREES,
DOWN,
LEFT,
ORIGIN,
RIGHT,
UP,
BackgroundRectangle,
Circle,
Line,
@ -15,6 +18,7 @@ from manim import (
Sector,
Square,
SurroundingRectangle,
TangentialArc,
)
logger = logging.getLogger(__name__)
@ -116,6 +120,14 @@ def test_SurroundingRectangle():
assert sr.get_fill_opacity() == 0.42
def test_TangentialArc():
l1 = Line(start=LEFT, end=RIGHT)
l2 = Line(start=DOWN, end=UP)
l2.rotate(angle=45 * DEGREES, about_point=ORIGIN)
arc = TangentialArc(l1, l2, radius=1.0)
assert arc.radius == 1.0
def test_SurroundingRectangle_buff():
sq = Square()
rect1 = SurroundingRectangle(sq, buff=1)