
    jy}                     H   d dl Zd dlmZ d dlmZ ddlmZmZm	Z	m
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mZmZmZmZmZmZmZ ddlmZ ddlmZ 	 d dl Z!	 d dl&m'Z' d Z(dee   dee   fdZ)deee   ef   fdZ*deeef   fdZ+d Z,d*dZ-d+dZ.d*dede/fdZ0d Z1d,dedee   fdZ2dedee   fd Z3d-d!Z4d" Z5d*d#Z6d.d$Z7d/d%Z8	 	 	 	 	 	 	 d0d&e9d'e/fd(Z:d1defd)Z;y# e"$ rZ#ddl$m%Z%  e%e#      Z!Y dZ#[#dZ#[#ww xY w# e"$ rZ#ddl$m%Z%  e%e#      Z'Y dZ#[#dZ#[#ww xY w)2    N)ops)Polygon   )boundsgeometrygraphgrouping)log)tol_path)reduce_cascade)transform_points)	ArrayLikeIterableNDArrayNumberOptionalUnionfloat64int64   )fit_circle_check)resample_path)ExceptionWrapper)Indexc           
         t        j                         }t        |       dk(  r't        j                  g t        j
                        |fS t        |       dk(  r9|j                  d       t        j                  dgt        j
                        |fS t        |       D ci c]  \  }}|t        |dg        c}}j                         D ci c]  \  }}t        |      dk(  r|| }}}|j                   |j                                t        |      dkD  rAt        t         |j                          |j                         dgt        |      z              } |j                         D ]u  \  }}j                  |      D ]\  }	||	k(  r	| |   j!                  | |	         r|j#                  ||	       3| |	   j!                  | |         sK|j#                  |	|       ^ w t%        |j'                               }
t        j                  t)        |
j                                     }t        j                  t)        |
j                                     }||dz  dk(     }t        |      dkD  r|j+                         dkD  rg }|t        j,                  |D cg c]  }|
|   	 c}         }|D ]R  }|||
|   dz   k(     }|j/                  |j1                  t        j2                  ||            j5                                T t        j6                  |t        j                               }|j                  |       ||fS c c}}w c c}}w c c}w )az  
    Given a list of shapely polygons with only exteriors,
    find which curves represent the exterior shell or root curve
    and which represent holes which penetrate the exterior.

    This is done with an R-tree for rough overlap detection,
    and then exact polygon queries for a final result.

    Parameters
    -----------
    polygons : (n,) shapely.geometry.Polygon
       Polygons which only have exteriors and may overlap

    Returns
    -----------
    roots : (m,) int
        Index of polygons which are root
    contains : networkx.DiGraph
       Edges indicate a polygon is
       contained by another polygon
    r   dtyper   r      Nr   )nxDiGraphlennparrayr   add_node	enumerategetattritemsadd_nodes_fromkeysr   zipvaluesintersectioncontainsadd_edgedict	in_degreelistmaxargsortextendsubgraphappendedgesfrom_edgelist)polygonsr-   ipolygonkvr   treebjdegreeindexesdegreesrootsr7   rrootchildrens                     B/DATA/.local/lib/python3.12/site-packages/trimesh/path/polygons.pyenclosure_treerI      s   0 zz|H
8}xx"((+X55	X!	!xx288,h66 AJ(@S
@S*!WAww"--@S

%'DAq q6Q;	 	
1   KFKKM*
6{Q
 S$#f+9MNO 1""1%AAv {##HQK0!!!Q'!%%hqk2!!!Q' &  ($$&'FhhtFKKM*+GhhtFMMO,-GWq[Q&'E 7|aGKKMA-bjjU!;U&)U!;<=Dw&,*::;HLL**299Xt+DEKKMN  ##E2::<8&(?m
\ "<s   L>MM

r7   verticesc                 4   t        |t        j                        sJ g }t        j                  | d      D ]S  }	 t        t        ||               }t        |d      r|j                  |j                         n|j                  |       U t        |      dk(  r|S t        |      \  }}|D cg c]H  }t        ||   j                  ||   j                         D cg c]  }||   j                   c}      J c}}S # t        $ r Y w xY wc c}w c c}}w )aw  
    Given an edge list of indices and associated vertices
    representing lines, generate a list of polygons.

    Parameters
    -----------
    edges : (n, 2)
      Indexes of vertices which represent lines
    vertices : (m, 2)
      Vertices in 2D space.

    Returns
    ----------
    polygons : (p,) shapely.geometry.Polygon
      Polygon objects with interiors
    dfs)modegeomsr   shellholes)
isinstancer"   ndarrayr   
traversalsrepair_invalidr   hasattrr4   rN   r6   
ValueErrorr!   rI   exteriorr)   )	r7   rJ   r9   rL   repairedrD   r>   rF   r:   s	            rH   edges_to_polygonsrZ   |   s   $ h

+++ HE2		%ghsm&<=Hx)/) 3 8} !*KE4 
 D	 	4.))15d1BC1BA8A;''1BC	
    		 Ds*   AD /-DD2
D 	DDDr9   c                     dgt        |       z  }dgt        |       z  }t        |       D ]  \  }}t        |      \  ||<   ||<    t        j                  |      t        j                  |      fS )z?
    Find the OBBs for a list of shapely.geometry.Polygons
    N)r!   r%   polygon_obbr"   r#   )r9   
rectangles
transformsr:   ps        rH   polygons_obbr`      sj     #h-'J#h-'J(#1'21~$
1z!} $88J*!555    r;   c                    t        | d      r*t        j                  | j                  j                        }n(t        | t        j                        r| }nt        d      t        j                  |      \  }}t        j                  rdt        ||      }t        j                  | dz  |j                  d            sJ t        j                  |dz  |j                  d            sJ ||fS )a  
    Find the oriented bounding box of a Shapely polygon.

    The OBB is always aligned with an edge of the convex hull of the polygon.

    Parameters
    -------------
    polygons : shapely.geometry.Polygon
      Input geometry

    Returns
    -------------
    transform : (3, 3) float
      Transformation matrix
      which will move input polygon from its original position
      to the first quadrant where the AABB is the OBB
    extents : (2,) float
      Extents of transformed polygon
    rX   z"polygon or points must be providedpointsmatrix       @r   axis)rV   r"   
asanyarrayrX   coordsrR   rS   rW   r   oriented_bounds_2Dtolstrictr   allcloseminr2   )r;   rd   	transformextentsmoveds        rH   r\   r\      s    ( w
#w//667	GRZZ	(=>>226:Iw
zz yA{{G8c>599!9+<==={{7S=%)))*;<<<gra   c                    t        j                  |t         j                        }t        | d      r*t	        | |      D cg c]  \  }}t        ||       }}}|S t        t        j                  | j                  j                        |      ddddf   }| j                  D cg c]4  }t        t        j                  |j                        |      ddddf   6 }}t        ||      }|S c c}}w c c}w )aV  
    Transform a polygon by a a 2D homogeneous transform.

    Parameters
    -------------
    polygon : shapely.geometry.Polygon
      2D polygon to be transformed.
    matrix  : (3, 3) float
      2D homogeneous transformation.

    Returns
    --------------
    result : shapely.geometry.Polygon
      Polygon transformed by matrix.
    r   rN   Nr   rO   )r"   ri   r   rV   r*   transform_polygonr   r#   rX   rj   	interiorsr   )r;   re   r_   tresultrP   r:   rQ   s           rH   rt   rt      s      ]]64Fw 69'66JK6Jda#Aq)6JKRXXg&6&6&=&=>G2A2NE FMEVEVEV!((+V4QU;EV 
  5.FM L
s   C0&9C6c                 x   |F|j                   dk(  sJ t        t        j                  | j                  j
                        |      }n)t        j                  | j                  j
                        }t        j                  |j                  d      |j                  d      g      }|j                   dk(  sJ |S )a  
    Get the transformed axis aligned bounding box of a
    shapely Polygon object.

    Parameters
    ------------
    polygon : shapely.geometry.Polygon
      Polygon pre-transform
    matrix : (3, 3) float or None.
      Homogeneous transform moving polygon in space

    Returns
    ------------
    bounds : (2, 2) float
      Axis aligned bounding box of transformed polygon.
    )   ry   rc   r   rg   r   r   )shaper   r"   r#   rX   rj   ro   r2   )r;   re   rd   r   s       rH   polygon_boundsr|      s    " ||v%%%!'2B2B2I2I)JSYZ'**112XXvzzqz)6::1:+=>?F<<6!!!Mra   c                 p   ddl m} fd}|j                         j                  dd       | j                  j
                  dk(  r!| j                  D cg c]
  } ||       c} n-t        | d      r| D cg c]
  } ||       c} n
|  ||        |r|j                          S c c}w c c}w )z
    Plot a shapely polygon using matplotlib.

    Parameters
    ------------
    polygon : shapely.geometry.Polygon
      Polygon to be plotted
    show : bool
      If True will display immediately
    **kwargs
      Passed to plt.plot
    r   Nc                      j                   | j                  j                  i  | j                  D ]  } j                   |j                  i    y N)plotrX   xyru   )singleinterioraxeskwargss     rH   plot_singlezplot.<locals>.plot_single+  sG    		6??%%00((HDIIx{{-f- )ra   equaldatalimMultiPolygon__iter__)	matplotlib.pyplotpyplotr   
set_aspect	__class____name__rN   rV   show)r;   r   r   r   pltr   r:   s     ``   rH   r   r     s     $. |xxzOOGY'!!^3!(/AQ/	*	%!()AQ)		G
K 	0)s   B.=B3
resolutionc                     fd}ddg || j                         g d}| j                  D ]  }|d   j                   ||              |S )a  
    Return a version of a polygon with boundaries re-sampled
    to a specified resolution.

    Parameters
    -------------
    polygon : shapely.geometry.Polygon
      Source geometry
    resolution : float
      Desired distance between points on boundary
    clip : (2,) int
      Upper and lower bounds to clip
      number of samples to avoid exploding count

    Returns
    ------------
    kwargs : dict
     Keyword args for a Polygon constructor `Polygon(**kwargs)`
    c                     | j                   z  }t        t        j                  |g       }t	        | j
                  |      S )N)count)lengthintr"   clipr   rj   )boundaryr   r   r   s     rH   resample_boundaryz.resample_boundaries.<locals>.resample_boundaryW  s<     *,BGGE)D)*X__E::ra         rO   rQ   )rX   ru   r6   )r;   r   r   r   r   r   s    ``   rH   resample_boundariesr   B  s\    *; |3x()9)9:RHF%%w0:; & Mra   c                     t        | d         dk(  r| d   S t        j                  | d   t        j                  | d         f      S )z
    Stack the boundaries of a polygon into a single
    (n, 2) list of vertices.

    Parameters
    ------------
    boundaries : dict
      With keys 'shell', 'holes'

    Returns
    ------------
    stacked : (n, 2) float
      Stacked vertices
    rQ   r   rP   )r!   r"   vstack)
boundariess    rH   stack_boundariesr   h  sH     :g1$'""99j)299Z5H+IJKKra   c                    t        | j                        dk(  rt        j                  t        j                  | j
                  d      d      j                         }t        | j                  j                  |      }|t        j                  |d   dz  dt        j                        }t        j                  |d   d|gz   |d   d|gz
  gt        j                  	      }t        j                  dd
ggt        j                  	      }||fS ddlm} ddlm}	 |Ft        j                  t        j                  | j
                  d      d      j                         dz  }t'        | ||      }
t)        |
      }
 ||
      } |	j*                  | g|j,                  j.                   }t        j0                  |d      }t        j2                  |j4                  t        j                  	      }|||   j7                  d
         }t        j8                  |      }t        j:                  t        |j,                        t        j                  	      }t        j<                  t        |            ||<   |j,                  |   }||   }t>        j@                  r-t        j                  ||   |j,                  |   z
        dk  sJ ||fS )ai  
    Given a shapely polygon, find the approximate medial axis
    using a voronoi diagram of evenly spaced points on the
    boundary of the polygon.

    Parameters
    ----------
    polygon : shapely.geometry.Polygon
      The source geometry
    resolution : float
      Distance between each sample on the polygon boundary
    clip : None, or (2,) int
      Clip sample count to min of clip[0] and max of clip[1]

    Returns
    ----------
    edges : (n, 2) int
      Vertex indices representing line segments
      on the polygon's medial axis
    vertices : (m, 2) float
      Vertex positions in space
    r   rz   rg   )scaleradiusi  h㈵>centerr   r   )Voronoi
vectorizedd   )r;   r   r   F)!r!   ru   r"   ptpreshaper   r2   r   rX   rj   r   infr#   r   r   scipy.spatialr   shapelyr   r   r   r-   rJ   Tr6   ri   ridge_verticesalluniquezerosarangerl   rm   )r;   r   r   r   fitepsilonrJ   r7   r   r   samplesvoronoir-   ridge	containedmaskedges_finals                    rH   medial_axisr   |  s=   0 7"rzz'..&9BFFHw//66eD?ggc(mc14@GxxX!W-s8}7|/KLjjH
 HHq!fXRXX6E(?"%"VVBJJw~~v>QGKKMPSS
 "'jtTGw'GgG"z""7@W-=-=-?-?@Hyy5)HMM'00AE(5/%%1%-.E 		% I88C(():DiiI/DO 	*Hu+K
zzvvh{+g.>.>u.EEFMMM  ra   returnc                 h   t        | j                        | j                  j                  | j                  j                  | j                  | j                  | j
                  j                  g}t        | d      \  }}}}|j                  |       t        j                  |t        j                        S )a  
    Return a vector containing values representative of
    a particular polygon.

    Parameters
    ---------
    polygon : shapely.geometry.Polygon
      Input geometry

    Returns
    ---------
    identifier : (8,) float
      Values which should be unique for this polygon.
    T)return_centeredr   )r!   ru   convex_hullarear   rX   second_momentsr4   r"   r#   r   )r;   rw   _	principals       rH   
identifierr     s      	G  ""F (FAy!Q
MM)88F"**--ra   c                 `   t        j                  t        j                  t         j                  j                  |       t         j                  z  dz        t         j                  dz  z        }t         j                  j                  |       |z  }t        j
                  t        j                  |      t        j                  |      f      |j                  d      z  }t        j                  ||d   f      }t        |      j                  d      }t        |d      r|j                  d   S |S )a  
    Generate a random polygon with a maximum number of sides and approximate radius.

    Parameters
    ---------
    segments : int
      The maximum number of sides the random polygon will have
    radius : float
      The approximate radius of the polygon desired

    Returns
    ---------
    polygon : shapely.geometry.Polygon
      Geometry object with random exterior and no interiors.
    r   )r   r           rN   )r"   sortcumsumrandompicolumn_stackcossinr   r   r   bufferrV   rN   )segmentsr   anglesradiird   r;   s         rH   random_polygonr     s      WWRYYryy//9BEEAAEF"%%RS)TUFIIX&/E__bffVnbffVn=>wAWWFYYq	*+Ffo$$S)Gw }}QNra   c                     t        j                  t        j                  | j                  d      d      }|dz  j	                         dz  }|S )z
    For a Polygon object return the diagonal length of the AABB.

    Parameters
    ------------
    polygon : shapely.geometry.Polygon
      Source geometry

    Returns
    ------------
    scale : float
      Length of AABB diagonal
    rz   r   rg   r         ?)r"   r   r   r   sum)r;   rq   r   s      rH   polygon_scaler     s?     ffRZZ7a@GaZ#%ELra   c                 L   dgt        |       z  }t        |       D ]A  \  }}t        |      dk  r	 t        |      }|j                  r|||<   nt	        ||      ||<   C t        j                  |      }|S # t
        $ r Y ft        $ r t        j                  dd       Y w xY w)aV  
    Given a sequence of connected points turn them into
    valid shapely Polygon objects.

    Parameters
    -----------
    paths : (n,) sequence
      Of (m, 2) float closed paths
    scale : float
      Approximate scale of drawing for precision

    Returns
    -----------
    polys : (p,) list
      Filled with Polygon or None

    Nr   zunrecoverable polygonT)exc_info)r!   r%   r   is_validrU   rW   BaseExceptionr
   errorr"   r#   )pathsr   r9   r:   pathr;   s         rH   paths_to_polygonsr     s    $ vE
"HU#4t9q= 
	>dmG%,We< $" xx!HO  	 	>II-=	>s   ,A66	B#B#"B#c                    ddl m} t        j                  | j                  d      }t        j
                  |d      }t        ||z        }|d   |t        j                  j                  |df      z  z   } |j                  | g|j                   }	||	   g}
t        |
d         }||k\  r|
d   d| S t        |      D ]u  }t        j                  j                  |df      |z  |d   z   } |j                  | g|j                   }	|
j                  ||	          |t        |
d         z  }||kD  su n t        j                  |
      d| }
|
S )a  
    Use rejection sampling to generate random points inside a
    polygon. Note that this function may return fewer or no
    points, in particular if the polygon as very little area
    compared to the area of the axis-aligned bounding box.

    Parameters
    -----------
    polygon : shapely.geometry.Polygon
      Polygon that will contain points
    count : int
      Number of points to return
    factor : float
      How many points to test per loop
    max_iter : int
      Maximum number of intersection checks is:
      > count * factor * max_iter

    Returns
    -----------
    hit : (n, 2) float
      Random points inside polygon
      where n <= count
    r   r   rz   rg   r   Nr   )r   r   r"   r   r   r   r   r   r-   r   r!   ranger6   r   )r;   r   factormax_iterr   r   rq   per_looprd   r   hit	hit_countr   s                rH   sampler   B  sI   4 # ZZ/FffV!$G 56>"H AY299#3#3XqM#BBBF:w22D$<.CCFIE1vfu~ 8_))""Ha=1G;vayH"z""76VXX6

6$< SR\!	u  ))C.%
 CJra   c                    t        | d      r| j                  r| S | j                  t        j                        }t        |d      rD|j
                  t        j                  |j
                  D cg c]  }|j                   c}         }|j                  r.t        j                  |j                  | j                  |      r|S |Gdt        j                  t        j                  | j                  d      d      j                         z  }nd|z  }t        | j                         dk(  rA| j"                  j                  |      j                   }t        |      dk(  rXt%        |d   	      j                  |      }|j                  r.t        j                  |j                  | j                  |      r|S t        j&                  | j"                  j(                        }t        j*                  d
t        j,                  |d      dz  j/                  d      dz  dkD        }	t%        ||	   	      }
|
j                  r.t        j                  |
j                  | j                  |      r|
S | j                  |      j                  |       }t        |d      rTt        j&                  |j
                  D cg c]  }|j                   c}      }|j
                  |j                            S |j                  rCt        j                  |j                  | j                  |      rt1        j2                  d       |S t5        d      c c}w c c}w )a  
    Given a shapely.geometry.Polygon, attempt to return a
    valid version of the polygon through buffering tricks.

    Parameters
    -----------
    polygon : shapely.geometry.Polygon
      Source geometry
    rtol : float
      How close does a perimeter have to be
    scale : float or None
      For numerical precision reference

    Returns
    ----------
    repaired : shapely.geometry.Polygon
      Repaired polygon

    Raises
    ----------
    ValueError
      If polygon can't be repaired
    r   rN   )rtolgMb`?rz   r   rg   r   )rP   Tr   r   g:0yE>z2Recovered invalid polygon through double bufferingzunable to recover polygon!)rV   r   r   rl   zerorN   r"   argmaxr   iscloser   r   r   r   meanr!   ru   rX   r   r#   rj   r6   diffr   r
   debugrW   )r;   r   r   basicr:   distanceringsreconrd   r   dedupebufferedr?   areass                 rH   rU   rU     sx   0 w
#(8(8 NN388$EugBIIu{{&C{!qvv{&CDE ~~"**U\\7>>M}266"**W^^V"D1MRRTT5= 7"   ''1;;u:?%(+228<E~~"**U\\7>>PT"U '**112 4"''&q"9Q">!C!C!C!Ks!RUY!YZvf~.??rzz&--dSM ~~h'..y9Hx!(..9.Q!&&.9:~~elln-- RZZdS		FG
1
22a 'DP :s   .M
6Mpreciseprecise_epsc	                 4   t        j                  |t         j                        }|t         j                  j	                  |      z  }t        j
                  || j                  j                        }	|rz|	|kD  }
|	| k  }t        j                  |
j                         |j                         g      }|j                         dk(  r|j                         }n|j                         }|
|g|   }n|	|kD  }|| j                     j                  d      }| j                  |   }t        j                  ||      }t!        | j"                  |      ddddf   }|r| j$                  |   }t'        t        j(                  t        j*                  |            dz         }t        j,                  ||      }|t        j.                  ||ddddf   f         }|ddg df   |ddg d	f   k(  j                  d      j1                  d       }t3        j4                  ||   D cg c]  }t7        |       c}      j9                  |      j9                  |       S t;        j<                  |t        j>                  |      d   
      }| j@                  jC                  d      }g }|D ]L  }||   jC                  d      }tE        jF                  |d      }|jI                  tK        ||   |             N d}||tM        |      z  }|7t        jN                  |d      jQ                         }|tM        |      |z  z  }n"tS        |      dk(  r|d   S tS        |      dk(  rytU        d |      } | !| j9                  |      j9                  |       S yc c}w )a  
    Project a mesh onto a plane and then extract the polygon
    that outlines the mesh projection on that plane.

    Note that this will ignore back-faces, which is only
    relevant if the source mesh isn't watertight.

    Also padding: this generates a result by unioning the
    polygons of multiple connected regions, which requires
    the polygons be padded by a distance so that a polygon
    union produces a single coherent result. This distance
    is calculated as: `apad + (rpad * scale)`

    Parameters
    ----------
    mesh : trimesh.Trimesh
      Source geometry
    normal : (3,) float
      Normal to extract flat pattern along
    origin : None or (3,) float
      Origin of plane to project mesh onto
    ignore_sign : bool
      Allow a projection from the normal vector in
      either direction: this provides a substantial speedup
      on watertight meshes where the direction is irrelevant
      but if you have a triangle soup and want to discard
      backfaces you should set this to False.
    rpad : float
      Proportion to pad polygons by before unioning
      and then de-padding result by to avoid zero-width gaps.
    apad : float
      Absolute padding to pad polygons by before unioning
      and then de-padding result by to avoid zero-width gaps.
    tol_dot : float
      Tolerance for discarding on-edge triangles.
    precise : bool
      Use the precise projection computation using shapely.
    precise_eps : float
      Tolerance for precise triangle checks.

    Returns
    ----------
    projected : shapely.geometry.Polygon or None
      Outline of source mesh

    Raises
    ---------
    ValueError
      If max_regions is exceeded
    r   r   r   rg   )originnormalNr   )r   r   r   )r   r   r   )nodes)r      )r   r   )require_count)r7   rJ   r   c                 $    | j                  |      S r   )union)ar?   s     rH   <lambda>zprojected.<locals>.<lambda>w  s    !''!*ra   )+r"   r#   r   linalgnormdotface_normalsr   r   ro   r   argminface_adjacencyr   r   plane_transformr   rJ   facesr   abslog10roundr   anyr   unary_unionr   r   r   connected_componentsnonzeroedges_sortedr   r	   
group_rowsr4   rZ   floatr   r2   r!   r   )!meshr   r   ignore_signrpadapadtol_dotr   r   dot_facefrontbackr   picksideadjacency_check	adjacencyto_2Dvertices_2Dr  digitsrounded	trianglesvalidfface_groupsr7   r9   edgegrouppaddingr   reduceds!                                    rH   	projectedr0    sW   | XXfBJJ/F
biinnV$$F vvfd//112H 7"7(" %))+txxz2399;!<<>D <<>Dt}T" '! 4../333;O##O4I $$F6BE"4==%8BQB?K 

4  RVVBHH[12Q67((;/BOOUE!RaR%L,ABC	 AyL)Yq)|-DDIIqIQUU V 
 
 OO51AB1AAWQZ1ABCVK V[L!	
 ,,Ybjj>Nq>QRK %%g.EHU|##G,##D:)UkRS  G5;{+//15;&& 
X!	{	X!	 4h?G ~~g&--wh77 Q Cs   $Nc                    t        j                  d      }|r=t        j                  | j                  j                         |dddf<   t        | |      } t        j                  | j                  j                        }t        j                  |d   |dd f      j                  \  }}|j                  \  }}||z  ||z  z
  }t        j                  |||z  ||z  z   ||z  z   z        dz  }	t        j                  |||z  ||z  z   ||z  z   z        dz  }
t        j                  |||z  d|z  |z  z   d|z  |z  z   ||z  z   z        dz  }| j                  D ]  }t        j                  |j                        }t        j                  |d   |dd f      j                  \  }}|j                  \  }}||z  ||z  z
  }|	t        j                  |||z  ||z  z   ||z  z   z        dz  z  }	|
t        j                  |||z  ||z  z   ||z  z   z        dz  z  }
|t        j                  |||z  d|z  |z  z   d|z  |z  z   ||z  z   z        dz  z  } |	|
|g}|s|S t        j                  |
|	z
  dz  dz  |dz  z         }|	|
z   dz  |z   }|	|
z   dz  |z
  }||g}t        j                  |dd	
      rd}nKt        j                  |	|
      rdt         j                  z  }n!dt        j                  d|z  |	|
z
  z        z  }t        j                  |      }t        j                   |      }||d<   ||d<   | |d<   ||d<   ||||fS )a>  
    Calculate the second moments of area of a polygon
    from the boundary.

    Parameters
    ------------
    polygon : shapely.geometry.Polygon
      Closed polygon.
    return_centered : bool
      Get second moments for a frame with origin at the centroid
      and perform a principal axis transformation.

    Returns
    ----------
    moments : (3,) float
      The values of `[Ixx, Iyy, Ixy]`
    principal_moments : (2,) float
      Principal second moments of inertia: `[Imax, Imin]`
      Only returned if `centered`.
    alpha : float
      Angle by which the polygon needs to be rotated, so the
      principal axis align with the X and Y axis.
      Only returned if `centered`.
    transform : (3, 3) float
      Transformation matrix which rotates the polygon by alpha.
      Only returned if `centered`.
    ry   Nr   r   g      (@g      8@rf   r   g-q=)atolr   g      ?r   )r   r   )r   r   )r   r   )r   r   )r"   eyer#   centroidrj   rt   rX   r   r   r   ru   sqrtr   r   arctanr   r   )r;   r   rp   rj   x1y1x2y2r=   IxxIyyIxyr   momentsrF   ImaxIminprincipal_momentsalpha	cos_alpha	sin_alphas                        rH   r   r   ~  si   : q	IHHW%5%5%<%<==	"1"a%#GY7 XXg&&--.FYYr
F3BK0133FBXXFB
R"r'A
&&b2gR'"r'12
3d
:C
&&b2gR'"r'12
3d
:C
&&b2gB+a"frk9BGCD
E
LC%%(//*F2Js4577BBGb2grvva27R"W,rBw6784??rvva27R"W,rBw6784??rvva27QVb[01r6B;>bHIJTQQ & CoG 77S3Y#%!+c1f45D#It#D#It#Dt 
zz#s'	C	ruubiic	S3Y 788 uIuIIdOIdO jIdOIdO%ui77ra   r   )NTN)NN)r   g      ?)g      ?
   )Nr   )NTr   N绽|=FrF  )F)<numpyr"   r   r   shapely.geometryr    r   r   r   r	   	constantsr
   r   rl   	iterationr   transformationsr   typedr   r   r   r   r   r   r   r   simplifyr   	traversalr   networkxr   r   E
exceptionsr   rtree.indexr   rI   rZ   r`   r\   rt   r|   r   r  r   r   r   r   r   r   r   r   rU   boolr0  r    ra   rH   <module>rV     s     $ 0 0  ' & . Y Y Y & $ !Zz1WU^ 1ww7G 1h65'!2I!=> 6"w/0 "J@8#L# #e #LL(L! L!hv.> L!^. .GG$4 .>6(&RAHP3l 		b8 b8 b8JV8G V8]   .	!	B   -QE	 s0   C$ D $D)C<<DD!	DD!