Esempio n. 1
0
    def from_three_points(
        p1: Sequence[float], p2: Sequence[float], p3: Sequence[float], **kwargs
    ):
        """Returns a circle passing through the specified
        three points.

        Example
        -------
        .. manim:: CircleFromPointsExample
            :save_last_frame:

            class CircleFromPointsExample(Scene):
                def construct(self):
                    circle = Circle.from_three_points(LEFT, LEFT + UP, UP * 2, color=RED)
                    dots = VGroup(
                        Dot(LEFT),
                        Dot(LEFT + UP),
                        Dot(UP * 2),
                    )
                    self.add(NumberPlane(), circle, dots)
        """
        center = line_intersection(
            perpendicular_bisector([p1, p2]),
            perpendicular_bisector([p2, p3]),
        )
        radius = np.linalg.norm(p1 - center)
        return Circle(radius=radius, **kwargs).shift(center)
Esempio n. 2
0
    def get_arc_center(self, warning=True):
        """Looks at the normals to the first two
        anchors, and finds their intersection points
        """
        # First two anchors and handles
        a1, h1, h2, a2 = self.points[:4]

        if np.all(a1 == a2):
            # For a1 and a2 to lie at the same point arc radius
            # must be zero. Thus arc_center will also lie at
            # that point.
            return a1
        # Tangent vectors
        t1 = h1 - a1
        t2 = h2 - a2
        # Normals
        n1 = rotate_vector(t1, TAU / 4)
        n2 = rotate_vector(t2, TAU / 4)
        try:
            return line_intersection(line1=(a1, a1 + n1), line2=(a2, a2 + n2))
        except Exception:
            if warning:
                warnings.warn("Can't find Arc center, using ORIGIN instead")
            self._failed_to_get_center = True
            return np.array(ORIGIN)
Esempio n. 3
0
    def __init__(
        self,
        line1: Line,
        line2: Line,
        radius: float = None,
        quadrant=(1, 1),
        other_angle: bool = False,
        dot=False,
        dot_radius=None,
        dot_distance=0.55,
        dot_color=WHITE,
        elbow=False,
        **kwargs,
    ):
        super().__init__(**kwargs)
        self.lines = (line1, line2)
        self.quadrant = quadrant
        self.dot_distance = dot_distance
        self.elbow = elbow
        inter = line_intersection(
            [line1.get_start(), line1.get_end()],
            [line2.get_start(), line2.get_end()],
        )

        if radius is None:
            if quadrant[0] == 1:
                dist_1 = np.linalg.norm(line1.get_end() - inter)
            else:
                dist_1 = np.linalg.norm(line1.get_start() - inter)
            if quadrant[1] == 1:
                dist_2 = np.linalg.norm(line2.get_end() - inter)
            else:
                dist_2 = np.linalg.norm(line2.get_start() - inter)
            if np.minimum(dist_1, dist_2) < 0.6:
                radius = (2 / 3) * np.minimum(dist_1, dist_2)
            else:
                radius = 0.4
        else:
            self.radius = radius

        anchor_angle_1 = inter + quadrant[0] * radius * line1.get_unit_vector()
        anchor_angle_2 = inter + quadrant[1] * radius * line2.get_unit_vector()

        if elbow:
            anchor_middle = (inter +
                             quadrant[0] * radius * line1.get_unit_vector() +
                             quadrant[1] * radius * line2.get_unit_vector())
            angle_mobject = Elbow(**kwargs)
            angle_mobject.set_points_as_corners(
                [anchor_angle_1, anchor_middle, anchor_angle_2], )
        else:
            angle_1 = angle_of_vector(anchor_angle_1 - inter)
            angle_2 = angle_of_vector(anchor_angle_2 - inter)

            if not other_angle:
                start_angle = angle_1
                if angle_2 > angle_1:
                    angle_fin = angle_2 - angle_1
                else:
                    angle_fin = 2 * np.pi - (angle_1 - angle_2)
            else:
                start_angle = angle_1
                if angle_2 < angle_1:
                    angle_fin = -angle_1 + angle_2
                else:
                    angle_fin = -2 * np.pi + (angle_2 - angle_1)

            self.angle_value = angle_fin

            angle_mobject = Arc(
                radius=radius,
                angle=self.angle_value,
                start_angle=start_angle,
                arc_center=inter,
                **kwargs,
            )

            if dot:
                if dot_radius is None:
                    dot_radius = radius / 10
                else:
                    self.dot_radius = dot_radius
                right_dot = Dot(ORIGIN, radius=dot_radius, color=dot_color)
                dot_anchor = (
                    inter + (angle_mobject.get_center() - inter) /
                    np.linalg.norm(angle_mobject.get_center() - inter) *
                    radius * dot_distance)
                right_dot.move_to(dot_anchor)
                self.add(right_dot)

        self.set_points(angle_mobject.points)