
    lj0(                    6   d Z ddlmZ ddlmZmZ ddlZddlm	Z
 ddlmZmZmZmZmZ ddlmZ ddlmZ dd	lmZ er
dd
lmZmZmZ ddlmZ g dZ G d dee          Z G d de          Z G d de          Z G d de          Z  G d de          Z!dS )z0Boolean operations for two-dimensional mobjects.    )annotations)TYPE_CHECKINGAnyN)Path)PathVerb
differenceintersectionunionxor)config)ConvertToOpenGL)VMobject)Point2DLike_ArrayPoint3D_ArrayPoint3DLike_Array   )RendererType)UnionIntersection
Difference	Exclusionc                  .    e Zd ZdZ	 ddd	ZddZddZdS )_BooleanOpszThis class contains some helper functions which
    helps to convert to and from skia objects and manim
    objects (:class:`~.VMobject`).
            points%Point2DLike_Array | Point3DLike_Arrayz_dimfloatreturnr   c                    t          |          }t          |          D ]0\  }}t          |          dk    rt          j        ||          ||<   1t          j        |          S )a3  Converts an iterable with coordinates in 2D to 3D by adding
        :attr:`z_dim` as the Z coordinate.

        Parameters
        ----------
        points
            An iterable of points.
        z_dim
            Default value for the Z coordinate.

        Returns
        -------
        Point3D_Array
            A list of the points converted to 3D.

        Example
        -------
        >>> a = _BooleanOps()
        >>> p = [(1, 2), (3, 4)]
        >>> a._convert_2d_to_3d_array(p)
        array([[1., 2., 0.],
               [3., 4., 0.]])
           )list	enumeratelennpappendasarray)selfr   r   list_of_pointsipoints         ]/home/agentuser/manim-venv/lib/python3.11/site-packages/manim/mobject/geometry/boolean_ops.py_convert_2d_to_3d_arrayz#_BooleanOps._convert_2d_to_3d_array   s`    8 f!.11 	< 	<HAu5zzQ$&IeU$;$;q!z.)))    vmobjectr   SkiaPathc                   t                      }t          j        t          j        |j                            r|j        }nt          j        d          }t          |          dk    r|S t          j        t          j
        k    r|                    |          }|D ]}|                    |          }|d         } |j        |dd           |D ]%\  }}	}
 |j        g |	dd         |
dd         R   &|                    |d         |d                   r|                                 nt          j        t          j        k    r|                    |          }|D ]}|                    |          }|d         } |j        |dd           |D ]0\  }}	}
} |j        g |	dd         |
dd         |dd         R   1|                    |d         |d                   r|                                 |S )a[  Converts a :class:`~.VMobject` to SkiaPath. This method only works for
        cairo renderer because it treats the points as Cubic beizer curves.

        Parameters
        ----------
        vmobject:
            The :class:`~.VMobject` to convert from.

        Returns
        -------
        SkiaPath
            The converted path.
        )   r   r   Nr!   )r0   r%   allisfiniter   zerosr$   r   rendererr   OPENGLget_subpaths_from_pointsget_bezier_tuples_from_pointsmoveToquadToconsider_points_equalscloseCAIROgen_subpaths_from_points_2d#gen_cubic_bezier_tuples_from_pointscubicToconsider_points_equals_2d)r(   r/   pathr   subpathssubpathquadsstart_p0p1p2p3s               r,   _convert_vmobject_to_skia_pathz*_BooleanOps._convert_vmobject_to_skia_path?   s&    zz6"+ho..// 	&_FFXf%%Fv;;!K ?l11188@@H# ! ! >>wGG
U2A2Y''#( 2 2KCRDK1BQB1"RaR&111112271:wr{KK !JJLLL! _ 222;;FCCH# ! ! DDWMM
U2A2Y''', < <OCR DL;"RaR&;2bqb6;BrrF;;;;;55gaj'"+NN !JJLLLr.   rD   c                   | }t          j        g d          }|D ]@\  }}|t          j        k    r2|                     |          }|D ]}|}|                    |           H|t          j        k    r1|                     |          \  }}	}
|                    ||	|
           |t          j        k    r1|                     |          }|	                    |d                    |t          j
        k    r|	                    |           |t          j        k    r0|                     |          \  }}	|                    ||	           0t          d|           |S )zConverts SkiaPath back to VMobject.
        Parameters
        ----------
        path:
            The SkiaPath to convert.

        Returns
        -------
        VMobject:
            The converted VMobject.
        )r   r   r   r   zUnsupported: )r%   arrayr   MOVEr-   start_new_pathCUBICadd_cubic_bezier_curve_toLINEadd_line_toCLOSEQUADadd_quadratic_bezier_curve_to	Exception)r(   rD   r/   current_path_start	path_verbr   partspartn1n2n3s              r,   _convert_skia_path_to_vmobjectz*_BooleanOps._convert_skia_path_to_vmobjectp   s~    Xiii00!% 	= 	=IvHM))44V<<! 2 2D)-&++D11112 hn,,!99&AA
B222r2>>>>hm++44V<<$$U1X....hn,,$$%78888hm++55f==B66r2>>>> ;	 ; ;<<<r.   N)r   )r   r   r   r   r   r   )r/   r   r   r0   )rD   r0   r   r   )__name__
__module____qualname____doc__r-   rM   ra    r.   r,   r   r      sf           *  *  *  *  *D/ / / /b# # # # # #r.   r   )	metaclassc                  $     e Zd ZdZd	 fdZ xZS )
r   a  Union of two or more :class:`~.VMobject` s. This returns the common region of
    the :class:`~VMobject` s.

    Parameters
    ----------
    vmobjects
        The :class:`~.VMobject` s to find the union of.

    Raises
    ------
    ValueError
        If less than 2 :class:`~.VMobject` s are passed.

    Example
    -------
    .. manim:: UnionExample
        :save_last_frame:

        class UnionExample(Scene):
            def construct(self):
                sq = Square(color=RED, fill_opacity=1)
                sq.move_to([-2, 0, 0])
                cr = Circle(color=BLUE, fill_opacity=1)
                cr.move_to([-1.3, 0.7, 0])
                un = Union(sq, cr, color=GREEN, fill_opacity=1)
                un.move_to([1.5, 0.3, 0])
                self.add(sq, cr, un)

    	vmobjectsr   kwargsr   r   Nonec                &    t          |          dk     rt          d           t                      j        di |  fd|D             }t	                      }t          ||                                                                |           d S )Nr!   z%At least 2 mobjects needed for Union.c                :    g | ]}                     |          S rf   )rM   ).0r/   r(   s     r,   
<listcomp>z"Union.__init__.<locals>.<listcomp>   s4     
 
 
>FD//99
 
 
r.   rf   )r$   
ValueErrorsuper__init__r0   r
   getPenra   )r(   ri   rj   pathsoutpen	__class__s   `    r,   rr   zUnion.__init__   s    y>>ADEEE""6"""
 
 
 
JS
 
 
 eV]]__%%%++F33333r.   ri   r   rj   r   r   rk   rb   rc   rd   re   rr   __classcell__rv   s   @r,   r   r      sG         <	4 	4 	4 	4 	4 	4 	4 	4 	4 	4r.   r   c                  $     e Zd ZdZd
 fd	Z xZS )r   a  Subtracts one :class:`~.VMobject` from another one.

    Parameters
    ----------
    subject
        The 1st :class:`~.VMobject`.
    clip
        The 2nd :class:`~.VMobject`

    Example
    -------
    .. manim:: DifferenceExample
        :save_last_frame:

        class DifferenceExample(Scene):
            def construct(self):
                sq = Square(color=RED, fill_opacity=1)
                sq.move_to([-2, 0, 0])
                cr = Circle(color=BLUE, fill_opacity=1)
                cr.move_to([-1.3, 0.7, 0])
                un = Difference(sq, cr, color=GREEN, fill_opacity=1)
                un.move_to([1.5, 0, 0])
                self.add(sq, cr, un)

    subjectr   cliprj   r   r   rk   c                    t                      j        di | t                      }t          |                     |          g|                     |          g|                                           |                     |           d S Nrf   )rq   rr   r0   r   rM   rs   ra   r(   r|   r}   rj   ru   rv   s        r,   rr   zDifference.__init__   s    ""6"""0099:00667MMOO	
 	
 	

 	++F33333r.   r|   r   r}   r   rj   r   r   rk   rx   rz   s   @r,   r   r      sG         44 4 4 4 4 4 4 4 4 4r.   r   c                  $     e Zd ZdZd	 fdZ xZS )
r   a3  Find the intersection of two :class:`~.VMobject` s.
    This keeps the parts covered by both :class:`~.VMobject` s.

    Parameters
    ----------
    vmobjects
        The :class:`~.VMobject` to find the intersection.

    Raises
    ------
    ValueError
        If less the 2 :class:`~.VMobject` are passed.

    Example
    -------
    .. manim:: IntersectionExample
        :save_last_frame:

        class IntersectionExample(Scene):
            def construct(self):
                sq = Square(color=RED, fill_opacity=1)
                sq.move_to([-2, 0, 0])
                cr = Circle(color=BLUE, fill_opacity=1)
                cr.move_to([-1.3, 0.7, 0])
                un = Intersection(sq, cr, color=GREEN, fill_opacity=1)
                un.move_to([1.5, 0, 0])
                self.add(sq, cr, un)

    ri   r   rj   r   r   rk   c                R   t          |          dk     rt          d           t                      j        di | t	                      }t          |                     |d                   g|                     |d                   g|                                           |}t          dt          |                    D ]P}t	                      }t          |g|                     ||                   g|                                           |}Q| 	                    |           d S )Nr!   z,At least 2 mobjects needed for Intersection.r   r2   rf   )
r$   rp   rq   rr   r0   r	   rM   rs   rangera   )r(   ri   rj   ru   
new_outpen_irv   s         r,   rr   zIntersection.__init__  s&   y>>AKLLL""6"""001>>?001>>?MMOO	
 	
 	

 
3y>>** 	  	 B!J44Yr]CCD!!##  
  FF++F33333r.   rw   rx   rz   s   @r,   r   r      sG         <4 4 4 4 4 4 4 4 4 4r.   r   c                  $     e Zd ZdZd
 fd	Z xZS )r   a  Find the XOR between two :class:`~.VMobject`.
    This creates a new :class:`~.VMobject` consisting of the region
    covered by exactly one of them.

    Parameters
    ----------
    subject
        The 1st :class:`~.VMobject`.
    clip
        The 2nd :class:`~.VMobject`

    Example
    -------
    .. manim:: IntersectionExample
        :save_last_frame:

        class IntersectionExample(Scene):
            def construct(self):
                sq = Square(color=RED, fill_opacity=1)
                sq.move_to([-2, 0, 0])
                cr = Circle(color=BLUE, fill_opacity=1)
                cr.move_to([-1.3, 0.7, 0])
                un = Exclusion(sq, cr, color=GREEN, fill_opacity=1)
                un.move_to([1.5, 0.4, 0])
                self.add(sq, cr, un)

    r|   r   r}   rj   r   r   rk   c                    t                      j        di | t                      }t          |                     |          g|                     |          g|                                           |                     |           d S r   )rq   rr   r0   r   rM   rs   ra   r   s        r,   rr   zExclusion.__init__;  s    ""6"""0099:00667MMOO	
 	
 	

 	++F33333r.   r   rx   rz   s   @r,   r   r     sG         84 4 4 4 4 4 4 4 4 4r.   r   )"re   
__future__r   typingr   r   numpyr%   pathopsr   r0   r   r   r	   r
   r   manimr   )manim.mobject.opengl.opengl_compatibilityr   &manim.mobject.types.vectorized_mobjectr   manim.typingr   r   r   	constantsr   __all__r   r   r   r   r   rf   r.   r,   <module>r      s   6 6 " " " " " " % % % % % % % %     $ $ $ $ $ $ B B B B B B B B B B B B B B       E E E E E E ; ; ; ; ; ; QPPPPPPPPPP % % % % % %
>
>
>| | | | |(o | | | |~(4 (4 (4 (4 (4K (4 (4 (4V#4 #4 #4 #4 #4 #4 #4 #4L44 44 44 44 44; 44 44 44n%4 %4 %4 %4 %4 %4 %4 %4 %4 %4r.   