
    lj&                        d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZmZmZ dd	lmZ dd
lmZmZ ddlmZ erddlmZ dgZ G d de          ZdS )zAUtilities for modifying the speed at which animations are played.    )annotationsN)Callable)TYPE_CHECKING)	piecewise   )	AnimationWaitprepare_animation)AnimationGroup)Mobject_AnimationBuilder)Scene)UpdaterChangeSpeedc                       e Zd ZdZdZdZ	 	 d&d' fdZd Zd(dZe		 	 d)d*d            Z
d+dZd,dZd-d Zd-d!Zd.d$Zd-d%Z xZS )/r   a  Modifies the speed of passed animation.
    :class:`AnimationGroup` with different ``lag_ratio`` can also be used
    which combines multiple animations into one.
    The ``run_time`` of the passed animation is changed to modify the speed.

    Parameters
    ----------
    anim
        Animation of which the speed is to be modified.
    speedinfo
        Contains nodes (percentage of ``run_time``) and its corresponding speed factor.
    rate_func
        Overrides ``rate_func`` of passed animation, applied before changing speed.

    Examples
    --------

    .. manim:: SpeedModifierExample

        class SpeedModifierExample(Scene):
            def construct(self):
                a = Dot().shift(LEFT * 4)
                b = Dot().shift(RIGHT * 4)
                self.add(a, b)
                self.play(
                    ChangeSpeed(
                        AnimationGroup(
                            a.animate(run_time=1).shift(RIGHT * 8),
                            b.animate(run_time=1).shift(LEFT * 8),
                        ),
                        speedinfo={0.3: 1, 0.4: 0.1, 0.6: 0.1, 1: 1},
                        rate_func=linear,
                    )
                )

    .. manim:: SpeedModifierUpdaterExample

        class SpeedModifierUpdaterExample(Scene):
            def construct(self):
                a = Dot().shift(LEFT * 4)
                self.add(a)

                ChangeSpeed.add_updater(a, lambda x, dt: x.shift(RIGHT * 4 * dt))
                self.play(
                    ChangeSpeed(
                        Wait(2),
                        speedinfo={0.4: 1, 0.5: 0.2, 0.8: 0.2, 1: 1},
                        affects_speed_updaters=True,
                    )
                )

    .. manim:: SpeedModifierUpdaterExample2

        class SpeedModifierUpdaterExample2(Scene):
            def construct(self):
                a = Dot().shift(LEFT * 4)
                self.add(a)

                ChangeSpeed.add_updater(a, lambda x, dt: x.shift(RIGHT * 4 * dt))
                self.wait()
                self.play(
                    ChangeSpeed(
                        Wait(),
                        speedinfo={1: 0},
                        affects_speed_updaters=True,
                    )
                )

    r   FNTanimAnimation | _AnimationBuilder	speedinfodict[float, float]	rate_funcCallable[[float], float] | Noneaffects_speed_updatersboolreturnNonec                    t          t          |          t                    rJ t          |          t           j        |j                  |j        |j        |j        |j	        d _
        n                     |           _
        |r+t          j        du s
J d            dt          _        d _        | _        | j
        j        n| _        d  _        d  _        d|vrd|d<   d|vr0t#          |                                          d	         d         |d<   t'          t#          |                                                     _        g  _        g  _                                         d} j        d         }d}t1           j                                                  dd          D ]u\  }	}
|	|z
  }|||
|f fd
	} j                            |           |||
||f fd	} j                            |           |                     ||
          |z  z  }|	}|
}v fd} j
                            |            t7                      j         j
        j        f j         j
        j        z  d| d S )N)grouprun_timer   	lag_ratioFzVOnly one animation at a time can play that changes speed (dt) for ChangeSpeed updatersTr   c                6    |dz  |dz  z
  | dz  z  dz  || z  z   S )Nr       )x
init_speedfinal_speeds      X/home/agentuser/manim-venv/lib/python3.11/site-packages/manim/animation/speedmodifier.py<lambda>z&ChangeSpeed.__init__.<locals>.<lambda>   s.    !^j!m+q!t3a7*q.H     c                    d| |z   z  S )Nr   r"   )r$   r%   s     r&   r'   z&ChangeSpeed.__init__.<locals>.<lambda>   s    qJ<T7U r(      c                l    |z  }|                     ||          |z  z   z  }|| cxk    o|k    nc S N)f_inv_1)	t	curr_timer$   r%   durlower_boundupper_boundscaled_total_timeselfs	          r&   	conditionz'ChangeSpeed.__init__.<locals>.condition   sY     (*;;Z E E KK%& #a6666;66666r(   c                P                         | z  |z
  |z  ||          |z  |z   S r-   )speed_modifier)r/   r0   r$   r%   r1   prevnoder4   r5   s         r&   functionz&ChangeSpeed.__init__.<locals>.function   sI     ''*Q.:cA"# 
  r(   c                     dk    rdt           _        t                                          fdj        D             j                  }j        r(|j        z
  j        j	        z  t           _
        |_        |S )Nr*   Fc                L    g | ] } |                                         !S r"   r   ).0r6   r5   r/   s     r&   
<listcomp>z6ChangeSpeed.__init__.<locals>.func.<locals>.<listcomp>   s/    OOO)4>>!,,--OOOr(   )r   is_changing_dtr   r   
conditions	functionsr   r/   r   r   dt)r/   new_tr5   s   ` r&   funcz"ChangeSpeed.__init__.<locals>.func   s    Avv-2*q!!OOOOOtOOO E
 * "'$&.DI4F!FLr(   )r   r   )
issubclasstyper   mapsetup
animationsr   r   r   r   r   r   r@   r/   r   r8   r.   sorteditemsdictr   rB   rA   get_scaled_total_timelistappendset_rate_funcsuper__init__mobject)r5   r   r   r   r   kwargsr9   r$   r0   noder%   r1   r6   r:   rE   r4   	__class__s   `              @r&   rS   zChangeSpeed.__init__a   s    d4jj.11 		)"T

TZ11j..  DII 

4((DI! 	-666h 766 *.K&DF&<#090A,,y
 

 VU IIaLI!)//"3"344R8;IaLfY__%6%67788 !6688^A&
	!%dn&:&:&<&<!=!=abb!A (	% (	%D+/C $%'7 7 7 7 7 7 7 O""9--- $%'!      $ N!!(+++j+>>DDIH$JJ	 	 	 	 	 		%%%I	
n&);;	
 	
 		
 	
 	
 	
 	
r(   c                    t          |          t          u rt          j        d |          |_        t          |          S )Nc                ,    |                      |          S r-   r=   r5   alphas     r&   r'   z#ChangeSpeed.setup.<locals>.<lambda>   s    DNN5$9$9 r(   )rG   r	   types
MethodTypeinterpolater
   )r5   r   s     r&   rI   zChangeSpeed.setup   s@    ::$/994   D !&&&r(   floatc                    d}| j         d         }d}t          | j                                                   dd         D ]*\  }}||z
  }|||                     ||          z  z  }|}|}+|S )zPThe time taken by the animation under the assumption that the ``run_time`` is 1.r   r*   N)r   rO   rL   r.   )r5   r9   r$   
total_timerV   r%   r1   s          r&   rN   z!ChangeSpeed.get_scaled_total_time   s    ^A&

!%dn&:&:&<&<!=!=abb!A 	% 	%D+/C#Z E EEEJH$JJr(   rT   r   update_functionr   index
int | Nonecall_updaterc                    dt          j                  j        v r|                    fd||           dS |                    ||           dS )a  This static method can be used to apply speed change to updaters.

        This updater will follow speed and rate function of any :class:`.ChangeSpeed`
        animation that is playing with ``affects_speed_updaters=True``. By default,
        updater functions added via the usual :meth:`.Mobject.add_updater` method
        do not respect the change of animation speed.

        Parameters
        ----------
        mobject
            The mobject to which the updater should be attached.
        update_function
            The function that is called whenever a new frame is rendered.
        index
            The position in the list of the mobject's updaters at which the
            function should be inserted.
        call_updater
            If ``True``, calls the update function when attaching it to the
            mobject.

        See also
        --------
        :class:`.ChangeSpeed`
        :meth:`.Mobject.add_updater`
        rC   c                L     | t           j        rt           j        n|          S r-   )r   r@   rC   )mobrC   rb   s     r&   r'   z)ChangeSpeed.add_updater.<locals>.<lambda>  s&    ;+EM2! ! r(   )rc   re   N)inspect	signature
parametersadd_updater)clsrT   rb   rc   re   s     `  r&   rl   zChangeSpeed.add_updater   s    B 7$_55@@@    )        u<XXXXXr(   r[   c                :    | j                             |           d S r-   )r   r^   rZ   s     r&   r^   zChangeSpeed.interpolate  s    	e$$$$$r(   rC   c                :    | j                             |           d S r-   )r   update_mobjects)r5   rC   s     r&   rp   zChangeSpeed.update_mobjects  s    	!!"%%%%%r(   c                P    dt           _        | j                                         d S NF)r   r@   r   finishr5   s    r&   rs   zChangeSpeed.finish  s$    %*"	r(   c                8    | j                                          d S r-   )r   beginrt   s    r&   rv   zChangeSpeed.begin!  s    	r(   scener   c                :    | j                             |           d S r-   )r   clean_up_from_scener5   rw   s     r&   ry   zChangeSpeed.clean_up_from_scene$  s    	%%e,,,,,r(   c                :    | j                             |           d S r-   )r   _setup_scenerz   s     r&   r|   zChangeSpeed._setup_scene'  s    	u%%%%%r(   )NT)
r   r   r   r   r   r   r   r   r   r   )r   r_   rr   )rT   r   rb   r   rc   rd   re   r   )r[   r_   r   r   )rC   r_   r   r   )r   r   )rw   r   r   r   )__name__
__module____qualname____doc__rC   r@   rS   rI   rN   classmethodrl   r^   rp   rs   rv   ry   r|   __classcell__)rW   s   @r&   r   r      s9       D DL 
BN 6:'+u
 u
 u
 u
 u
 u
 u
n' ' '
 
 
 
 
 !")Y )Y )Y )Y [)YV% % % %& & & &      - - - -& & & & & & & &r(   )r   
__future__r   ri   r\   collections.abcr   typingr   numpyr   animation.animationr   r	   r
   animation.compositionr   mobject.mobjectr   r   scene.scener   r   __all__r   r"   r(   r&   <module>r      s   G G " " " " " "   $ $ $ $ $ $                   D D D D D D D D D D 2 2 2 2 2 2 8 8 8 8 8 8 8 8       *))))))/Q& Q& Q& Q& Q&) Q& Q& Q& Q& Q&r(   