U
    td6                     @   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 )	ShapeDrawerzStatic 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 )zDetermines 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 )zDraws 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 )zDetermines 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 zDetermines 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 )zDetermines 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 )zRegisters 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 )zRegisters 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 )zGiven 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%&:@