
    h,                       S SK Jr  S SKJr  S SKrS SKJrJrJrJ	r	J
r
Jr  S SKrS SKrS SKJrJrJrJr  S/r\" S5      r\
" S\\5      r " S	 S
\R.                  \\   5      r " S S\\   5      r " S S\\   5      r " S S\\   5      r        SS jrSS jr          SS jrSS jrSS jr SS jr!SS jr"SS jr#g)     )annotations)
itemgetterN)IteratorCallableSequenceIterableTypeVarGeneric)BoundingBoxVec2Vec3spherical_envelopeRTreeinfTc                  2   \ rS rSrSrSS jr\R                  SS j5       r\R                  SS j5       r	\R                  SS j5       r
\R                  S\4       SS jj5       r\R                  SS	 j5       r\R                  SS
 j5       rSS jrSrg)Node   bboxc                    Xl         g Nr   selfr   s     B/var/www/html/env/lib/python3.13/site-packages/ezdxf/math/rtree.py__init__Node.__init__   s    !%	    c                    g r    r   s    r   __len__Node.__len__    s    !r   c                    g r   r    r!   s    r   __iter__Node.__iter__#   s    '*r   c                    g r   r    r   points     r   containsNode.contains&   s    *-r   Nc                    g r   r    )r   targetnnnn_dists       r   _nearest_neighborNode._nearest_neighbor)   s     r   c                    g r   r    r   centerradiuss      r   points_in_sphereNode.points_in_sphere.   s    ILr   c                    g r   r    r   s     r   points_in_bboxNode.points_in_bbox1   s    @Cr   c                $    U R                  U5      $ r   )r0   r   r-   s     r   nearest_neighborNode.nearest_neighbor4   s    %%f--r   )r   r   returnintr@   Iterator[T]r)   r   r@   boolr-   r   r.   r   r/   floatr@   tuple[T, float]r4   r   r5   rG   r@   rC   r   r   r@   rC   r-   r   r@   rH   )__name__
__module____qualname____firstlineno__	__slots__r   abcabstractmethodr"   r%   r*   INFr0   r6   r9   r=   __static_attributes__r    r   r   r   r      s    I& 	! !* *- -!%05	  	L LC C.r   r   c                  ~   ^  \ rS rSrSrSU 4S jjrS rSS jrSS jrS\	4       SS jjr
SS	 jrSS
 jrSrU =r$ )LeafNode8   )pointsr   c                j   > [        U5      U l        [        TU ]  [	        U R                  5      5        g r   )tuplerX   superr   r   )r   rX   	__class__s     r   r   LeafNode.__init__;   s$    FmT[[12r   c                ,    [        U R                  5      $ r   )lenrX   r!   s    r   r"   LeafNode.__len__?   s    4;;r   c                ,    [        U R                  5      $ r   )iterrX   r!   s    r   r%   LeafNode.__iter__B   s    DKK  r   c                B   ^ [        U4S jU R                   5       5      $ )Nc              3  F   >#    U  H  nTR                  U5      v   M     g 7fr   )isclose.0pr)   s     r   	<genexpr>$LeafNode.contains.<locals>.<genexpr>F   s     9[5==##[   !)anyrX   r(   s    `r   r*   LeafNode.containsE   s    9T[[999r   Nc                Z   ^ [        U4S jU R                   5       5      u  pEXC:  a  XTp2X#4$ )Nc              3  J   >#    U  H  nTR                  U5      U4v   M     g 7fr   distance)rh   ri   r-   s     r   rj   -LeafNode._nearest_neighbor.<locals>.<genexpr>K   s     K{!vq115{s    #)minrX   )r   r-   r.   r/   rr   r)   s    `    r   r0   LeafNode._nearest_neighborH   s.     Kt{{KK{r   c                4   ^^ UU4S jU R                    5       $ )Nc              3  V   >#    U  H  nTR                  U5      T::  d  M  Uv   M      g 7fr   rq   )rh   ri   r4   r5   s     r   rj   ,LeafNode.points_in_sphere.<locals>.<genexpr>Q   s#     G;a&//!*<*F;s   )	)rX   r3   s    ``r   r6   LeafNode.points_in_sphereP   s    G4;;GGr   c                0   ^ U4S jU R                    5       $ )Nc              3  X   >#    U  H  nTR                  U5      (       d  M  Uv   M!     g 7fr   )inside)rh   ri   r   s     r   rj   *LeafNode.points_in_bbox.<locals>.<genexpr>T   s     9;a$++a.;s   *	*ry   r   s    `r   r9   LeafNode.points_in_bboxS   s    94;;99r   ry   )rX   list[T]rB   rD   rF   rI   rJ   rL   rM   rN   rO   rP   r   r"   r%   r*   rS   r0   r6   r9   rT   __classcell__r\   s   @r   rV   rV   8   sX    "I3 !: "&05	H: :r   rV   c                     ^  \ rS rSrSrSU 4S jjrSS jrSS jrSS jrS\	4       SS jjr
SS	 jrSS
 jrSrU =r$ )	InnerNodeW   )childrenr   c                  > [         TU ]  [        5       5        [        U5      U l        U R                   HH  nU R
                  R                  UR
                  R                  UR
                  R                  /5        MJ     g r   )	r[   r   r   rZ   r   r   extendextminextmax)r   r   childr\   s      r   r   InnerNode.__init__Z   sV    'h]]EIIejj//1B1BCD #r   c                :    [        S U R                   5       5      $ )Nc              3  8   #    U  H  n[        U5      v   M     g 7fr   )r_   )rh   cs     r   rj   $InnerNode.__len__.<locals>.<genexpr>b   s     1=a3q66=s   )sumr   r!   s    r   r"   InnerNode.__len__a   s    14==111r   c              #  \   #    U R                    H  n[        U5       S h  vN   M     g  N	7fr   )r   rb   )r   r   s     r   r%   InnerNode.__iter__d   s#     ]]EE{"" #"s   ,*
,c                    U R                    H=  nUR                  R                  U5      (       d  M%  UR                  U5      (       d  M=    g   g)NTF)r   r   r}   r*   )r   r)   r   s      r   r*   InnerNode.containsh   s;    ]]Ezz  ''ENN5,A,A # r   Nc                $   [        U R                  U5      nUR                  XU5      u  p#U R                   HT  nXTL a  M	  [        UR                  U5      R                  U5      (       d  M5  UR                  XU5      u  pgXs:  d  MP  UnUnMV     X#4$ r   )find_closest_childr   r0   grow_boxr   r}   )r   r-   r.   r/   closest_childr   r)   rr   s           r   r0   InnerNode._nearest_neighborn   s     +4==&A#55f'J]]E%

G,33F;;"'"9"9&g"N%B&G # {r   c              #     #    U R                    Ha  n[        [        U5      X#R                  R                  UR                  R
                  5      (       d  MH  UR                  X5       S h  vN   Mc     g  N	7fr   )r   is_sphere_intersecting_bboxr   r   r4   sizer6   )r   r4   r5   r   s       r   r6   InnerNode.points_in_sphere~   sY     ]]E*Vfjj&7&7  !11&AAA	 # Bs   AA7A7+A5,
A7c              #     #    U R                    H>  nUR                  UR                  5      (       d  M%  UR                  U5       S h  vN   M@     g  N	7fr   )r   has_overlapr   r9   )r   r   r   s      r   r9   InnerNode.points_in_bbox   s?     ]]E

++ //555 #5s   .AAA	
A)r   )r   Sequence[Node[T]]r?   rB   rD   rF   rI   rJ   r   r   s   @r   r   r   W   sY    $IE2# "&05	 B6 6r   r   c                      \ rS rSrSrSrSSS jjrS rSS jrSS jr	SS jr
SS	 jrSS
 jrSSS jjrSSS jjrSSS jjrSrg)r      a  Immutable spatial search tree loosely based on `R-trees`_.

The search tree is buildup once at initialization and immutable afterwards,
because rebuilding the tree after inserting or deleting nodes is very costly
and makes the implementation very complex.  

Without the ability to alter the content the restrictions which forces the tree 
balance at growing and shrinking of the original `R-trees`_, are ignored, like the 
fixed minimum and maximum node size.

This class uses internally only 3D bounding boxes, but also supports
:class:`Vec2` as well as :class:`Vec3` objects as input data, but point
types should not be mixed in a search tree.

The point objects keep their type and identity and the returned points of
queries can be compared by the ``is`` operator for identity to the input
points.

The implementation requires a maximum node size of at least 2 and
does not support empty trees!

Raises:
    ValueError: max. node size too small or no data given

.. _R-trees: https://en.wikipedia.org/wiki/R-tree

)_rootc                    US:  a  [        S5      e[        U5      n[        U5      S:X  a  [        S5      e[        X2[        5      U l        g )N   zmax node size must be > 1r   zno points given)
ValueErrorlistr_   	make_node	box_splitr   )r   rX   max_node_size_pointss       r   r   RTree.__init__   sE    1899v,w<1.//wyA
r   c                ,    [        U R                  5      $ )z/Returns the count of points in the search tree.)r_   r   r!   s    r   r"   RTree.__len__   s    4::r   c              #  J   #    [        U R                  5       Sh  vN   g N7f)z%Yields all points in the search tree.N)rb   r   r!   s    r   r%   RTree.__iter__   s     

###s   #!#c                8    U R                   R                  U5      $ )zReturns ``True`` if `point` exists, the comparison is done by the
:meth:`isclose` method and not by the identity operator ``is``.
)r   r*   r(   s     r   r*   RTree.contains   s     zz""5))r   c                8    U R                   R                  U5      $ )zWReturns the closest point to the `target` point and the distance
between these points.
)r   r=   r<   s     r   r=   RTree.nearest_neighbor   s     zz**622r   c                8    U R                   R                  X5      $ )zZReturns all points in the range of the given sphere including the
points at the boundary.
)r   r6   r3   s      r   r6   RTree.points_in_sphere   s     zz**6::r   c                8    U R                   R                  U5      $ )z`Returns all points in the range of the given bounding box including
the points at the boundary.
)r   r9   r   s     r   r9   RTree.points_in_bbox   s     zz((..r   c                    [        U R                  5       Vs/ s H,  n[        UR                  R                  R
                  5      PM.     nn[        X15      $ s  snf )zReturns the average size of the leaf bounding boxes.
The size of a leaf bounding box is the maximum size in all dimensions.
Excludes outliers of sizes beyond mean + standard deviation * spread.
Returns 0.0 if less than two points in tree.
)collect_leafsr   maxr   r   xyzaverage_exclusive_outliers)r   spreadleafsizess       r   avg_leaf_sizeRTree.avg_leaf_size   sO     1>djj0I
0IC		""#0I 	 
 *%88
s   3Ac                    [        U R                  5       Vs/ s H  n[        UR                  5      S   PM     nn[	        X15      $ s  snf )zReturns the average radius of spherical envelopes of the leaf nodes.
Excludes outliers with radius beyond mean + standard deviation * spread.
Returns 0.0 if less than two points in tree.
   )r   r   r   rX   r   )r   r   r   radiis       r   avg_spherical_envelope_radius#RTree.avg_spherical_envelope_radius   sL     <I;T
;T4t{{+A.;T 	 
 *%88
s   "Ac                    / n[        U R                  5       H'  nUR                  [        UR                  5      5        M)     [        X!5      $ )aS  Returns the average of the nearest neighbor distances inside (!)
leaf nodes. Excludes outliers with a distance beyond the overall
mean + standard deviation * spread. Returns 0.0 if less than two points
in tree.

.. warning::

    This is a brute force check with O(n!) for each leaf node, where n
    is the point count of the leaf node.

)r   r   r   nearest_neighbor_distancesrX   r   )r   r   	distancesr   s       r   avg_nn_distanceRTree.avg_nn_distance   s?     "$	!$**-D7DE .))<<r   N)   )rX   zIterable[T]r   rA   rB   rD   rK   rI   rJ   )g      ?)r   rG   r@   rG   )rL   rM   rN   rO   __doc__rP   r   r"   r%   r*   r=   r6   r9   r   r   r   rT   r    r   r   r   r      sF    8 IB$*3;/	99= =r   c                X    [        U 5      U:  a  [        U" X5      5      $ [        U 5      $ r   )r_   r   rV   )rX   max_sizesplit_strategys      r   r   r      s+    
 6{X9::r   c                6  ^ ^^ [        T 5      n[        T 5      R                  R                  nUR	                  [        U5      5      nT R                  [        U5      S9  [        R                  " UT-  5      m[        UUU 4S j[        SUT5       5       5      $ )Nkeyc              3  P   >#    U  H  n[        TXT-    T[        5      v   M     g 7fr   )r   r   )rh   ikr   rX   s     r   rj   box_split.<locals>.<genexpr>
  s)      CQa	&U#Xy99>s   #&r   )r_   r   r   r   indexr   sortr   mathceilrZ   range)rX   r   nr   dimr   s   ``   @r   r   r     sz    FA'26':'?'?'C'CD
**SY
C
KKJsOK$		!h,A CHAq>  r   c                   X-
  nUS-  [        XU5      -   n[        UR                  5      UR                  :  a  g[        UR                  5      UR                  :  a  g[        UR                  5      UR                  :  a  gg)Ng      ?FT)r   absxyz)centroidr5   r4   r   rr   intersection_distances         r   r   r     ss      H 3Jff)EE
8::.000
8::.000
8::.000r   c                H   ^ SU4S jjn[        U 5      S:  d   e[        XS9$ )Nc                N   > TR                  U R                  R                  5      $ r   )rr   r   r4   )r   r)   s    r   rr   $find_closest_child.<locals>.distance  s    ~~ejj//00r   r   r   )r   r   r@   rG   )r_   rt   )r   r)   rr   s    ` r   r   r     s'    1 x=1x&&r   c                H    U R                  5       nUR                  U5        U$ r   )copygrow)boxdistr   s      r   r   r   &  s    88:DIIdOKr   c                   [        U 5      S:  a  g[        R                  " U 5      n[        U 5      [        U 5      -  nX2U-  -   nU  Vs/ s H  oUU::  d  M
  UPM     n n[        U 5      (       a  [        U 5      [        U 5      -  $ gs  snf )Nr   g        )r_   
statisticsstdevr   )valuesr   r   mean	max_valuevalues         r   r   r   ,  s{    
6{QV$Ev;V$Dv~%I!'>I+=eF>
6{{6{S[(( ?s   		BBc              #     #    [        U [        5      (       a  U v   g[        U [        5      (       a'  U R                   H  n[	        U5       Sh  vN   M     gg N
7f)z+Yields all leaf nodes below the given node.N)
isinstancerV   r   r   r   )noder   s     r   r   r   8  sH     $!!
	D)	$	$]]E$U+++ # 
%+s   AAAAc           
        ^ [        U SS 5       VV^s/ s H   u  nm[        U4S jXS-   S  5       5      PM"     snn$ s  snnf )zRBrute force calculation of nearest neighbor distances with a
complexity of O(n!).
Nc              3  F   >#    U  H  nTR                  U5      v   M     g 7fr   rq   rg   s     r   rj   -nearest_neighbor_distances.<locals>.<genexpr>F  s     ;':!ENN1':rl   r   )	enumeratert   )rX   r   r)   s     `r   r   r   A  sM     &fSbk22LE5 	;vaik':;;2  s   '?)rX   r   r   rA   r   z(Callable[[list[T], int], Sequence[Node]]r@   Node[T])rX   r   r   rA   r@   r   )
r   r   r5   rG   r4   r   r   r   r@   rE   )r   r   r)   r   r@   r  )r   r   r   rG   r@   r   )r   list[float]r   rG   r@   rG   )r   r  r@   zIterable[LeafNode[T]])rX   zSequence[T]r@   r  )$
__future__r   operatorr   r   typingr   r   r   r   r	   r
   rQ   r   
ezdxf.mathr   r   r   r   __all__rG   rS   r   ABCr   rV   r   r   r   r   r   r   r   r   r   r   r    r   r   <module>r
     s    #   K K 
  B B)ElCt.377GAJ .<:tAw :>16Q 16hk=GAJ k=\    =  	 !+/7;	'	,r   