
    Tiy}                        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!n## e"$ rZ#ddl$m%Z%  e%e#          Z!Y dZ#[#ndZ#[#ww xY w	 d dl&m'Z' n## e"$ rZ#ddl$m%Z%  e%e#          Z'Y dZ#[#ndZ#[#ww xY w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,d3dZ-d4dZ.d3dede/fdZ0d Z1d5dedee         fdZ2ded ee         fd!Z3d6d$Z4d% Z5d3d&Z6d7d)Z7d8d+Z8	 	 	 	 	 	 	 d9d/e9d0e/fd1Z:d:defd2Z;dS );    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    r8|                    d           t          j        dgt          j                  |fS d d t          |           D                                             D             }|	                     |j
                               t          |          dk    rIt          t           |j
                     |j                    dgt          |          z                      } |j                    D ]\  }}|                    |          D ]x}||k    r	| |                             | |                   r|                    ||           A| |                             | |                   r|                    ||           yt#          |                                          t          j        t'          
                                                    }t          j        t'                                                              }||dz  dk             }	t          |          dk    r|                                dk    rg }
|	t          j        fd|	D                                }	|	D ]d}|||         dz   k             }|
                    |                    t          j        ||                                                               et          j        |
t          j                              }|	                    |	           |	|fS )	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   c                 @    i | ]\  }}t          |          d k    ||S )   )len).0kvs      O/DATA/AppData/hermes/venv/lib/python3.11/site-packages/trimesh/path/polygons.py
<dictcomp>z"enclosure_tree.<locals>.<dictcomp>A   s9       Aq q66Q;;	 	
1 ;;    c                 8    i | ]\  }}|t          |d g           S )r   )getattr)r"   ipolygons      r%   r&   z"enclosure_tree.<locals>.<dictcomp>C   s7     
 
 
2<!WAww"--
 
 
r'   Nr   c                      g | ]
}|         S  r-   )r"   rdegrees     r%   
<listcomp>z"enclosure_tree.<locals>.<listcomp>o   s    !;!;!;&)!;!;!;r'   )nxDiGraphr!   nparrayr   add_node	enumerateitemsadd_nodes_fromkeysr   zipvaluesintersectioncontainsadd_edgedict	in_degreelistmaxargsortextendsubgraphappendedgesfrom_edgelist)polygonsr=   r   treer*   bjindexesdegreesrootsrG   rootchildrenr/   s                @r%   enclosure_treerR      s?   0 z||H
8}}x"(+++X55	X!		!x28,,,h66 
 
@I(@S@S
 
 

%''	  F KFKMM***
6{{Q
 S$#f++9MNNOO  ( (1""1%% 		( 		(AAvv {##HQK00 (!!!Q''''!%%hqk22 (!!!Q'''		( ($$&&''FhtFKKMM**++GhtFMMOO,,--GWq[Q&'E 7||aGKKMMA--bj!;!;!;!;U!;!;!;<<= 	O 	ODw&,*::;HLL**29Xt+D+DEEKKMMNNNN#E2:<<88&&&(?r'   rG   verticesc                    t          |t          j                  sJ g t          j        | d          D ]u}	 t          t          ||                             }t          |d          r                    |j	                   n
                    |           f# t          $ r Y rw xY wt                    dk    rS t                    \  }fd|D             S )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   c                     g | ]B}t          |         j        fd |                                         D                       CS )c                 *    g | ]}|         j         S r-   )exterior)r"   r*   rI   s     r%   r0   z0edges_to_polygons.<locals>.<listcomp>.<listcomp>   s     CCCA8A;'CCCr'   shellholes)r   rZ   r9   )r"   rP   rI   rJ   s     r%   r0   z%edges_to_polygons.<locals>.<listcomp>   si       
 	 	4.)CCCCd1B1BCCC	
 	
 	
  r'   )
isinstancer3   ndarrayr	   
traversalsrepair_invalidr   hasattrrD   rW   rF   
ValueErrorr!   rR   )rG   rS   rU   repairedrO   rI   rJ   s        @@r%   edges_to_polygonsre   |   s   $ h
+++++ HE222 
 
		%ghsm&<&<==Hx)) *////))) 	 	 	H	 8}} !**KE4    
    s   A"B
B*)B*rI   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!   r6   polygon_obbr3   r4   )rI   
rectangles
transformsr*   ps        r%   polygons_obbrk      s|     #h--'J#h--'J(## 6 61'21~~$
1z!}}8J*!5!555r'   r+   c                    t          | d          rt          j        | j        j                  }n,t          | t          j                  r| }nt          d          t          j	        |          \  }}t          j        rnt          ||          }t          j        | dz  |                    d                    sJ t          j        |dz  |                    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
    rZ   z"polygon or points must be providedpointsmatrix       @r   axis)rb   r3   
asanyarrayrZ   coordsr^   r_   rc   r   oriented_bounds_2Dtolstrictr   allcloseminrB   )r+   rn   	transformextentsmoveds        r%   rg   rg      s    ( w
## ?w/677	GRZ	(	( ?=>>>26::Iw
z = yAAA{G8c>599!9+<+<====={7S=%)))*;*;<<<<<gr'   c                 X   t          j        t           j                  t          | d          rd t	          |           D             }|S t          t          j        | j        j                            ddddf         }fd| j	        D             }t          ||          }|S )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   rW   c                 4    g | ]\  }}t          ||          S r-   )transform_polygon)r"   rj   ts      r%   r0   z%transform_polygon.<locals>.<listcomp>   s'    KKKda#Aq))KKKr'   Nr   c                 v    g | ]5}t          t          j        |j                            d d d df         6S )Nr   )r   r3   r4   rt   )r"   r*   ro   s     r%   r0   z%transform_polygon.<locals>.<listcomp>   sN       @A!(++V44QQQU;  r'   r[   )r3   rs   r   rb   r:   r   r4   rZ   rt   	interiorsr   )r+   ro   resultr\   r]   s    `   r%   r   r      s      ]6444Fw   KKc'66J6JKKKRXg&6&=>>GG2A2NE   ELEV  E 5...FMr'   c                 R   |;|j         dk    sJ t          t          j        | j        j                  |          }nt          j        | j        j                  }t          j        |                    d          |                    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.
    N)   r   rm   r   rq   r   r   )shaper   r3   r4   rZ   rt   ry   rB   )r+   ro   rn   r   s       r%   polygon_boundsr      s    " |v%%%%!'2B2I)J)JSYZZZ'*122Xvzzqz))6::1:+=+=>??F<6!!!!Mr'   Tc                 H   ddl m} fd|                                                    dd           | j        j        dk    rfd| j        D              n,t          | d          rfd	| D              n|  |            |r|                                 S )
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                 n     j         | j        j        i  | j        D ]} j         |j        i  d S N)plotrZ   xyr   )singleinterioraxeskwargss     r%   plot_singlezplot.<locals>.plot_single+  sW    	6?%0000( 	. 	.HDIx{-f----	. 	.r'   equaldatalimMultiPolygonc                 &    g | ]} |          S r-   r-   r"   r*   r   s     r%   r0   zplot.<locals>.<listcomp>6  s!    ///AQ///r'   __iter__c                 &    g | ]} |          S r-   r-   r   s     r%   r0   zplot.<locals>.<listcomp>8  s!    )))AQ)))r'   )	matplotlib.pyplotpyplotr   
set_aspect	__class____name__rW   rb   show)r+   r   r   r   pltr   s     `` @r%   r   r     s     $#####. . . . . . |xxzzOOGY'''!^33/////////	*	%	% )))))))))		G 


Kr'   
resolutionc                     fd}ddg || j                   g d}| j        D ]&}|d                              ||                     '|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R            }t	          | j        |          S )N)count)lengthintr3   clipr   rt   )boundaryr   r   r   s     r%   resample_boundaryz.resample_boundaries.<locals>.resample_boundaryW  sE     *,BGE)D)))**X_E::::r'   N      r[   r]   )rZ   r   rF   )r+   r   r   r   r   r   s    ``   r%   resample_boundariesr   B  s    *; ; ; ; ; ; |3x(()9::RHHF% < <w00::;;;;Mr'   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
    r]   r   r\   )r!   r3   vstack)
boundariess    r%   stack_boundariesr   h  sP     :g1$$'""9j)29Z5H+I+IJKKKr'   c                 X   t          | j                  dk    rt          j        t          j        | j        d          d                                          }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}	 |Ct          j        t          j        | j        d          d                                          dz  }t'          | ||          }
t)          |
          }
 ||
          } |	j        | g|j        j        R  }t          j        |d          }t          j        |j        t          j        
          }|||                             d                   }t          j        |          }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   r   rq   )scaleNradiusi  h㈵>centerr   r   )Voronoi
vectorizedd   )r+   r   r   F)!r!   r   r3   ptpreshaper   rB   r   rZ   rt   r   infr4   r   r   scipy.spatialr   shapelyr   r   r   r=   rS   TrF   rs   ridge_verticesalluniquezerosarangerv   rw   )r+   r   r   r   fitepsilonrS   rG   r   r   samplesvoronoir=   ridge	containedmaskedges_finals                    r%   medial_axisr   |  s   0 7""rz'.&99BBBFFHHw/6eDDD?gc(mc14@@GxX!W-s8}7|/KLj  H
 Hq!fXRX666E(?"%%%%%%""""""VBJw~v>>QGGGKKMMPSS
 "'jtTTTGw''GggG"z"7@W-=-?@@@Hy5))HM'0AAAE(5/%%1%--.E 	%  I8C()):::DiI//DO 	*Hu+K
z Nvh{+g.>u.EEFFMMMM  r'   returnc                    t          | j                  | j        j        | j        j        | j        | j        | j        j        g}t          | d          \  }}}}|                    |           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!   r   convex_hullarear   rZ   second_momentsrD   r3   r4   r   )r+   r   _	principals       r%   
identifierr     s      	G "F (FFFAy!Q
MM)8F"*----r'   r         ?c                 f   t          j        t          j        t           j                            |           t           j        z  dz            t           j        dz  z            }t           j                            |           |z  }t          j        t          j        |          t          j        |          f          |                    d          z  }t          j	        ||d         f          }t          |                              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           rW   )r3   sortcumsumrandompicolumn_stackcossinr   r   r   bufferrb   rW   )segmentsr   anglesradiirn   r+   s         r%   random_polygonr     s      WRYry//99BEAAEFF"%RS)TUUFIX&&/E_bfVnnbfVnn=>>wAWAWWFYq	*++Ffoo$$S))Gw    }QNr'   c                     t          j        t          j        | j        d          d          }|dz                                  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
    r   r   rq   r         ?)r3   r   r   r   sum)r+   r{   r   s      r%   polygon_scaler     sE     fRZ77a@@@GaZ#%ELr'   c                 h   dgt          |           z  }t          |           D ]z\  }}t          |          dk     r	 t          |          }|j        r|||<   nt	          ||          ||<   J# t
          $ r Y Vt          $ r t          j        dd           Y ww xY wt          j
        |          }|S )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!   r6   r   is_validra   rc   BaseExceptionr   errorr3   r4   )pathsr   rI   r*   pathr+   s         r%   paths_to_polygonsr     s    $ vE

"HU## > >4t99q== 
	>dmmG =%,We<< 	 	 	H 	> 	> 	>I-======	>x!!HOs   /A--
B9BB      ?
   c                    ddl m} t          j        | j        d          }t          j        |d          }t          ||z            }|d         |t          j                            |df          z  z   } |j        | g|j	        R  }	||	         g}
t          |
d                   }||k    r|
d         d|         S t          |          D ]}}t          j                            |df          |z  |d         z   } |j        | g|j	        R  }	|
                    ||	                    |t          |
d                   z  }||k    r 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   r   rq   r   Nr   )r   r   r3   r   r   r   r   r   r=   r   r!   rangerF   r   )r+   r   factormax_iterr   r   r{   per_looprn   r   hit	hit_countr   s                r%   sampler   B  s   4 #""""" Z//FfV!$$$G 56>""H AY29#3#3XqM#B#BBBF:w2222D$<.CCFIE1vfuf~ 8__ 
 
)""Ha=11G;vayH"z"76VX666

6$<   SR\\!	uE  )C..%
 CJr'   r   c                    t          | d          r	| j        r| S |                     t          j                  }t          |d          r.|j        t          j        d |j        D                                }|j        r#t          j        |j	        | j	        |          r|S |Ddt          j
        t          j        | j        d          d	                                          z  }nd|z  }t          | j                  dk    r*| j                            |          j        }t          |          d
k    rSt#          |d                                       |          }|j        r#t          j        |j	        | j	        |          r|S t          j        | j        j                  }t          j        dt          j        |d	          dz                      d
	          dz  dk              }t#          ||                   }	|	j        r#t          j        |	j	        | j	        |          r|	S |                     |                              |           }
t          |
d          rBt          j        d |
j        D                       }|
j        |                                         S |
j        r7t          j        |
j	        | j	        |          rt/          j        d           |
S t3          d          )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   rW   c                     g | ]	}|j         
S r-   r   )r"   r*   s     r%   r0   z"repair_invalid.<locals>.<listcomp>  s    &C&C&C!qv&C&C&Cr'   )rtolNgMb`?r   r   rq   r   )r\   Tr   r   g:0yE>c                     g | ]	}|j         
S r-   r   )r"   rK   s     r%   r0   z"repair_invalid.<locals>.<listcomp>  s    999Q!&999r'   z2Recovered invalid polygon through double bufferingzunable to recover polygon!)rb   r   r   rv   zerorW   r3   argmaxiscloser   r   r   r   meanr!   r   rZ   r   r4   rt   rF   diffr   r   debugrc   )r+   r   r   basicdistanceringsreconrn   r   dedupebufferedareass               r%   ra   ra     s   0 w
## (8  NN38$$Eug FBI&C&Cu{&C&C&CDDE ~ "*U\7>MMM }26"*W^V"D"D1MMMRRTTT5= 7""  ''11;u::??%(+++228<<E~ "*U\7>PT"U"U"U  '*122 4"'&q"9"9"9Q">!C!C!C!K!Ks!RUY!YZZvf~...? 	rz&-dSSS 	M ~~h''..y99Hx!! .99(.999::~ellnn--  RZdSSS 	FGGG
1
2
22r'   r   绽|=Fpreciseprecise_epsc	                    t          j        |t           j                  }|t           j                            |          z  }t          j        || j        j                  }	|r|	|k    }
|	| k     }t          j        |
                                |                                g          }|	                                dk    r|
                                }n|                                }|
|g|         }n|	|k    }|| 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                        d                              d           }t3          j        d
 ||         D                                           |                              |           S t9          j        |t          j        |          d                   }| j                             d          }g }|D ]]}||                              d          }tC          j"        |d          }|#                    tI          ||         |                     ^d}||tK          |          z  }|>t          j&        |d          '                                }|tK          |          |z  z  }n0tQ          |          dk    r|d         S tQ          |          dk    rdS tS          d |          }|)|                    |                              |           S dS )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   rq   )originnormalNr   )r   r   r   )r   r   r   c                 ,    g | ]}t          |          S r-   r   )r"   fs     r%   r0   zprojected.<locals>.<listcomp>R  s    BBBAWQZZBBBr'   )nodes)r      )r   r   )require_count)rG   rS   r   c                 ,    |                      |          S r   )union)arK   s     r%   <lambda>zprojected.<locals>.<lambda>w  s    !''!** r'   )*r3   r4   r   linalgnormdotface_normalsr   r   ry   r  argminface_adjacencyr   r   plane_transformr   rS   facesr   abslog10roundr   anyr   unary_unionr   r	   connected_componentsnonzeroedges_sortedr   r
   
group_rowsrD   re   floatr   rB   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face_groupsrG   rI   edgegrouppaddingr   reduceds                                    r%   	projectedrG    s   | XfBJ///F
binnV$$$F vfd/122H " 7"7(" %))++txxzz23399;;!<<>>DD <<>>Dt}T" '! 4./333;;O#O4I $F6BBBE"4=%88BQB?K 
 
4  RVBH[1122Q677(;//BOUE!!!RaR%L,ABBC	 AAAyyyL)Yqqq)))|-DDIIqIQQUU V 
 
 
 OBB51ABBBCCVK  V[L!!	
 ,Ybj>N>Nq>QRRRK %%g..EH T TU|##G,,#D:::)UkRRRSSSSG5;;{+++//115;;&& 
X!		{	X!		t 44h??G ~~g&&--wh777 r'   c                    t          j        d          }|r6t          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}nEt          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`.
    r   Nr   r   g      (@g      8@rp   r   g-q=)atolr   g      ?r   )r   r   )r   r   )r   r   )r   r   )r3   eyer4   centroidrt   r   rZ   r   r   r   r   sqrtr  r   arctanr   r   )r+   r   rz   rt   x1y1x2y2r$   IxxIyyIxyr   momentsrP   ImaxIminprincipal_momentsalpha	cos_alpha	sin_alphas                        r%   r   r   ~  s   : q		I 8HW%5%<===	"1"a%#GY77 Xg&-..FYr
F3B3K0113FBXFB
R"r'A
&b2gR'"r'12
3
3d
:C
&b2gR'"r'12
3
3d
:C
&b2gB+a"frk9BGCD
E
E
LC% 	R 	R(/**F2Jss4557BBGb2grva27R"W,rBw67884??rva27R"W,rBw67884??rva27QVb[01r6B;>bHIJJTQQCoG  7S3Y#%!+c1f455D#It#D#It#Dt 
z#s''' 9	C		 9rubic	S3Y 7888 uIuIIdOIdO jIdOIdO%ui77r'   r   )NTN)NN)r   r   )r   r   )Nr   )NTr   Nr  Fr  )F)<numpyr3   r   r   shapely.geometryr    r   r   r	   r
   	constantsr   r   rv   	iterationr   transformationsr   typedr   r   r   r   r   r   r   r   simplifyr   	traversalr   networkxr1   r   E
exceptionsr   rtree.indexr   rR   re   rk   rg   r   r   r   r/  r   r   r   r   r   r   r   r   ra   boolrG  r   r-   r'   r%   <module>rj     s             $ $ $ $ $ $ 0 0 0 0 0 0 0 0 0 0 0 0       ' ' ' ' ' ' & & & & & & . . . . . . Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y & & & & & & $ $ $ $ $ $    .-----		!		BBBBBB !!!!!!!      ------QEEEEEE	 Z Z Zz1WU^ 1ww7G 1 1 1 1h65'!2I!=> 6 6 6 6"w/0 " " " "J  @   8# # # #L# # #e # # # #LL L L(L! L! L!hv.> L! L! L! L!^. .GG$4 . . . .>   6  (& & & &RA A A AHP3 P3 P3 P3l 		b8 b8 b8 b8 b8 b8 b8JV8 V8G V8 V8 V8 V8 V8 V8s0   A A; A66A;?B B&B!!B&