
    Miy}                     p   S SK rS SKJr  S SKJr  SSKJrJrJ	r	J
r
  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJrJrJrJrJrJrJrJr  SSKJr  SSKJr   S SK r! S SK&J'r'  S r(S\\   S\\   4S jr)S\\\   \4   4S jr*S\\\4   4S jr+S r,S*S jr-S+S jr.S*S\S\/4S jjr0S r1S,S\S\\   4S jjr2S\S\\   4S  jr3S-S! jr4S" r5S*S# jr6S.S$ jr7S/S% jr8       S0S&\9S'\/4S( jjr:S1S\4S) jjr;g! \" a  r#SSK$J%r%  \%" \#5      r! Sr#C#NSr#C#ff = f! \" a  r#SSK$J%r%  \%" \#5      r' Sr#C#NSr#C#ff = f)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           
         [         R                  " 5       n[        U 5      S:X  a%  [        R                  " / [        R
                  S9U4$ [        U 5      S:X  a7  UR                  S5        [        R                  " S/[        R
                  S9U4$ [        U 5       VVs0 s H  u  p#U[        US/ 5      _M     snnR                  5        VVs0 s H  u  pE[        U5      S:X  d  M  XE_M     nnnUR                  UR                  " 5       5        [        U5      S:  aA  [        [        UR                  " 5       UR                  " 5       S/[        U5      -  5      5      nUR                  " 5        H~  u  p(WR                  U5       Hd  n	X):X  a  M
  X   R!                  X	   5      (       a  UR#                  X)5        M7  X	   R!                  X   5      (       d  MS  UR#                  X5        Mf     M     [%        UR'                  5       5      n
[        R                  " [)        U
R                  5       5      5      n[        R                  " [)        U
R                  5       5      5      nXS-  S:H     n[        U5      S:  a  UR+                  5       S:  a  / nU[        R,                  " U Vs/ s H  oU   PM	     sn5         nU HS  nXU
U   S-   :H     nUR/                  UR1                  [        R2                  " UU5      5      R5                  5       5        MU     [         R6                  " U[         R                  " 5       5      nUR                  U5        X4$ s  snnf s  snnf s  snf )a6  
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                     o/var/www/eduai.edurigo.com/storigo/production/storigo_env/lib/python3.13/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*!Aww"--@S

%'DA q6Q;	 	   FKKM*
6{Q
 S$#f+9MNO ""1%Av {##HK00!!!'%%hk22!!!' &  ($$&'FhhtFKKM*+GhhtFMMO,-Gq[Q&'E 7|aGKKMA-bjjU!;U)U!;<=D&,*::;HLL**299Xt+DEKKMN  ##E2::<8&?m
\ "<s   MM&M)M#
r7   verticesc                 L   [        U[        R                  5      (       d   e/ n[        R                  " U SS9 HY  n [        [        X   5      5      n[        US5      (       a  UR                  UR                  5        MH  UR                  U5        M[     [        U5      S:X  a  U$ [        U5      u  pVU VVs/ s HF  n[        X'   R                  Xg   R                  5        Vs/ s H  oU   R                  PM     snS9PMH     snn$ ! [         a     M  f = fs  snf s  snnf )aC  
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		%ghm&<=Hx))/) 3 8} !*KE 
 D	 	.))151BC1BAA;''1BC	
    		 Ds0   AD
D
9,D %D=	D 

DDD r9   c                     S/[        U 5      -  nS/[        U 5      -  n[        U 5       H  u  p4[        U5      u  X#'   X'   M     [        R                  " U5      [        R                  " U5      4$ )z7
Find the OBBs for a list of shapely.geometry.Polygons
N)r!   r%   polygon_obbr"   r#   )r9   
rectangles
transformsr:   ps        rH   polygons_obbr`      sd     #h-'J#h-'J(#'21~$
z} $88J*!555    r;   c                     [        U S5      (       a+  [        R                  " U R                  R                  5      nO-[        U [        R                  5      (       a  U nO[        S5      e[        R                  " U5      u  p#[        R                  (       af  [        XS9n[        R                  " U* S-  UR                  SS95      (       d   e[        R                  " US-  UR                  SS95      (       d   eX#4$ )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:I
zz A{{G8c>599!9+<===={{7S=%)))*;<<<<ra   c                    [         R                  " U[         R                  S9n[        U S5      (       a*  [	        X5       VVs/ s H  u  p#[        X#5      PM     nnnU$ [        [         R                  " U R                  R                  5      U5      SS2SS24   nU R                   Vs/ s H6  n[        [         R                  " UR                  5      U5      SS2SS24   PM8     nn[        XWS9nU$ s  snnf s  snf )a&  
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'6JK6Jda#A)6JKRXXg&6&6&=&=>G2A2NE FMEVEVEV!((+V4QU;EV 
  5.FM L
s   C4*=C:c                 r   UbE  UR                   S:X  d   e[        [        R                  " U R                  R
                  5      US9nO*[        R                  " U R                  R
                  5      n[        R                  " UR                  SS9UR                  SS9/5      nUR                   S:X  d   eU$ )aO  
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                   ^^ SSK Jn  UU4S jnTc  UR                  5       mTR                  SS5        U R                  R
                  S:X  a"  U R                   Vs/ s H
  oe" U5      PM       nO4[        U S5      (       a  U  Vs/ s H
  oe" U5      PM       nOU b  U" U 5        U(       a  UR                  5         T$ s  snf s  snf )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                    > TR                   " U R                  R                  0 TD6  U R                   H  nTR                   " UR                  0 TD6  M!     g N)plotrX   xyru   )singleinterioraxeskwargss     rH   plot_singleplot.<locals>.plot_single+  sC    		6??%%00((HIIx{{-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>C
resolutionc                    ^^ UU4S jnTc  SS/mU" U R                   5      / S.nU R                   H  nUS   R                  U" U5      5        M     U$ )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                    > U R                   T-  n[        [        R                  " U/TQ76 5      n[	        U R
                  US9$ )N)count)lengthintr"   clipr   rj   )boundaryr   r   r   s     rH   resample_boundary.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                     [        U S   5      S:X  a  U S   $ [        R                  " U S   [        R                  " U S   5      45      $ )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                 ~   [        U R                  5      S:X  a  [        R                  " [        R                  " U R
                  S5      SS9R                  5       n[        U R                  R                  US9nUb  [        R                  " US   S-  S[        R                  5      n[        R                  " US   SU/-   US   SU/-
  /[        R                  S	9n[        R                  " SS
//[        R                  S	9nXv4$ SSKJn  SSKJn	  UcE  [        R                  " [        R                  " U R
                  S5      SS9R                  5       S-  n['        XUS9n
[)        U
5      n
U" U
5      nU	R*                  " U /UR,                  R.                  Q76 n[        R0                  " US5      n[        R2                  " UR4                  [        R                  S	9nXU   R7                  S
S9   n[        R8                  " U5      n[        R:                  " [        UR,                  5      [        R                  S	9n[        R<                  " [        U5      5      X'   UR,                  U   nX   n[>        R@                  (       a/  [        R                  " UU   UR,                  U   -
  5      S:  d   eUU4$ )a  
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   |  s1   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
 "'tTGw'GgG""7@W-=-=-?-?@Hyy5)HMM'00AE5/%%1%-.E 		% I88C(():DiiI/DO 	*H+K
zzvvh{+g.>.>u.EEFMMM  ra   returnc                 \   [        U R                  5      U R                  R                  U R                  R                  U R                  U R                  U R
                  R                  /n[        U SS9u  p#  nUR                  U5        [        R                  " U[        R                  S9$ )z
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A!Q
MM)88F"**--ra   c                 t   [         R                  " [         R                  " [         R                  R                  U 5      [         R                  -  S-  5      [         R                  S-  -  5      n[         R                  R                  U 5      U-  n[         R
                  " [         R                  " U5      [         R                  " U5      45      UR                  S5      -  n[         R                  " XDS   45      n[        U5      R                  S5      n[        US5      (       a  UR                  S   $ U$ )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                     [         R                  " [         R                  " U R                  S5      SS9nUS-  R	                  5       S-  nU$ )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                 ^   S/[        U 5      -  n[        U 5       HF  u  p4[        U5      S:  a  M   [        U5      nUR                  (       a  XRU'   M9  [	        XQ5      X#'   MH     [        R                  " U5      nU$ ! [
         a     Mo  [         a    [        R                  " SSS9   M  f = f)a"  
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#t9q= 
	>dmG%,W< $" xx!HO  	 	>II-=	>s    A=A==
B,
B,+B,c                    SSK Jn  [        R                  " U R                  S5      n[        R
                  " USS9n[        X-  5      nUS   U[        R                  R                  US45      -  -   nUR                  " U /UR                  Q76 n	X   /n
[        U
S   5      nX:  a  U
S   SU $ [        U5       Hu  n[        R                  R                  US45      U-  US   -   nUR                  " U /UR                  Q76 n	U
R                  X   5        U[        U
S   5      -  nX:  d  Mu    O   [        R                  " U
5      SU n
U
$ )aO  
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  s;   4 # ZZ/FffV!$G 5>"H AY299#3#3XqM#BBBFw22D<.CCFI1vfu~ 8_))""Ha=1G;vayH""76VXX6

6< SR\!	  ))C.%
 CJra   c                    [        U S5      (       a  U R                  (       a  U $ U R                  [        R                  5      n[        US5      (       aG  UR
                  [        R                  " UR
                   Vs/ s H  oDR                  PM     sn5         nUR                  (       a1  [        R                  " UR                  U R                  US9(       a  U$ UcF  S[        R                  " [        R                  " U R                  S5      SS9R                  5       -  nOSU-  n[        U R                   5      S:X  GaH  U R"                  R                  U5      R                   n[        U5      S:X  a]  [%        US   S	9R                  U5      nUR                  (       a1  [        R                  " UR                  U R                  US9(       a  U$ [        R&                  " U R"                  R(                  5      n[        R*                  " S
[        R,                  " USS9S-  R/                  SS9S-  S:  5      n	[%        X   S	9n
U
R                  (       a1  [        R                  " U
R                  U R                  US9(       a  U
$ U R                  U5      R                  U* 5      n[        US5      (       aW  [        R&                  " UR
                   Vs/ s H  oR                  PM     sn5      nUR
                  UR                  5          $ UR                  (       aG  [        R                  " UR                  U R                  US9(       a  [0        R2                  " S5        U$ [5        S5      es  snf s  snf )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     s{   0 w
##(8(8 NN388$EugBIIu{{&C{!vv{&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v~.??rzz&--dSM ~~h'..y9Hx!!(..9.Q&&.9:~~elln-- RZZdS		FG
1
22a 'DP :s   >M:
M?preciseprecise_epsc	                 4   [         R                  " U[         R                  S9nU[         R                  R	                  U5      -  n[         R
                  " XR                  R                  5      n	U(       ay  X:  n
X* :  n[         R                  " U
R                  5       UR                  5       /5      nUR                  5       S:X  a  UR                  5       nOUR                  5       nX/U   nOX:  nXR                     R                  SS9nU R                  U   n[        R                  " X!S9n[!        U R"                  U5      SS2SS24   nU(       Ga  U R$                  U   n['        [         R(                  " [         R*                  " U5      5      S-   5      n[         R,                  " UU5      nU[         R.                  " UUSS2SS24   45         nUSS2/ SQ4   USS2/ S	Q4   :H  R                  SS9R1                  SS9) n[2        R4                  " UU    Vs/ s H  n[7        U5      PM     sn5      R9                  U5      R9                  U* 5      $ [:        R<                  " U[         R>                  " U5      S   S
9nU R@                  RC                  S5      n/ nU HH  nUU   RC                  S5      n[D        RF                  " USS9nURI                  [K        UU   US95        MJ     SnUb  U[M        U5      -  nUb5  [         RN                  " USS9RQ                  5       nU[M        U5      U-  -  nO$[S        U5      S:X  a  US   $ [S        U5      S:X  a  g[U        S U5      n U b!  U R9                  U5      R9                  U* 5      $ gs  snf )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                 $    U R                  U5      $ r   )union)ar?   s     rH   <lambda>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   	projectedr3    sI   | XXfBJJ/F
biinnV$$F vvf//112H "(" %))+txxz2399;!<<>D <<>D}T" ! ../333;O##O4I $$F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                    [         R                  " S5      nU(       a=  [         R                  " U R                  R                  5      * USS2S4'   [        X5      n [         R                  " U R                  R                  5      n[         R                  " US   USS 45      R                  u  pEUR                  u  pgXG-  Xe-  -
  n[         R                  " XU-  XW-  -   Xw-  -   -  5      S-  n	[         R                  " XU-  XF-  -   Xf-  -   -  5      S-  n
[         R                  " XU-  SU-  U-  -   SU-  U-  -   Xe-  -   -  5      S-  nU R                   H  n[         R                  " UR                  5      n[         R                  " US   USS 45      R                  u  pEUR                  u  pgXG-  Xe-  -
  nU	[         R                  " XU-  XW-  -   Xw-  -   -  5      S-  -  n	U
[         R                  " XU-  XF-  -   Xf-  -   -  5      S-  -  n
U[         R                  " XU-  SU-  U-  -   SU-  U-  -   Xe-  -   -  5      S-  -  nM     XU/nU(       d  U$ [         R                  " X-
  S-  S-  US-  -   5      nX-   S-  U-   nX-   S-  U-
  nUU/n[         R                  " USS	S
9(       a  SnOP[         R                  " X5      (       a  S[         R                  -  nO!S[         R                  " SU-  X-
  -  5      -  n[         R                  " U5      n[         R                   " U5      nUUS'   UUS'   U* US'   UUS'   UUUU4$ )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   ~  s.   : q	IHHW%5%5%<%<==	"1"a%#G7 XXg&&--.FYYr
F3BK0133FBXXFB
"'A
&&2g'"'12
3d
:C
&&2g'"'12
3d
:C
&&2gB+a"frk9BGCD
E
LC%%(//*F2Js4577Gbgrvva7RW,rw6784??rvva7RW,rw6784??rvva7QVb[01r6B;>HIJTQQ & oG 77SY#%!+c1f45DIt#DIt#Dt 
zz#s'	C		ruubiic	SY 788 uIuIIdOIdO jIdOIdO%ui77ra   r   )NTN)NN)r   g      ?)g      ?
   )Nr   )NTr   N绽|=FrI  )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   boolr3  r    ra   rH   <module>rY     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   C6 D 6D<DDD5D00D5