U
    Ñtœd�6  ã                   @   sè   d Z dZddlmZmZ ddlmZmZmZm	Z	m
Z
 ddlZddlmZ eƒ \ZZG dd„ ded	�ZG d
d„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ dƒZe eje j¡ dS )a`  
Shape drawing classes for igraph

Vertex shapes in igraph are usually referred to by short names like
C{"rect"} or C{"circle"}. This module contains the classes that
implement the actual drawing routines for these shapes, and a
resolver class that determines the appropriate shape drawer class
given the short name.

Classes that are derived from L{ShapeDrawer} in this module are
automatically registered by L{ShapeDrawerDirectory}. If you
implement a custom shape drawer, you must register it in
L{ShapeDrawerDirectory} manually if you wish to refer to it by a
name in the C{shape} attribute of vertices.
)ÚShapeDrawerDirectoryé    )ÚABCMetaÚabstractmethod)Úatan2ÚcopysignÚcosÚpiÚsinN)Úfind_matplotlibc                   @   s0   e Zd ZdZeeddd„ƒƒZeddd„ƒZdS )	ÚShapeDrawerzúStatic class, the ancestor of all vertex shape drawer classes.

    Custom shapes must implement at least the C{draw_path} method of the class.
    The method I{must not} stroke or fill, it should just set up the current
    Cairo path appropriately.Nc                 K   s   t ‚dS )a:  Draws the path of the shape on the given Cairo context, without
        stroking or filling it.

        This method must be overridden in derived classes implementing custom shapes
        and declared as a static method using C{staticmethod(...)}.

        @param ctx: the context to draw on
        @param center_x: the X coordinate of the center of the object
        @param center_y: the Y coordinate of the center of the object
        @param width: the width of the object
        @param height: the height of the object. If C{None}, equals to the width.
        N)ÚNotImplementedError©ÚctxÚcenter_xÚcenter_yÚwidthÚheightÚkwargs© r   úN/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/igraph/drawing/shapes.pyÚ	draw_path&   s    zShapeDrawer.draw_pathc                 C   s   | |fS )aU  Determines where the shape centered at (center_x, center_y)
        intersects with a line drawn from (source_x, source_y) to
        (center_x, center_y).

        Can be overridden in derived classes. Must always be defined as a static
        method using C{staticmethod(...)}

        @param width: the width of the shape
        @param height: the height of the shape. If C{None}, defaults to the width
        @return: the intersection point (the closest to (source_x, source_y) if
            there are more than one) or (center_x, center_y) if there is no
            intersection
        r   ©r   r   Úsource_xÚsource_yr   r   r   r   r   Úintersection_point7   s    zShapeDrawer.intersection_point)N)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ústaticmethodr   r   r   r   r   r   r   r      s   r   )Ú	metaclassc                   @   s,   e Zd ZdZdddddgZed
dd	„ƒZdS )Ú
NullDrawerzgStatic drawer class which draws nothing.

    This class is used for graph vertices with unknown shapesÚnullÚnoneÚemptyZhiddenÚ Nc                 C   s   dS )zDraws nothing.Nr   )r   r   r   r   r   r   r   r   r   P   s    zNullDrawer.draw_path)N)r   r   r   r   Únamesr   r   r   r   r   r   r!   I   s   r!   c                   @   s0   e Zd ZdZdZeddd„ƒZed	dd„ƒZdS )
ÚRectangleDrawerz-Static class which draws rectangular verticesz'rectangle rect rectangular square box sNc                 K   sj   |p|}t tdƒrFt| tjƒrFtjj||d  ||d  f||f|ŽS |  ||d  ||d  ||¡ dS )z~Draws a rectangle-shaped path on the Cairo context without stroking
        or filling it.
        @see: ShapeDrawer.draw_pathÚAxesé   N)ÚhasattrÚpltÚ
isinstancer(   ÚmplÚpatchesZ	RectangleZ	rectangler   r   r   r   r   [   s      ÿÿzRectangleDrawer.draw_pathc                 C   s°  |p|}| | ||  }}|dkr2|dkr2| |fS |dkrt||krt|| krt||d  }|d | }	| |	|  |fS |dk r¸|| kr¸||kr¸||d  }|d |  }	| |	|  |fS |dkrú||krú|| krú| |d  }
|d | }	|
||	|  fS |dk �rD|| k�rD||k�rD| |d  }
|d |  }	|
||	|  fS |dk�rx|dk�rh| ||d  fS | ||d  fS |dk�r¬|dk�rœ| |d  |fS | |d  |fS dS )zïDetermines where the rectangle centered at (center_x, center_y)
        having the given width and height intersects with a line drawn from
        (source_x, source_y) to (center_x, center_y).

        @see: ShapeDrawer.intersection_pointr   r)   Nr   )r   r   r   r   r   r   Údelta_xÚdelta_yZryÚratioÚrxr   r   r   r   h   s8     



z"RectangleDrawer.intersection_point)N)N©r   r   r   r   r&   r   r   r   r   r   r   r   r'   V   s   r'   c                   @   s0   e Zd ZdZdZeddd„ƒZed	dd„ƒZdS )
ÚCircleDrawerz*Static class which draws circular verticeszcircle circular oNc                 K   sN   t tdƒr0t| tjƒr0tjj||f|d f|ŽS |  |||d ddt ¡ dS )zÏDraws a circular path on the Cairo context without stroking or
        filling it.

        Height is ignored, it is the width that determines the diameter of the circle.

        @see: ShapeDrawer.draw_pathr(   r)   r   N)	r*   r+   r,   r(   r-   r.   ZCircleÚarcr   r   r   r   r   r   �   s    zCircleDrawer.draw_pathc                 C   sB   |p|}t || | | ƒ}| |d t|ƒ  ||d t|ƒ  fS )zÊDetermines where the circle centered at (center_x, center_y)
        intersects with a line drawn from (source_x, source_y) to
        (center_x, center_y).

        @see: ShapeDrawer.intersection_pointr)   )r   r   r	   )r   r   r   r   r   r   Zangler   r   r   r   ª   s    zCircleDrawer.intersection_point)N)Nr3   r   r   r   r   r4   ˜   s   r4   c                   @   s0   e Zd ZdZdZeddd„ƒZed	dd„ƒZdS )
ÚUpTriangleDrawerz*Static class which draws upright trianglesz:triangle triangle-up up-triangle arrow arrow-up up-arrow ^Nc                 K   sÌ   |p|}t tdƒrtt| tjƒrt|d|  |d|  g|d|  |d|  g||d|  gg}tjj|fddi|—ŽS |  ||d  ||d  ¡ |  |||d  ¡ |  ||d  ||d  ¡ |  	¡  dS )	z{Draws an upright triangle on the Cairo context without stroking or
        filling it.

        @see: ShapeDrawer.draw_pathr(   ç      à?çZd;ßOÕ?çòÒMbXå?ÚclosedTr)   N©
r*   r+   r,   r(   r-   r.   ZPolygonÚmove_toZline_toZ
close_path©r   r   r   r   r   r   Zverticesr   r   r   r   »   s    ýzUpTriangleDrawer.draw_pathc                 C   s   |p|}| |fS ©zÌDetermines where the triangle centered at (center_x, center_y)
        intersects with a line drawn from (source_x, source_y) to
        (center_x, center_y).

        @see: ShapeDrawer.intersection_pointr   r   r   r   r   r   Ï   s    z#UpTriangleDrawer.intersection_point)N)Nr3   r   r   r   r   r6   ¶   s   r6   c                   @   s0   e Zd ZdZdZeddd„ƒZed	dd„ƒZdS )
ÚDownTriangleDrawerz0Static class which draws triangles pointing downz3down-triangle triangle-down arrow-down down-arrow vNc                 K   sÌ   |p|}t tdƒrtt| tjƒrt|d|  |d|  g|d|  |d|  g||d|  gg}tjj|fddi|—ŽS |  ||d  ||d  ¡ |  |||d  ¡ |  ||d  ||d  ¡ |  	¡  dS )	zrDraws a triangle on the Cairo context without stroking or
        filling it.

        @see: ShapeDrawer.draw_pathr(   r7   r8   r9   r:   Tr)   Nr;   r=   r   r   r   r   à   s    ýzDownTriangleDrawer.draw_pathc                 C   s   |p|}| |fS r>   r   r   r   r   r   r   õ   s    z%DownTriangleDrawer.intersection_point)N)Nr3   r   r   r   r   r?   Û   s   r?   c                   @   s0   e Zd ZdZdZeddd„ƒZed	dd„ƒZdS )
ÚDiamondDrawerz2Static class which draws diamonds (i.e. rhombuses)zdiamond rhombus dNc                 K   sÎ   |p|}t tdƒrrt| tjƒrr|d|  |g||d|  g|d|  |g||d|  gg}tjj|fddi|—ŽS |  ||d  |¡ |  |||d  ¡ |  ||d  |¡ |  |||d  ¡ |  	¡  dS )zqDraws a rhombus on the Cairo context without stroking or
        filling it.

        @see: ShapeDrawer.draw_pathr(   r7   r:   Tr)   Nr;   r=   r   r   r   r     s    üzDiamondDrawer.draw_pathc           	      C   s¬   |p|}|dkr |dkr | |fS ||  ||  }}|dkr`|dkrJ| |fS | |t |d |ƒ fS t ||ƒ}t ||ƒ}|||| |   }| || d  |d| | d  fS )zËDetermines where the rhombus centered at (center_x, center_y)
        intersects with a line drawn from (source_x, source_y) to
        (center_x, center_y).

        @see: ShapeDrawer.intersection_pointr   r)   é   )r   )	r   r   r   r   r   r   r/   r0   Úfr   r   r   r     s    

z DiamondDrawer.intersection_point)N)Nr3   r   r   r   r   r@     s   r@   c                   @   sH   e Zd ZdZi Zedd„ ƒZedd„ ƒZedd„ ƒZee	fdd	„ƒZ
d
S )r   a  Static class that resolves shape names to their corresponding
    shape drawer classes.

    Classes that are derived from L{ShapeDrawer} in this module are
    automatically registered by L{ShapeDrawerDirectory} when the module
    is loaded for the first time.
    c                 C   s0   |j }t|tƒr| ¡ }|D ]}|| j|< qdS )zŒRegisters the given shape drawer class under the given names.

        @param drawer_class: the shape drawer class to be registered
        N)r&   r,   ÚstrÚsplitÚknown_shapes)ÚclsZdrawer_classr&   Únamer   r   r   ÚregisterF  s
    
zShapeDrawerDirectory.registerc                 C   sH   |  ¡ D ]:\}}| d¡rqt|tƒrt|tƒr|tkr|  |¡ qdS )z…Registers all L{ShapeDrawer} classes in the given namespace

        @param namespace: a Python dict mapping names to Python objects.Ú__N)ÚitemsÚ
startswithr,   ÚtypeÚ
issubclassr   rH   )rF   Ú	namespacerG   Úvaluer   r   r   Úregister_namespaceS  s    

z'ShapeDrawerDirectory.register_namespacec                 C   s2   z| j | W S  tk
r,   td| ƒ‚Y nX dS )zàGiven a shape name, returns the corresponding shape drawer class

        @param shape: the name of the shape
        @return: the corresponding shape drawer class

        @raise ValueError: if the shape is unknown
        zunknown shape: %sN)rE   ÚKeyErrorÚ
ValueError)rF   Úshaper   r   r   Úresolve_  s    	zShapeDrawerDirectory.resolvec                 C   s   | j  ||¡S )a¨  Given a shape name, returns the corresponding shape drawer class
        or the given default shape drawer if the shape name is unknown.

        @param shape: the name of the shape
        @param default: the default shape drawer to return when the shape
          is unknown
        @return: the shape drawer class corresponding to the given name or
          the default shape drawer class if the name is unknown
        )rE   Úget)rF   rS   Údefaultr   r   r   Úresolve_defaultm  s    z$ShapeDrawerDirectory.resolve_defaultN)r   r   r   r   rE   ÚclassmethodrH   rP   rT   r!   rW   r   r   r   r   r   ;  s   


r   )r   Ú__all__Úabcr   r   Úmathr   r   r   r   r	   ÚsysZigraph.drawing.matplotlib.utilsr
   r-   r+   r   r!   r'   r4   r6   r?   r@   r   rP   Úmodulesr   Ú__dict__r   r   r   r   Ú<module>   s   
*B%&:@