Source code for manim_extensions.compass.animations.animation_compass

__all__ = [
    'DrawArc',
    'MoveNiddleTipTo',
    'RotateCompass',
    'SplitCompass',
    'PutCompass',
    'PutCompassAway'
]
# from manim import *
import numpy as np
from manim.mobject.geometry.arc import Arc
from manim.mobject.geometry.line import Line
from manim.mobject.types.point_cloud_mobject import Point
from manim.animation.composition import AnimationGroup
from manim.animation.transform import ApplyMethod
from manim.animation.rotation import Rotate
from manim.animation.creation import Create
from manim.constants import RIGHT, LEFT, UP, DOWN

from ..compass import Compass
from ..utils.geometry_method import (
    get_vecs_angle,
    get_distance,
    is_counter_clockwise
)

[docs] class DrawArc(AnimationGroup): '''Compass-and-straightedge animation: draw an arc. .. manim:: DrawArcDocExample from manim import * from manim_extensions.compass import Compass, DrawArc from manim.mobject.geometry.arc import Arc class DrawArcDocExample(Scene): def construct(self): compass = Compass().to_edge(LEFT) arc = Arc(arc_center=ORIGIN, radius=1, angle=PI / 2) self.play(DrawArc(compass, arc)) self.wait() '''
[docs] def __init__( self, compass:Compass, arc:Arc, **kwargs ): ''' Compass-and-straightedge animation: draw an arc. Note: before this animation, move the compass needle tip (niddle_tip) to the centre of the arc, and move the compass pen tip to the start of the arc. Parameters ---------- compass : Compass The compass. arc : Arc The arc to draw. ''' super().__init__( Create(arc), RotateCompass(compass,arc.angle), **kwargs )
[docs] class SplitCompass(AnimationGroup): '''Compass-and-straightedge animation: rotate the two legs of the compass .. manim:: SplitCompassDocExample from manim import * from manim_extensions.compass import Compass, SplitCompass class SplitCompassDocExample(Scene): def construct(self): compass = Compass().to_edge(LEFT) self.play(SplitCompass(compass, 2)) self.wait() '''
[docs] def __init__( self, compass:Compass, span:float = None, **kwargs ): ''' Compass-and-straightedge animation: rotate the two legs of the compass uniformly outward (or inward) so that the distance between the tips is span. The niddle_tip stays fixed. Parameters ---------- compass : Compass The compass. span : float The distance between the two compass tips. ''' theta_new, theta_old = np.arcsin(span/2/compass.leg_length), compass.theta compass.theta = theta_new rotate_angle = theta_old - theta_new if is_counter_clockwise( compass.get_niddle_tip() - compass.c.get_center(), compass.get_pen_tip() - compass.c.get_center() ): rotate_angle = -rotate_angle super().__init__( Rotate( compass.head, about_point = compass.c.get_center(), angle = rotate_angle ), Rotate( compass.pen_tip, about_point = compass.c.get_center(), angle = 2*rotate_angle ), **kwargs )
[docs] class RotateCompass(Rotate): '''Compass-and-straightedge animation: rotate the compass around its needle tip by angle. .. manim:: RotateCompassDocExample from manim import * from manim_extensions.compass import Compass, RotateCompass class RotateCompassDocExample(Scene): def construct(self): compass = Compass().to_edge(LEFT) self.play(RotateCompass(compass, PI / 2)) self.wait() '''
[docs] def __init__( self, compass:Compass, angle:float = None, **kwargs ): ''' Compass-and-straightedge animation: rotate the compass around its needle tip by angle. Parameters ---------- compass : Compass The compass. angle : float The rotation angle. ''' super().__init__( compass, about_point = compass.get_niddle_tip(), angle = angle, **kwargs )
[docs] class MoveNiddleTipTo(ApplyMethod): '''Compass-and-straightedge animation: move the compass so that its needle tip is placed at point. .. manim:: MoveNiddleTipToDocExample from manim import * from manim_extensions.compass import Compass, MoveNiddleTipTo class MoveNiddleTipToDocExample(Scene): def construct(self): compass = Compass().to_edge(LEFT) self.play(MoveNiddleTipTo(compass, ORIGIN)) self.wait() '''
[docs] def __init__( self, compass:Compass, point:Point = None, **kwargs ): ''' Compass-and-straightedge animation: move the compass so that its needle tip is placed at point. Parameters ---------- compass : Compass The compass. point : Point The target point. ''' super().__init__( compass.move_niddle_tip_to, point, **kwargs )
[docs] class PutCompass(ApplyMethod): '''Compass-and-straightedge animation: place the compass's niddle_tip and pen_tip at the given positions. .. manim:: PutCompassDocExample from manim import * from manim_extensions.compass import Compass, PutCompass class PutCompassDocExample(Scene): def construct(self): compass = Compass().to_edge(LEFT) self.play(PutCompass(compass, ORIGIN, 2 * RIGHT)) self.wait() '''
[docs] def __init__( self, compass:Compass, niddle_pos:Point = None, pen_pos:Point = None, **kwargs ): ''' Compass-and-straightedge animation: place the compass's niddle_tip and pen_tip at the given positions. Parameters ---------- compass : Compass The compass. niddle_pos : Point Position for niddle_tip. pen_pos : Point Position for pen_tip. ''' arc_radius = get_distance(niddle_pos,pen_pos) if arc_radius > compass.leg_length*2: raise ValueError("The span exceeds the compass drawing range.") span_angle = compass.get_compass_rotate_angle_with_span(arc_radius) rotate_angle = get_vecs_angle( compass.get_niddle2pen_vec(), Line(niddle_pos,pen_pos).get_unit_vector() ) super().__init__( compass.set_compass, span_angle/2, rotate_angle, niddle_pos, **kwargs )
[docs] class PutCompassAway(PutCompass): '''Compass-and-straightedge animation: put the compass aside at point, with the two tips separated by span_buff. .. manim:: PutCompassAwayDocExample from manim import * from manim_extensions.compass import Compass, PutCompassAway class PutCompassAwayDocExample(Scene): def construct(self): compass = Compass().to_edge(LEFT) self.play(PutCompassAway(compass, 2 * RIGHT)) self.wait() '''
[docs] def __init__( self, compass:Compass, point:Point = RIGHT, span_buff:float = 0.1, **kwargs ): ''' Compass-and-straightedge animation: put the compass aside at point, with the two tips separated by span_buff. Parameters ---------- compass : Compass The compass. point : Point Position to place the compass. span_buff : float Distance between the two tips when placed aside. ''' r = 0.5*compass.leg_length vec = r*DOWN if compass.get_compass_rotate_angle_direction() else r*UP super().__init__( compass, niddle_pos = point + span_buff*LEFT + vec, pen_pos = point + span_buff*RIGHT + vec, **kwargs )