Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions manim/mobject/geometry.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import warnings
import numpy as np
import math

from ..constants import *
from ..mobject.mobject import Mobject
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand All @@ -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):
Expand All @@ -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,
Expand All @@ -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):
Expand Down Expand Up @@ -847,4 +875,4 @@ class RoundedRectangle(Rectangle):

def __init__(self, **kwargs):
Rectangle.__init__(self, **kwargs)
self.round_corners(self.corner_radius)
self.round_corners(self.corner_radius)
2 changes: 1 addition & 1 deletion manim/mobject/mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down