diff --git a/manim/mobject/geometry.py b/manim/mobject/geometry.py index 5636219560..d9de953ac4 100644 --- a/manim/mobject/geometry.py +++ b/manim/mobject/geometry.py @@ -1,5 +1,6 @@ import warnings import numpy as np +import math from ..constants import * from ..mobject.mobject import Mobject @@ -213,6 +214,7 @@ class Arc(TipableVMobject): def __init__(self, start_angle=0, angle=TAU / 4, **kwargs): self.start_angle = start_angle self.angle = angle + self._failed_to_get_center=False VMobject.__init__(self, **kwargs) def generate_points(self): @@ -245,7 +247,7 @@ def set_pre_positioned_points(self): anchors[1:], ) - def get_arc_center(self): + def get_arc_center(self,warning=True): """ Looks at the normals to the first two anchors, and finds their intersection points @@ -264,7 +266,9 @@ def get_arc_center(self): line2=(a2, a2 + n2), ) except Exception: - warnings.warn("Can't find Arc center, using ORIGIN instead") + if warning: + warnings.warn("Can't find Arc center, using ORIGIN instead") + self._failed_to_get_center=True return np.array(ORIGIN) def move_arc_center_to(self, point): @@ -278,7 +282,24 @@ def stop_angle(self): class ArcBetweenPoints(Arc): - def __init__(self, start, end, angle=TAU / 4, **kwargs): + """ + Inherits from Arc and additionally takes 2 points between which the arc is spanned. + """ + def __init__(self, start, end, angle=TAU / 4, radius=None, **kwargs): + if radius is not None: + self.radius=radius + if radius < 0: + sign=-2 + radius*=(-1) + else: + sign=2 + halfdist=np.linalg.norm(np.array(start) - np.array(end)) / 2 + if radius < halfdist: + raise ValueError("""ArcBetweenPoints called with a radius that is + smaller than half the distance between the points.""") + arc_height=radius - math.sqrt(radius ** 2 - halfdist ** 2) + angle=math.acos((radius - arc_height) / radius)*sign + Arc.__init__( self, angle=angle, @@ -287,6 +308,13 @@ def __init__(self, start, end, angle=TAU / 4, **kwargs): if angle == 0: self.set_points_as_corners([LEFT, RIGHT]) self.put_start_and_end_on(start, end) + + if radius is None: + center=self.get_arc_center(warning=False) + if not self._failed_to_get_center: + self.radius=np.linalg.norm(np.array(start) - np.array(center)) + else: + self.radius=math.inf class CurvedArrow(ArcBetweenPoints): @@ -847,4 +875,4 @@ class RoundedRectangle(Rectangle): def __init__(self, **kwargs): Rectangle.__init__(self, **kwargs) - self.round_corners(self.corner_radius) \ No newline at end of file + self.round_corners(self.corner_radius) diff --git a/manim/mobject/mobject.py b/manim/mobject/mobject.py index edd22af14d..0fb3c41aa3 100644 --- a/manim/mobject/mobject.py +++ b/manim/mobject/mobject.py @@ -550,7 +550,7 @@ def put_start_and_end_on(self, start, end): curr_vect = curr_end - curr_start if np.all(curr_vect == 0): raise Exception("Cannot position endpoints of closed loop") - target_vect = end - start + target_vect = np.array(end) - np.array(start) self.scale( get_norm(target_vect) / get_norm(curr_vect), about_point=curr_start,