
    h~?                     J    S SK Jr  S SKrS/rS
S jrS rS rS rSS jr	S	 r
g)    )defaultdictNcombinatorial_embedding_to_posc                   ^ [        U R                  5       5      S:  a0  / SQn0 n[        U R                  5       5       H  u  pEX$   X5'   M     U$ [        X5      u  p0 n0 n0 m0 n	[	        X5      n
U
S   S   U
S   S   U
S   S   pnSTU'   SX'   XU'   SX{'   STU'   SX'   SX'   SX|'   STU'   SX'   XU'   SX}'   [        S[        U
5      5       H  nX   u  nnUS   nUS   nUS   nUS	   n[        U5      S:  nTU==   S-  ss'   TU==   S-  ss'   [        U4S
 jUSS  5       5      nU	U   * U-   U	U   -   S-  TU'   U	U   U-   U	U   -   S-  X'   UTU   -
  TU'   U(       a  TU==   TU   -  ss'   XU'   UX'   U(       a  UX'   SUU'   M  SX'   M     0 nSX   4X;'   U/nU(       a7  UR                  5       n[        UUUTX5        [        UUUTX5        U(       a  M7  U$ )a  Assigns every node a (x, y) position based on the given embedding

The algorithm iteratively inserts nodes of the input graph in a certain
order and rearranges previously inserted nodes so that the planar drawing
stays valid. This is done efficiently by only maintaining relative
positions during the node placements and calculating the absolute positions
at the end. For more information see [1]_.

Parameters
----------
embedding : nx.PlanarEmbedding
    This defines the order of the edges

fully_triangulate : bool
    If set to True the algorithm adds edges to a copy of the input
    embedding and makes it chordal.

Returns
-------
pos : dict
    Maps each node to a tuple that defines the (x, y) position

References
----------
.. [1] M. Chrobak and T.H. Payne:
    A Linear-time Algorithm for Drawing a Planar Graph on a Grid 1989
    http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.51.6677

   ))r   r   )   r   )   r   r   r   r   N   c              3   .   >#    U  H
  nTU   v   M     g 7fN ).0xdelta_xs     T/var/www/html/env/lib/python3.13/site-packages/networkx/algorithms/planar_drawing.py	<genexpr>1combinatorial_embedding_to_pos.<locals>.<genexpr>\   s     A0@1GAJ0@s   )	lennodes	enumeratetriangulate_embeddingget_canonical_orderingrangesumpopset_position)	embeddingfully_triangulatedefault_positionsposiv
outer_faceleft_t_childright_t_childy_coordinate	node_listv1v2v3kvkcontour_nbrswpwp1wqwq1adds_mult_tridelta_x_wp_wqremaining_nodesparent_noder   s                            @r   r   r      s   < 9??!4ioo/0DA&)CF 1
1)OI
 LM GL&y=I
 1a)A,q/9Q<?BBGBKL"LGBKLMLGBKL"L1c)n%$<L!_1o"2L)A- 	qAQR0@AA %R((=8<;KKPQQ(,}<|B?OOTUU#gbk1CLGBK'L b"L!%M##L9 &> C,"#CGdO
%))+ 		
 	,	
 / J    c                 b    X   nXP   S   nUb!  XsU   -   nXU   4XV'   UR                  U5        gg)z:Helper method to calculate the absolute position of nodes.r   N)append)	parenttreer5   r   r'   r!   childparent_node_xchild_xs	            r   r   r      sH    LEKNM%.0E23
u% r7   c                 |  ^^^^ US   mUS   n[        [        5      n[        5       m[        U5      n0 mUn[        S[	        U5      5       H  nX   TU'   X   nM     TTU'   0 mTn[        [	        U5      S-
  SS5       H  nX   TU'   X   nM     UU4S jnUUU4S jnU HV  n	U R                  U	5       H>  n
U" U
5      (       d  M  U" X5      (       a  M!  X9==   S-  ss'   UR                  U	5        M@     MX     S/[	        U R                  5       5      -  nT/ 4US'   U/ 4US'   UR                  T5        UR                  U5        [        [	        U R                  5       5      S-
  SS5       GH  nUR                  5       n	TR                  U	5        SnSn[        U R                  U	5      5      n [        U5      n
U
T;   a  M  U" U
5      (       a  U
T:X  a  TnOX:X  a  UnOTU
   U	:X  a  U
nOU
nUb  Ub  OMH  U/nUn
X:w  a.  X	   U
   S   nUR                  U5        UTU
'   U
TU'   Un
X:w  a  M.  [	        U5      S:X  aK  X===   S-  ss'   X=   S:X  a  UR                  U5        X>==   S-  ss'   X>   S:X  a  UR                  U5        O[        USS 5      nU H  nUR                  U5        U R                  U5       He  n
U" U
5      (       d  M  U" UU
5      (       a  M"  UU==   S-  ss'   UR                  U5        U
U;  d  MH  X:==   S-  ss'   UR                  U
5        Mg     M     U	U4X'   GM     U$ )	a  Returns a canonical ordering of the nodes

The canonical ordering of nodes (v1, ..., vn) must fulfill the following
conditions:
(See Lemma 1 in [2]_)

- For the subgraph G_k of the input graph induced by v1, ..., vk it holds:
    - 2-connected
    - internally triangulated
    - the edge (v1, v2) is part of the outer face
- For a node v(k+1) the following holds:
    - The node v(k+1) is part of the outer face of G_k
    - It has at least two neighbors in G_k
    - All neighbors of v(k+1) in G_k lie consecutively on the outer face of
      G_k (excluding the edge (v1, v2)).

The algorithm used here starts with G_n (containing all nodes). It first
selects the nodes v1 and v2. And then tries to find the order of the other
nodes by checking which node can be removed in order to fulfill the
conditions mentioned above. This is done by calculating the number of
chords of nodes on the outer face. For more information see [1]_.

Parameters
----------
embedding : nx.PlanarEmbedding
    The embedding must be triangulated
outer_face : list
    The nodes on the outer face of the graph

Returns
-------
ordering : list
    A list of tuples `(vk, wp_wq)`. Here `vk` is the node at this position
    in the canonical ordering. The element `wp_wq` is a list of nodes that
    make up the outer face of G_k.

References
----------
.. [1] Steven Chaplick.
    Canonical Orders of Planar Graphs and (some of) Their Applications 2015
    https://wuecampus2.uni-wuerzburg.de/moodle/pluginfile.php/545727/mod_resource/content/0/vg-ss15-vl03-canonical-orders-druckversion.pdf
.. [2] M. Chrobak and T.H. Payne:
    A Linear-time Algorithm for Drawing a Planar Graph on a Grid 1989
    http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.51.6677

r   r   r   r
   c                 j   > U T;  a  TU    U:H  $ U T;  a  TU    U:H  $ TU    U:H  =(       d    TU    U:H  $ r   r   )r   youter_face_ccw_nbrouter_face_cw_nbrs     r   is_outer_face_nbr1get_canonical_ordering.<locals>.is_outer_face_nbr   sU    &&$Q'1,,%%%a(A--!!$)F->q-AQ-FFr7   c                 >   > U T;  =(       a    U T;   =(       d    U T:H  $ r   r   )r   marked_nodesrB   r)   s    r   is_on_outer_face0get_canonical_ordering.<locals>.is_on_outer_face   s"    $M!/A*A*LQ"WMr7   Nccw)r   intsetr   r   neighbors_cw_orderdiscardr   r   additernextr9   )r   r$   r*   chordsready_to_pickprev_nbridxrD   rH   r#   nbrcanonical_orderingr,   r/   r1   nbr_iteratorwp_wqnext_nbrnew_face_nodeswrG   rB   rC   r)   s                       @@@@r   r   r      sz   ^ 
AB	ABF5L
OM HQJ('18$? ) $&x  HS_q(!R0&0o(#? 1GN //2C$$->q-F-F	Q	%%a( 3  #ioo&7"88HqHq""3y()A-q"5 I88;<|$Cl"$$"9BYB(-2  !~".) . i |C(/HLL"%-c"+.x(C i u:?J!OJzQ!!"%J!OJzQ!!"% !q-N#!!!$$77:C',,5Fq#5N5Nq	Q	%--a0n4 #K1,K)11#6 ; $ "#E
M 6P r7   c                    U R                  X5      u  p4U R                  X$5      u  p5XU4;   a  gX:w  aZ  U R                  X5      (       a  X$UpBnO$U R                  XUS9  U R                  XAUS9  XUpBnU R                  X$5      u  p5X:w  a  MY  gg)zTriangulates the face given by half edge (v, w)

Parameters
----------
embedding : nx.PlanarEmbedding
v1 : node
    The half-edge (v1, v2) belongs to the face that gets triangulated
v2 : node
NrJ   cw)next_face_half_edgehas_edgeadd_half_edge)r   r)   r*   _r+   v4s         r   triangulate_facerf   3  s     ))"1EA))"1EA	"X~
(b%%BBB ##B#3##Br#2BB--b5 (r7   c                    [        U R                  5      S::  a  U [        U R                  5      4$ [        R                  " U 5      n [        R
                  " U 5       Vs/ s H  n[        [        U5      5      PM     nn[        [        U5      S-
  5       H  nX4   nX4S-      nU R                  XV5        M!     / n/ n[        5       n	U R                  5        H]  n
U R                  U
5       HE  n[        X
X5      nU(       d  M  UR                  U5        [        U5      [        U5      :  d  MC  UnMG     M_     U H"  nXLd	  U(       d  M  [        XS   US   5        M$     U(       a  US   nUS   nX   U   S   nXVU/nX4$ s  snf )a  Triangulates the embedding.

Traverses faces of the embedding and adds edges to a copy of the
embedding to triangulate it.
The method also ensures that the resulting graph is 2-connected by adding
edges if the same vertex is contained twice on a path around a face.

Parameters
----------
embedding : nx.PlanarEmbedding
    The input graph must contain at least 3 nodes.

fully_triangulate : bool
    If set to False the face with the most nodes is chooses as outer face.
    This outer face does not get triangulated.

Returns
-------
(embedding, outer_face) : (nx.PlanarEmbedding, list) tuple
    The element `embedding` is a new embedding containing all edges from
    the input embedding and the additional edges to triangulate the graph.
    The element `outer_face` is a list of nodes that lie on the outer face.
    If the graph is fully triangulated these are three arbitrary connected
    nodes.

r   r   rJ   )r   r   listnxPlanarEmbeddingconnected_componentsrQ   rP   r   connect_componentsrL   rM   make_bi_connectedr9   rf   )r   r   r   component_nodesr"   r)   r*   r$   	face_listedges_visitedr#   r\   new_facefacer+   s                  r   r   r   P  sy   6 9??q $y///""9-I /1.E.Ei.PQ.PtDG}.POQ 3'!+,U#$$R, - JIEM__--a0A(qHHx  *x=3z?2!)J 1  !%6%6YQa9 
 ]]]2u%b\
  E Rs   Fc                    X4U;   a  / $ UR                  X45        UnUnU/n[        U5      nU R                  XE5      u  pXQ:w  d  X:w  a  XE:X  a  [        R                  " S5      eXW;   aG  U R                  XIUS9  U R                  XUS9  UR                  XY45        UR                  X45        UnO"UR                  U5        UR                  U5        UnU R                  XY5      u  pYUR                  XE45        XQ:w  a  M  X:w  a  M  U$ )a  Triangulate a face and make it 2-connected

This method also adds all edges on the face to `edges_counted`.

Parameters
----------
embedding: nx.PlanarEmbedding
    The embedding that defines the faces
starting_node : node
    A node on the face
outgoing_node : node
    A node such that the half edge (starting_node, outgoing_node) belongs
    to the face
edges_counted: set
    Set of all half-edges that belong to a face that have been visited

Returns
-------
face_nodes: list
    A list of all nodes at the border of this face
zInvalid half-edger^   r_   )rO   rL   ra   ri   NetworkXExceptionrc   r9   )
r   starting_nodeoutgoing_nodeedges_countedr)   r*   ro   face_setrd   r+   s
             r   rm   rm     s!   0 	%6	}45 
B	BI9~H))"1EA 
!48&&':;;>##B#3##Br#2rh'rh'BLLR  ..r6 	2(#) 
!4, r7   )F)T)collectionsr   networkxri   __all__r   r   r   rf   r   rm   r   r7   r   <module>r|      s7    # +
,up	&dN6:B!J;r7   