
    lj>=                    F   d Z ddlm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 ddlmZ dd	lmZ dd
lmZ erddlmZ ddlmZmZ g dZ G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          ZdS )z-General polyhedral class and platonic solids.    )annotations)Hashable)TYPE_CHECKINGAnyN)Polygon)Graph)Dot3D)VGroup)	QuickHull)Mobject)Point3DPoint3DLike_Array)
PolyhedronTetrahedron
OctahedronIcosahedronDodecahedronConvexHull3Dc                  J     e Zd ZdZi i fd fd
ZddZddZddZddZ xZ	S )r   a:  An abstract polyhedra class.

    In this implementation, polyhedra are defined with a list of vertex coordinates in space, and a list
    of faces. This implementation mirrors that of a standard polyhedral data format (OFF, object file format).

    Parameters
    ----------
    vertex_coords
        A list of coordinates of the corresponding vertices in the polyhedron. Each coordinate will correspond to
        a vertex. The vertices are indexed with the usual indexing of Python.
    faces_list
        A list of faces. Each face is a sublist containing the indices of the vertices that form the corners of that face.
    faces_config
        Configuration for the polygons representing the faces of the polyhedron.
    graph_config
        Configuration for the graph containing the vertices and edges of the polyhedron.

    Examples
    --------
    To understand how to create a custom polyhedra, let's use the example of a rather simple one - a square pyramid.

    .. manim:: SquarePyramidScene
        :save_last_frame:

        class SquarePyramidScene(ThreeDScene):
            def construct(self):
                self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
                vertex_coords = [
                    [1, 1, 0],
                    [1, -1, 0],
                    [-1, -1, 0],
                    [-1, 1, 0],
                    [0, 0, 2]
                ]
                faces_list = [
                    [0, 1, 4],
                    [1, 2, 4],
                    [2, 3, 4],
                    [3, 0, 4],
                    [0, 1, 2, 3]
                ]
                pyramid = Polyhedron(vertex_coords, faces_list)
                self.add(pyramid)

    In defining the polyhedron above, we first defined the coordinates of the vertices.
    These are the corners of the square base, given as the first four coordinates in the vertex list,
    and the apex, the last coordinate in the list.

    Next, we define the faces of the polyhedron. The triangular surfaces of the pyramid are polygons
    with two adjacent vertices in the base and the vertex at the apex as corners. We thus define these
    surfaces in the first four elements of our face list. The last element defines the base of the pyramid.

    The graph and faces of polyhedra can also be accessed and modified directly, after instantiation.
    They are stored in the `graph` and `faces` attributes respectively.

    .. manim:: PolyhedronSubMobjects
        :save_last_frame:

        class PolyhedronSubMobjects(ThreeDScene):
            def construct(self):
                self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
                octahedron = Octahedron(edge_length = 3)
                octahedron.graph[0].set_color(RED)
                octahedron.faces[2].set_color(YELLOW)
                self.add(octahedron)
    vertex_coordsr   
faces_listlist[list[int]]faces_config#dict[str, str | int | float | bool]graph_configdict[str, Any]c                    t                                                       t          dddfi | _        t          t          ddidfi | _        | _        t          t          t           j                                       _
        t          t           j                             _        | _         fd|D              _                              j                   _                              j                   _        t'           j
         j        fd j        i j         _                              j         j                                         j                   d S )	N      ?T)fill_opacityshade_in_3dstroke_opacityr   )vertex_typeedge_configc                ,    g | ]}fd |D             S )c                *    g | ]}j         |         S  )layout).0jselfs     Z/home/agentuser/manim-venv/lib/python3.11/site-packages/manim/mobject/three_d/polyhedra.py
<listcomp>z2Polyhedron.__init__.<locals>.<listcomp>.<listcomp>z   s    777T[^777    r&   )r(   ir*   s     r+   r,   z'Polyhedron.__init__.<locals>.<listcomp>z   s.    LLLA7777Q777LLLr-   r'   )super__init__dictr   r	   r   r   listrangelenvertex_indices	enumerater'   r   face_coords	get_edgesedgescreate_facesfacesr   graphaddadd_updaterupdate_faces)r*   r   r   r   r   	__class__s   `    r+   r0   zPolyhedron.__init__b   s    	  66
 
:F
 
 !$$a  
 
 
 
 +"5T-?)@)@#A#ABB+/	$:L0M0M+N+N$LLLLLLL^^DO44
&&t'788

 
48K
CGCT
 

 	TZ(((*+++++r-   returnlist[tuple[int, int]]c           	     d    g }|D ]*}|t          ||dd         |dd         z   d          z  }+|S )z'Creates list of cyclic pairwise tuples.   NT)strict)zip)r*   r   r9   faces       r+   r8   zPolyhedron.get_edges   sM    ') 	A 	ADStABBx$rr(24@@@@EEr-   r7   r
   c                t    t                      }|D ]&}|                    t          |i | j                   '|S )z8Creates VGroup of faces from a list of face coordinates.)r
   r=   r   r   )r*   r7   
face_grouprG   s       r+   r:   zPolyhedron.create_faces   sI    
 XX
 	@ 	@DNN7D>D,=>>????r-   mr   Nonec                    |                                  }|                     |          }| j                            |           d S )N)extract_face_coordsr:   r;   match_points)r*   rJ   r7   	new_facess       r+   r?   zPolyhedron.update_faces   sB    ..00%%k22	
	*****r-   c                      fd j         j        D             }t          t          |                    fd j        D             S )z`Extracts the coordinates of the vertices in the graph.
        Used for updating faces.
        c                N    g | ]!}j         |                                         "S r&   )r<   
get_center)r(   vr*   s     r+   r,   z2Polyhedron.extract_face_coords.<locals>.<listcomp>   s+    UUUATZ]5577UUUr-   c                ,    g | ]}fd |D             S )c                     g | ]
}|         S r&   r&   )r(   r)   r'   s     r+   r,   z=Polyhedron.extract_face_coords.<locals>.<listcomp>.<listcomp>   s    &&&q&&&r-   r&   )r(   r.   r'   s     r+   r,   z2Polyhedron.extract_face_coords.<locals>.<listcomp>   s.    @@@1&&&&A&&&@@@r-   )r<   verticesr1   r6   r   )r*   new_vertex_coordsr'   s   ` @r+   rM   zPolyhedron.extract_face_coords   sX     VUUUATUUUi 12233@@@@@@@@r-   )r   r   r   r   r   r   r   r   )r   r   rA   rB   )r7   r   rA   r
   )rJ   r   rA   rK   )rA   r   )
__name__
__module____qualname____doc__r0   r8   r:   r?   rM   __classcell__r@   s   @r+   r   r      s        A AN =?'), , , , , , ,B      + + + +
A A A A A A A Ar-   r   c                  &     e Zd ZdZdd	 fdZ xZS )
r   a  A tetrahedron, one of the five platonic solids. It has 4 faces, 6 edges, and 4 vertices.

    Parameters
    ----------
    edge_length
        The length of an edge between any two vertices.

    Examples
    --------

    .. manim:: TetrahedronScene
        :save_last_frame:

        class TetrahedronScene(ThreeDScene):
            def construct(self):
                self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
                obj = Tetrahedron()
                self.add(obj)
    rD   edge_lengthfloatkwargsr   c                H   |t          j        d          z  dz  } t                      j        dt          j        |||g          t          j        || | g          t          j        | || g          t          j        | | |g          gg dg dg dg dgd| d S )	N      )r   rD   rc   )   r   rc   )r   rD   re   )re   rD   rc   r   r   r&   npsqrtr/   r0   arrayr*   r_   ra   unitr@   s       r+   r0   zTetrahedron.__init__   s    RWQZZ'!+ 		
$d+,,$u-..4%u-..4%$-..	 "		999iiiC		
 		
 		
 		
 		
 		
 		
r-   rD   r_   r`   ra   r   rX   rY   rZ   r[   r0   r\   r]   s   @r+   r   r      sL         (
 
 
 
 
 
 
 
 
 
 
r-   r   c                  &     e Zd ZdZdd	 fdZ xZS )
r   a  An octahedron, one of the five platonic solids. It has 8 faces, 12 edges and 6 vertices.

    Parameters
    ----------
    edge_length
        The length of an edge between any two vertices.

    Examples
    --------

    .. manim:: OctahedronScene
        :save_last_frame:

        class OctahedronScene(ThreeDScene):
            def construct(self):
                self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
                obj = Octahedron()
                self.add(obj)
    rD   r_   r`   ra   r   c                   |t          j        d          z  dz  } t                      j        dt          j        |ddg          t          j        | ddg          t          j        d|dg          t          j        d| dg          t          j        dd|g          t          j        dd| g          gg dg dg dg dg dg dg d	g d
gd| d S )Nrc   r   )rc   rd   rD   )r   rd   rc   )rd   re   r   )rD   re   rd   )re      r   )rD   rr   re   )rc   rr   rD   )r   rr   rc   rf   r&   rg   rk   s       r+   r0   zOctahedron.__init__   s   RWQZZ'!+ 	
$1&&4%A''!T1&&!dUA''!Q&&!Q'' 																		
 	
& '	
 	
 	
 	
 	
r-   rm   rn   ro   r]   s   @r+   r   r      sL         (
 
 
 
 
 
 
 
 
 
 
r-   r   c                  &     e Zd ZdZdd	 fdZ xZS )
r   a   An icosahedron, one of the five platonic solids. It has 20 faces, 30 edges and 12 vertices.

    Parameters
    ----------
    edge_length
        The length of an edge between any two vertices.

    Examples
    --------

    .. manim:: IcosahedronScene
        :save_last_frame:

        class IcosahedronScene(ThreeDScene):
            def construct(self):
                self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
                obj = Icosahedron()
                self.add(obj)
    rD   r_   r`   ra   r   c                $   |dt          j        d          z   dz  z  }|dz  } t                      j        dt          j        d||g          t          j        d| |g          t          j        d|| g          t          j        d| | g          t          j        ||dg          t          j        || dg          t          j        | |dg          t          j        | | dg          t          j        |d|g          t          j        |d| g          t          j        | d|g          t          j        | d| g          gg dg dg dg d	g d
g dg dg dg dg dg dg dg dg dg dg dg dg dg dg dgd| d S )NrD   rr   rd   r   r   )rD      r   )rD   rr      )ru   rr   rD   )rv   re   rr   )rr   	   re   )ru   rw   rr   )re   rc   rw   )rw   rd   rc   )ru   rd   rw   )r   rd   ru   )   rd   r   )rx   rc   rd   )   rc   rx   )re   ry   rc   )r   rx   
   )rz   rD   r   )rz   rv   rD   )ry   rv   re   )rz   ry   rv   )rz   ry   rx   rf   r&   rg   )r*   r_   ra   unit_aunit_br@   s        r+   r0   zIcosahedron.__init__  s   RWQZZ1 45& &	
!VV,--!fWf-..!VfW-..!fWvg.//&&!,--&6'1-..6'61-..6'F7A.//&!V,--&!fW-..6'1f-..6'1vg.// 																								











)&	
 &	
J K&	
 &	
 &	
 &	
 &	
r-   rm   rn   ro   r]   s   @r+   r   r      sL         ()
 )
 )
 )
 )
 )
 )
 )
 )
 )
 )
r-   r   c                  &     e Zd ZdZdd	 fdZ xZS )
r   a  A dodecahedron, one of the five platonic solids. It has 12 faces, 30 edges and 20 vertices.

    Parameters
    ----------
    edge_length
        The length of an edge between any two vertices.

    Examples
    --------

    .. manim:: DodecahedronScene
        :save_last_frame:

        class DodecahedronScene(ThreeDScene):
            def construct(self):
                self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
                obj = Dodecahedron()
                self.add(obj)
    rD   r_   r`   ra   r   c                   |dt          j        d          z   dz  z  }|dt          j        d          z   dz  z  }|dz  } t                      j        dt          j        |||g          t          j        ||| g          t          j        || |g          t          j        || | g          t          j        | ||g          t          j        | || g          t          j        | | |g          t          j        | | | g          t          j        d||g          t          j        d|| g          t          j        d| | g          t          j        d| |g          t          j        ||dg          t          j        | |dg          t          j        || dg          t          j        | | dg          t          j        |d|g          t          j        | d|g          t          j        |d| g          t          j        | d| g          gg dg dg d	g d
g dg dg dg dg dg dg dg dgd| d S )NrD   rr   rd   re   r   r   )      r      rD   )re   r   r   rc      )re   rz   rw   rD   r   )rD   rw   rr      r   )r   ru   rd   r   r   )rc   r   r   ru   ry   )rd      rx   ry   ru   )r      rr   r   rd   )r   rv      rx   r   )rx   r   r   rc   ry   )r   rr   rw   rz   rv   )rv   rz   re   r   r   rf   r&   rg   )r*   r_   ra   r{   r|   unit_cr@   s         r+   r0   zDodecahedron.__init__I  s   RWQZZ1 45RWQZZ1 45& &	
&&&122&&6'233&6'6233&6'F73446'662336'6F73446'F7F3446'F7VG455!VV,--!VfW-..!fWvg.//!fWf-..&&!,--6'61-..&6'1-..6'F7A.//&!V,--6'1f-..&!fW-..6'1vg.//). #"""""!!!!!!!!!!!!!!!"""""""""!!!"""/&	
 &	
J K&	
 &	
 &	
 &	
 &	
r-   rm   rn   ro   r]   s   @r+   r   r   4  sL         (*
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
r-   r   c                  *     e Zd ZdZddd fd
Z xZS )r   a  A convex hull for a set of points

    Parameters
    ----------
    points
        The points to consider.
    tolerance
        The tolerance used for quickhull.
    kwargs
        Forwarded to the parent constructor.

    Examples
    --------
    .. manim:: ConvexHull3DExample
        :save_last_frame:
        :quality: high

        class ConvexHull3DExample(ThreeDScene):
            def construct(self):
                self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES)
                points = [
                    [ 1.93192757,  0.44134585, -1.52407061],
                    [-0.93302521,  1.23206983,  0.64117067],
                    [-0.44350918, -0.61043677,  0.21723705],
                    [-0.42640268, -1.05260843,  1.61266094],
                    [-1.84449637,  0.91238739, -1.85172623],
                    [ 1.72068132, -0.11880457,  0.51881751],
                    [ 0.41904805,  0.44938012, -1.86440686],
                    [ 0.83864666,  1.66653337,  1.88960123],
                    [ 0.22240514, -0.80986286,  1.34249326],
                    [-1.29585759,  1.01516189,  0.46187522],
                    [ 1.7776499,  -1.59550796, -1.70240747],
                    [ 0.80065226, -0.12530398,  1.70063977],
                    [ 1.28960948, -1.44158255,  1.39938582],
                    [-0.93538943,  1.33617705, -0.24852643],
                    [-1.54868271,  1.7444399,  -0.46170734]
                ]
                hull = ConvexHull3D(
                    *points,
                    faces_config = {"stroke_opacity": 0},
                    graph_config = {
                        "vertex_type": Dot3D,
                        "edge_config": {
                            "stroke_color": BLUE,
                            "stroke_width": 2,
                            "stroke_opacity": 0.05,
                        }
                    }
                )
                dots = VGroup(*[Dot3D(point) for point in points])
                self.add(hull)
                self.add(dots)
    gh㈵>)	tolerancepointsr   r   r`   ra   r   c                  t          j        |          }t          |          }|                    |           g }g }d}i t	          |j                  |j        z
  }	|	D ]}
t	                      }|
j        D ]I}|j        D ]?}|vr$|	                    |j
                   ||<   |dz  }|                    |           @J|	                    fd|D                         t                      j        d||d| d S )Nr   rD   c                     g | ]
}|         S r&   r&   )r(   pointds     r+   r,   z)ConvexHull3D.__init__.<locals>.<listcomp>  s    444u!E(444r-   rf   r&   )rh   rj   r   buildsetfacetsremoved	subfacetsr   appendcoordinatesr=   r/   r0   )r*   r   r   ra   rj   hullrV   r;   cr   facettmpsubfacetr   r   r@   s                 @r+   r0   zConvexHull3D.__init__  sM     ##

5  T[!!DL0 		6 		6E%%C!O # #%_ # #EA~~ (9:::#$%QGGENNNN# LL44444445555 	 	
"	
 	
 	
 	
 	
 	
 	
r-   )r   r   r   r`   ra   r   ro   r]   s   @r+   r   r   v  sX        4 4l =A 
 
 
 
 
 
 
 
 
 
 
 
r-   r   ) r[   
__future__r   collections.abcr   typingr   r   numpyrh   manim.mobject.geometry.polygramr   manim.mobject.graphr   &manim.mobject.three_d.three_dimensionsr	   &manim.mobject.types.vectorized_mobjectr
   manim.utils.qhullr   manim.mobject.mobjectr   manim.typingr   r   __all__r   r   r   r   r   r   r&   r-   r+   <module>r      s   3 3 " " " " " " $ $ $ $ $ $ % % % % % % % %     3 3 3 3 3 3 % % % % % % 8 8 8 8 8 8 9 9 9 9 9 9 ' ' ' ' ' ' 8------77777777  AA AA AA AA AA AA AA AAH 
  
  
  
  
*  
  
  
F+
 +
 +
 +
 +
 +
 +
 +
\>
 >
 >
 >
 >
* >
 >
 >
B?
 ?
 ?
 ?
 ?
: ?
 ?
 ?
DU
 U
 U
 U
 U
: U
 U
 U
 U
 U
r-   