
    hd<                    z   % S SK Jr  S SKJrJrJrJrJr  S SKrS SK	J
r
Jr  S SKrS SKJrJrJrJrJrJrJrJrJr  S SKr/ SQrSr " S S	\5      rSS
 jr " S S\
5      r " S S5      r S     SS jjr S     SS jjr SS jr!\\\"\"\"4   \4   r#S\$S'    " S S5      r% " S S\%5      r& " S S\%5      r'g)    )annotations)IterableTupleIteratorSequenceDictN)Protocol	TypeAlias)	Vec2Vec3UVecNULLVECintersection_line_line_2dBoundingBox2dintersection_line_line_3dBoundingBoxAbstractBoundingBox)ConstructionPolylineApproxParamTintersect_polylines_2dintersect_polylines_3dg&.>c                      \ rS rSrSrS\4     SS jjrSS jrSS jrS r	\
SS j5       r\
SS	 j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S jjrSrg)r   )   a  Construction tool for 3D polylines.

A polyline construction tool to measure, interpolate and divide anything
that can be approximated or flattened into vertices.
This is an immutable data structure which supports the :class:`Sequence`
interface.

Args:
    vertices: iterable of polyline vertices
    close: ``True`` to close the polyline (first vertex == last vertex)
    rel_tol: relative tolerance for floating point comparisons

Example to measure or divide a SPLINE entity::

    import ezdxf
    from ezdxf.math import ConstructionPolyline

    doc = ezdxf.readfile("your.dxf")
    msp = doc.modelspace()
    spline = msp.query("SPLINE").first
    if spline is not None:
        polyline = ConstructionPolyline(spline.flattening(0.01))
        print(f"Entity {spline} has an approximated length of {polyline.length}")
        # get dividing points with a distance of 1.0 drawing unit to each other
        points = list(polyline.divide_by_length(1.0))

Fc                   [        U5      U l        [        R                  " U5      nX@l        U(       aH  [        U5      S:  a9  US   R                  US   U R                  S9(       d  UR                  US   5        [        U5      U l        g )N   r   rel_tol)	float_rel_tolr   list	_verticesleniscloseappend
_distances)selfverticescloser   v3lists        E/var/www/html/env/lib/python3.13/site-packages/ezdxf/math/polyline.py__init__ConstructionPolyline.__init__F   sj     g!YYx0%+S[1_!9$$VBZ$GfQi('1&'9    c                ,    [        U R                  5      $ )z	len(self))r#   r"   r'   s    r+   __len__ConstructionPolyline.__len__U   s    4>>""r.   c                ,    [        U R                  5      $ )z
iter(self))iterr"   r0   s    r+   __iter__ConstructionPolyline.__iter__Y   s    DNN##r.   c                    [        U[        5      (       a  U R                  U   $ U R                  U R                  U   U R                  S9$ )zvertex = self[item]r   )
isinstanceintr"   	__class__r    )r'   items     r+   __getitem__ ConstructionPolyline.__getitem__]   s>    dC  >>$''>>$.."6>NNr.   c                D    U R                   (       a  U R                   S   $ g)z+Returns the overall length of the polyline.r           )r&   r0   s    r+   lengthConstructionPolyline.lengthd   s     ????2&&r.   c                    [        U R                  5      S:  a4  U R                  S   R                  U R                  S   U R                  S9$ g)zJReturns ``True`` if the polyline is closed
(first vertex == last vertex).
r   r   r   r   F)r#   r"   r$   r    r0   s    r+   	is_closedConstructionPolyline.is_closedk   sM    
 t~~">>!$,,r"DMM -   r.   c                    U R                   nU(       d  [        S5      eU R                  nUS:X  a  SSUS   4$ X1S-
     nX1   nX!   nXUU-
  U4$ )z{Returns the tuple (distance from start, distance from previous vertex,
vertex). All distances measured along the polyline.
zempty polyliner   r?      )r"   
ValueErrorr&   )r'   indexr(   	distancesprev_distancecurrent_distancevertexs          r+   dataConstructionPolyline.datav   si     >>-..OO	A:Xa[((!!),$+M!A6IIr.   c                    US::  a  gXR                   :  a  [        S[        U 5      S-
  5      $ U R                  U5      $ )zReturns the data index of the exact or next data entry for the given
`distance`. Returns the index of last entry if `distance` > :attr:`length`.

r?   r   rF   )r@   maxr#   	_index_atr'   distances     r+   index_atConstructionPolyline.index_at   s<    
 s?{{"q#d)a-((~~h''r.   c                D    [         R                  " U R                  U5      $ N)bisectbisect_leftr&   rR   s     r+   rQ   ConstructionPolyline._index_at   s    !!$//8<<r.   c                    US:  d  XR                   :  a  [        S5      e[        U R                  5      S:  a  [        S5      eU R	                  U5      $ )zXReturns the interpolated vertex at the given `distance` from the
start of the polyline.
r?   zdistance out of ranger   %not enough vertices for interpolation)r@   rG   r#   r"   
_vertex_atrR   s     r+   	vertex_atConstructionPolyline.vertex_at   sL     c>X3455t~~"DEEx((r.   c                    U R                   nU R                  nU R                  U5      nUS:X  a  US   $ US-
  nX4   nX5   nUS:  a  Xv:X  a  US-  nX5   nUS:  a  Xv:X  a  M  Xv:X  a  [        S5      eX-
  Xg-
  -  nX%   R	                  X$   US9$ )Nr   rF   zinternal interpolation error)factor)r"   r&   rQ   ArithmeticErrorlerp)	r'   rS   r(   rI   index1index0	distance1	distance0ra   s	            r+   r]   ConstructionPolyline._vertex_at   s    >>OO	)Q;A;!%	%	qjY3aKF!)I qjY3 !!"@AA&9+@A$$X%5f$EEr.   c              #     #    US:  a  [        SU 35      eU R                  n[        R                  " SU R                  U5       H  nU" U5      v   M     g7f)zReturns `count` interpolated vertices along the polyline.
Argument `count` has to be greater than 2 and the start- and end
vertices are always included.

r   zinvalid count: r?   N)rG   r]   nplinspacer@   )r'   countr^   rS   s       r+   divideConstructionPolyline.divide   sO      19ug677OO	Ce<HH%% =s   AAc              #  n  #    US::  a  [        SU 35      e[        U R                  5      S:  a  [        S5      eU R                  nU R                  nSn[
        nXS::  a  U" U5      nUv   XQ-  nXS::  a  M  U(       a6  UR                  U R                  S   5      (       d  U R                  S   v   ggg7f)zReturns interpolated vertices along the polyline. Each vertex has a
fix distance `length` from its predecessor. Yields the last vertex if
argument `force_last` is ``True`` even if the last distance is not equal
to `length`.

r?   zinvalid length: r   r\   r   N)rG   r#   r"   r@   r]   r   r$   )r'   r@   
force_lasttotal_lengthr^   rS   rL   s          r+   divide_by_length%ConstructionPolyline.divide_by_length   s      S=/x899t~~"DEE"kkOO	&x(FLH &
 fnnT^^B-?@@..$$ A:s   A3B57>B5)r&   r    r"   N)r(   zIterable[UVec]r)   boolr   r   )returnr9   )ru   Iterator[Vec3]ru   r   )ru   rt   )rH   r9   ru   ztuple[float, float, Vec3])rS   r   ru   r9   )rS   r   ru   r   )rl   r9   ru   rv   )F)r@   r   rp   rt   ru   rv   )__name__
__module____qualname____firstlineno____doc__REL_TOLr,   r1   r5   r<   propertyr@   rC   rM   rT   rQ   r^   r]   rm   rr   __static_attributes__ r.   r+   r   r   )   s    >  	: : : 	:#$O    J 	(=)F(
& 16%%)-%	% %r.   r   c                    Sn/ n[        5       nU  HA  nU(       a$  XC-
  nXR                  -  nUR                  U5        OUR                  U5        UnMC     U$ )Nr?   )r   	magnituder%   )r(   current_stationrI   prev_vertexrL   distant_vecs         r+   r&   r&      s_     OI&K .K444O_-_-  r.   c                      \ rS rSrSS jrSrg)SupportsPointMethod   c                    g rW   r   )r'   ts     r+   pointSupportsPointMethod.point   s    r.   r   N)r   r   ru   r   )rx   ry   rz   r{   r   r   r   r.   r+   r   r      s    r.   r   c                  r    \ rS rSrSrSSS.     SS jjr\SS j5       r\SS j5       rSS	 jr	SS
 jr
Srg)r      a  Approximation tool for parametrized curves.

- approximate parameter `t` for a given distance from the start of the curve
- approximate the distance for a given parameter `t` from the start of the curve

These approximations can be applied to all parametrized curves which provide
a :meth:`point` method, like :class:`Bezier4P`, :class:`Bezier3P` and
:class:`BSpline`.

The approximation is based on equally spaced parameters from 0 to `max_t`
for a given segment count.
The :meth:`flattening` method can not be used for the curve approximation,
because the required parameter `t` is not logged by the flattening process.

Args:
    curve: curve object, requires a method :meth:`point`
    max_t: the max. parameter value
    segments: count of approximation segments

g      ?d   )max_tsegmentsc          	        ^ [        TS5      (       d   eUS:  d   e[        U4S j[        R                  " SX#S-   5       5       5      U l        X l        X#-  U l        g )Nr   r   c              3  F   >#    U  H  nTR                  U5      v   M     g 7frW   )r   ).0r   curves     r+   	<genexpr>(ApproxParamT.__init__.<locals>.<genexpr>  s      .
$IqEKKNN$Is   !r?   rF   )hasattrr   rj   rk   	_polyline_max_t_step)r'   r   r   r   s    `  r+   r,   ApproxParamT.__init__  s]     ug&&&&!||- .
$&KKUqL$I.
 
 %
r.   c                    U R                   $ rW   )r   r0   s    r+   r   ApproxParamT.max_t  s    {{r.   c                    U R                   $ rW   )r   r0   s    r+   polylineApproxParamT.polyline  s    ~~r.   c                
   U R                   nXR                  :  a  U R                  $ U R                  nUR	                  U5      nUR                  U5      u  pVnX4-  nUS:  a  XXQ-
  -  U-  -  n[        U R                  U5      $ )zNApproximate parameter t for the given `distance` from the start of
the curve.
g-q=)r   r@   r   r   rT   rM   min)	r'   rS   polyt_stepistationd0_r   s	            r+   param_tApproxParamT.param_t  s}     ~~{{";;MM(#1QJ:7-.33A4;;""r.   c                    US::  a  gU R                   nXR                  :  a  UR                  $ U R                  n[	        X-  5      S-   nUR                  U5      u  pVnXVX4-  U-
  -  U-  -
  $ )zTApproximate the distance from the start of the curve to the point
`t` on the curve.
r?   rF   )r   r   r@   r   r9   rM   )r'   r   r   steprH   r   r   r   s           r+   rS   ApproxParamT.distance-  sp     8~~;;zzAH!5)Qt|a/04777r.   )r   r   r   N)r   r   r   r   r   r9   rw   )ru   r   )rS   r   )r   r   ru   r   )rx   ry   rz   r{   r|   r,   r~   r   r   r   rS   r   r   r.   r+   r   r      sb    2 &"& 	&
 &    # 8r.   r   c                R    [        XU5      nUR                  5         UR                  $ )a.  Returns the intersection points for two polylines as list of :class:`Vec2`
objects, the list is empty if no intersection points exist.
Does not return self intersection points of `p1` or `p2`.
Duplicate intersection points are removed from the result list, but the list
does not have a particular order! You can sort the result list by
:code:`result.sort()` to introduce an order.

Args:
    p1: first polyline as sequence of :class:`Vec2` objects
    p2: second polyline as sequence of :class:`Vec2` objects
    abs_tol: absolute tolerance for comparisons

)_PolylineIntersection2dexecuteintersectionsp1p2abs_tol	intersects       r+   r   r   =  (      (8I"""r.   c                R    [        XU5      nUR                  5         UR                  $ )a.  Returns the intersection points for two polylines as list of :class:`Vec3`
objects, the list is empty if no intersection points exist.
Does not return self intersection points of `p1` or `p2`.
Duplicate intersection points are removed from the result list, but the list
does not have a particular order! You can sort the result list by
:code:`result.sort()` to introduce an order.

Args:
    p1: first polyline as sequence of :class:`Vec3` objects
    p2: second polyline as sequence of :class:`Vec3` objects
    abs_tol: absolute tolerance for comparisons

)_PolylineIntersection3dr   r   r   s       r+   r   r   R  r   r.   c                    X-   S-  nXX!4$ )Nr   r   )abms      r+   rm   rm   g  s    	
1A:r.   r
   TCachec                      \ rS rSr% S\S'   S\S'   SS jr\R                  SS j5       r\R                  SS j5       r	SS jr
SS	 jrSS
 jrSrg)_PolylineIntersectionio  r   r   r   c                    0 U l         g rW   
bbox_cacher0   s    r+   r,   _PolylineIntersection.__init__s  s     #%r.   c                    g rW   r   r'   pointss     r+   bbox_PolylineIntersection.bboxx      r.   c                    g rW   r   )r'   s1e1s2e2s        r+   line_intersection'_PolylineIntersection.line_intersection|  r   r.   c                    [        U R                  5      n[        U R                  5      nUS:  d  US:  a  g U R                  SUS-
  SUS-
  5        g )Nr   r   rF   )r#   r   r   r   )r'   l1l2s      r+   r   _PolylineIntersection.execute  sF    dgg,dgg,6R!Vq"q&!R!V,r.   c                V   US-  nUS-  nX!-
  S:  d  XC-
  S:  a  gU R                   nSX4nUR                  U5      nUc!  U R                  U R                  X 5      nXuU'   SX44nUR                  U5      n	U	c!  U R                  U R                  X4 5      n	XU'   UR                  U	5      $ )NrF   r   F)r   getr   r   r   has_overlap)
r'   r   r   r   r   cachekey1bbox1key2bbox2s
             r+   overlap_PolylineIntersection.overlap  s    
a
a 7Q;"'A+2{		$=IIdggbn-E$K2{		$=IIdggbn-E$K  ''r.   c                   X!:  a  XC:  d   eX!-
  S:X  a  XC-
  S:X  a  U R                  XX45        g [        X5      u  pVpx[        X45      u  ppU R                  XVX5      (       a  U R                  XVX5        U R                  XVX5      (       a  U R                  XVX5        U R                  XxX5      (       a  U R                  XxX5        U R                  XxX5      (       a  U R                  XxX5        g g )NrF   )r   rm   r   r   )r'   r   r   r   r   s1_ae1_bs1_ce1_ds2_ae2_bs2_ce2_ds                r+   r   _PolylineIntersection.intersect  s    w27""7a<BGqL""222!'D!'D<<D//NN4t2<<D//NN4t2<<D//NN4t2<<D//NN4t2 0r.   r   N)ru   Noner   r   ru   r   
r   r9   r   r9   r   r9   r   r9   ru   r   )
r   r9   r   r9   r   r9   r   r9   ru   rt   )rx   ry   rz   r{   __annotations__r,   abcabstractmethodr   r   r   r   r   r   r   r.   r+   r   r   o  sT    LL%
 	  	 -(,3r.   r   c                  D   ^  \ rS rSrSSU 4S jjjrSS jrS	S jrSrU =r$ )
r   i  c                T   > [         TU ]  5         Xl        X l        / U l        X0l        g rW   superr,   r   r   r   r   r'   r   r   r   r:   s       r+   r,    _PolylineIntersection2d.__init__  %    )+r.   c                    [        U5      $ rW   )r   r   s     r+   r   _PolylineIntersection2d.bbox  s    V$$r.   c                4  ^ ^ T R                   U   T R                   U   4nT R                  U   T R                  U   4n[        XVST R                  S9mTbB  [	        UU 4S jT R
                   5       5      (       d  T R
                  R                  T5        g g g )NFvirtualr   c              3  X   >#    U  H  nTR                  UTR                  S 9v   M!     g7f)r   Nr$   r   r   ippr'   s     r+   r   <_PolylineIntersection2d.line_intersection.<locals>.<genexpr>  &      %
:LBAIIb$,,I/:L   '*)r   r   r   r   anyr   r%   r'   r   r   r   r   line1line2r  s   `      @r+   r   )_PolylineIntersection2d.line_intersection      TWWR[(TWWR[(%%
 = %
:>:L:L%
 "
 "
 %%a("
=r.   r   r   r   r   g|=)r   Sequence[Vec2]r   r  r   r   	rx   ry   rz   r{   r,   r   r   r   __classcell__r:   s   @r+   r   r     s     %	) 	)r.   r   c                  D   ^  \ rS rSrSSU 4S jjjrSS jrS	S jrSrU =r$ )
r   i  c                T   > [         TU ]  5         Xl        X l        / U l        X0l        g rW   r   r   s       r+   r,    _PolylineIntersection3d.__init__  r   r.   c                    [        U5      $ rW   )r   r   s     r+   r   _PolylineIntersection3d.bbox  s    6""r.   c                4  ^ ^ T R                   U   T R                   U   4nT R                  U   T R                  U   4n[        XVST R                  S9mTbB  [	        UU 4S jT R
                   5       5      (       d  T R
                  R                  T5        g g g )NFr   c              3  X   >#    U  H  nTR                  UTR                  S 9v   M!     g7fr   r   r   s     r+   r   <_PolylineIntersection3d.line_intersection.<locals>.<genexpr>  r  r  )r   r   r   r   r  r   r%   r  s   `      @r+   r   )_PolylineIntersection3d.line_intersection  r  r.   r  r  )r   Sequence[Vec3]r   r  r   r   r  r  s   @r+   r   r     s     #	) 	)r.   r   )r(   zIterable[Vec3]ru   zlist[float]r  )r   r  r   r  ru   z
list[Vec2])r   r  r   r  ru   z
list[Vec3])r   r9   r   r9   ru   ztuple[int, int, int, int])(
__future__r   typingr   r   r   r   r   r   typing_extensionsr	   r
   numpyrj   
ezdxf.mathr   r   r   r   r   r   r   r   r   rX   __all__r}   r   r&   r   r   r   r   rm   r9   r   r   r   r   r   r   r.   r+   <module>r"     s    #   1 
 
 
  o%8 o%d ( 
J8 J8\ 5:##*##, 5:##*##*
 sC}-/BBC	 C=3 =3@)3 ).)3 )r.   