
    'jd<                       U d dl mZ d dlmZmZmZmZmZ d dlZd dl	m
Z
mZ d dlZd dlmZmZmZmZmZmZmZmZmZ d dlZg dZdZ G d d	e          Zd)dZ G d de
          Z G d d          Z	 d*d+dZ	 d*d,dZ d-d Z!eee"e"e"f         ef         Z#d!e$d"<    G d# d$          Z% G d% d&e%          Z& G d' d(e%          Z'dS ).    )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                      e Zd ZdZdefd!d	Zd"dZd#dZd Ze	d$d            Z
e	d%d            Zd&dZd'dZd'dZd(dZd(dZd)dZ	 d*d+dZd S ),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))

    FverticesIterable[UVec]closeboolrel_tolfloatc                <   t          |          | _        t          j        |          }|| _        |rVt          |          dk    rC|d                             |d         | j                  s|                    |d                    t          |          | _        d S )N   r   r   )	r   _rel_tolr   list	_verticesleniscloseappend
_distances)selfr   r   r   v3lists        M/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/math/polyline.py__init__zConstructionPolyline.__init__F   s     g!Yx00%+ 	)S[[1__!9$$VBZ$GG )fQi((('1&'9'9    returnintc                *    t          | j                  S )z	len(self))r&   r%   r*   s    r,   __len__zConstructionPolyline.__len__U   s    4>"""r.   Iterator[Vec3]c                *    t          | j                  S )z
iter(self))iterr%   r2   s    r,   __iter__zConstructionPolyline.__iter__Y   s    DN###r.   c                    t          |t                    r| j        |         S |                     | j        |         | j                  S )zvertex = self[item]r"   )
isinstancer0   r%   	__class__r#   )r*   items     r,   __getitem__z ConstructionPolyline.__getitem__]   sA    dC   	O>$''>>$."6>NNNr.   c                .    | j         r| j         d         S dS )z+Returns the overall length of the polyline.r!           )r)   r2   s    r,   lengthzConstructionPolyline.lengthd   s      ? 	'?2&&sr.   c                    t          | j                  dk    r2| j        d                             | j        d         | j                  S dS )zZReturns ``True`` if the polyline is closed
        (first vertex == last vertex).
        r    r   r!   r"   F)r&   r%   r'   r#   r2   s    r,   	is_closedzConstructionPolyline.is_closedk   sR    
 t~"">!$,,r"DM -    ur.   indextuple[float, float, Vec3]c                    | j         }|st          d          | j        }|dk    rdd|d         fS ||dz
           }||         }||         }|||z
  |fS )zReturns the tuple (distance from start, distance from previous vertex,
        vertex). All distances measured along the polyline.
        zempty polyliner   r>      )r%   
ValueErrorr)   )r*   rB   r   	distancesprev_distancecurrent_distancevertexs          r,   datazConstructionPolyline.datav   sx     > 	/-...O	A::Xa[((!%!),$U+%!1M!A6IIr.   distancec                    |dk    rdS || j         k    r t          dt          |           dz
            S |                     |          S )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   rE   )r?   maxr&   	_index_atr*   rL   s     r,   index_atzConstructionPolyline.index_at   sK    
 s??1t{""q#d))a-(((~~h'''r.   c                6    t          j        | j        |          S N)bisectbisect_leftr)   rP   s     r,   rO   zConstructionPolyline._index_at   s    !$/8<<<r.   r   c                    |dk     s|| j         k    rt          d          t          | j                  dk     rt          d          |                     |          S )zhReturns 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?   rF   r&   r%   
_vertex_atrP   s     r,   	vertex_atzConstructionPolyline.vertex_at   s^     c>>X334555t~""DEEEx(((r.   c                ^   | j         }| j        }|                     |          }|dk    r|d         S |dz
  }||         }||         }|dk    r||k    r|dz  }||         }|dk    r||k    ||k    rt          d          ||z
  ||z
  z  }||                             ||         |          S )Nr   rE   zinternal interpolation error)factor)r%   r)   rO   ArithmeticErrorlerp)	r*   rL   r   rG   index1index0	distance1	distance0r[   s	            r,   rX   zConstructionPolyline._vertex_at   s    >O	))Q;;A;!f%	f%	qjjY)33aKF!&)I qjjY)33 	!!!"@AAAY&9y+@A$$Xf%5f$EEEr.   countc              #     K   |dk     rt          d|           | j        }t          j        d| j        |          D ]} ||          V  dS )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)rF   rX   nplinspacer?   )r*   rb   rY   rL   s       r,   dividezConstructionPolyline.divide   sq       1996u66777O	Ce<< 	& 	&H)H%%%%%%	& 	&r.   r?   
force_lastc              #  `  K   |dk    rt          d|           t          | j                  dk     rt          d          | j        }| j        }d}t
          }||k    r ||          }|V  ||z  }||k    |r1|                    | j        d                   s| j        d         V  dS dS dS )a  Returns 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    rW   r!   N)rF   r&   r%   r?   rX   r   r'   )r*   r?   rg   total_lengthrY   rL   rJ   s          r,   divide_by_lengthz%ConstructionPolyline.divide_by_length   s       S==888999t~""DEEE"kO	,&&Yx((FLLLH ,&&
  	%fnnT^B-?@@ 	%.$$$$$$	% 	% 	% 	%r.   N)r   r   r   r   r   r   )r/   r0   )r/   r4   r/   r   )r/   r   )rB   r0   r/   rC   )rL   r   r/   r0   )rL   r   r/   r   )rb   r0   r/   r4   )F)r?   r   rg   r   r/   r4   )__name__
__module____qualname____doc__REL_TOLr-   r3   r7   r<   propertyr?   rA   rK   rQ   rO   rY   rX   rf   rj    r.   r,   r   r   )   sW        >  	: : : : :# # # #$ $ $ $O O O    X    XJ J J J 	( 	( 	( 	(= = = =) ) ) )F F F F(
& 
& 
& 
& 16% % % % % % %r.   r   r   Iterable[Vec3]r/   list[float]c                    d}g }t                      }| D ]@}|r%||z
  }||j        z  }|                    |           n|                    |           |}A|S )Nr>   )r   	magnituder(   )r   current_stationrG   prev_vertexrJ   distant_vecs         r,   r)   r)      s{     OI&&K   	. ;.K{44O_----_---r.   c                      e Zd ZddZdS )SupportsPointMethodtr   r/   r   c                    d S rS   rr   )r*   r|   s     r,   pointzSupportsPointMethod.point   s    r.   N)r|   r   r/   r   )rl   rm   rn   r~   rr   r.   r,   r{   r{      s(             r.   r{   c                  b    e Zd ZdZdddddZedd            Zedd            ZddZddZ	dS )r   a9  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segmentscurver{   r   r   r   r0   c          	         t          d          sJ |dk    sJ t          fdt          j        d||dz             D                       | _        || _        ||z  | _        d S )Nr~   r   c              3  B   K   | ]}                     |          V  d S rS   )r~   ).0r|   r   s     r,   	<genexpr>z(ApproxParamT.__init__.<locals>.<genexpr>  s>       .
 .
 EKKNN.
 .
 .
 .
 .
 .
r.   r>   rE   )hasattrr   rd   re   	_polyline_max_t_step)r*   r   r   r   s    `  r,   r-   zApproxParamT.__init__  s     ug&&&&&!||||- .
 .
 .
 .
$&KUHqL$I$I.
 .
 .
 
 
 X%


r.   r/   c                    | j         S rS   )r   r2   s    r,   r   zApproxParamT.max_t  s
    {r.   r   c                    | j         S rS   )r   r2   s    r,   polylinezApproxParamT.polyline  s
    ~r.   rL   c                    | j         }||j        k    r| j        S | j        }|                    |          }|                    |          \  }}}||z  }|dk    r||||z
  z  |z  z  }t          | j        |          S )z^Approximate parameter t for the given `distance` from the start of
        the curve.
        g-q=)r   r?   r   r   rQ   rK   min)	r*   rL   polyt_stepistationd0_r|   s	            r,   param_tzApproxParamT.param_t  s     ~t{"";MM(##1QQJ::7X-.33A4;"""r.   r|   c                    |dk    rdS | j         }|| j        k    r|j        S | j        }t	          ||z            dz   }|                    |          \  }}}||||z  |z
  z  |z  z
  S )zdApproximate the distance from the start of the curve to the point
        `t` on the curve.
        r>   rE   )r   r   r?   r   r0   rK   )r*   r|   r   steprB   r   r   r   s           r,   rL   zApproxParamT.distance-  s~     883~;zAH!5))Qte|a/04777r.   N)r   r{   r   r   r   r0   rk   )r/   r   )rL   r   )r|   r   r/   r   )
rl   rm   rn   ro   r-   rq   r   r   r   rL   rr   r.   r,   r   r      s         2 & & & & & &    X    X# # # # 8 8 8 8 8 8r.   r   绽|=p1Sequence[Vec2]p2
list[Vec2]c                Z    t          | ||          }|                                 |j        S )aV  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r   r   abs_tol	intersects       r,   r   r   =  0      (B88I""r.   Sequence[Vec3]
list[Vec3]c                Z    t          | ||          }|                                 |j        S )aV  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.   ar0   btuple[int, int, int, int]c                    | |z   dz  }| |||fS )Nr    rr   )r   r   ms      r,   rf   rf   g  s    	
Q1AaA:r.   r
   TCachec                      e Zd ZU ded<   ded<   ddZej        dd	            Zej        dd            ZddZ	ddZ
ddZdS )_PolylineIntersectionr   r   r   r/   Nonec                    i | _         d S rS   )
bbox_cacher2   s    r,   r-   z_PolylineIntersection.__init__s  s     #%r.   pointsr   c                    d S rS   rr   r*   r   s     r,   bboxz_PolylineIntersection.bboxx      r.   s1r0   e1s2e2c                    d S rS   rr   )r*   r   r   r   r   s        r,   line_intersectionz'_PolylineIntersection.line_intersection|  r   r.   c                    t          | j                  }t          | j                  }|dk     s|dk     rd S |                     d|dz
  d|dz
             d S )Nr    r   rE   )r&   r   r   r   )r*   l1l2s      r,   r   z_PolylineIntersection.execute  sX    dg,,dg,,66R!VVFq"q&!R!V,,,,,r.   r   c                   |dz  }|dz  }||z
  dk     s	||z
  dk     rdS | j         }d||f}|                    |          }|'|                     | j        ||                   }|||<   d||f}|                    |          }	|	'|                     | j        ||                   }	|	||<   |                    |	          S )NrE   r    F)r   getr   r   r   has_overlap)
r*   r   r   r   r   cachekey1bbox1key2bbox2s
             r,   overlapz_PolylineIntersection.overlap  s    
a
a 7Q;;"r'A++52r{		$=IIdgben--EE$K2r{		$=IIdgben--EE$K  '''r.   c                R   ||k    r||k    sJ ||z
  dk    r#||z
  dk    r|                      ||||           d S t          ||          \  }}}}t          ||          \  }	}
}}|                     |||	|
          r|                     |||	|
           |                     ||||          r|                     ||||           |                     |||	|
          r|                     |||	|
           |                     ||||          r|                     ||||           d S d S )NrE   )r   rf   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   z_PolylineIntersection.intersect  sT   Bww2777"7a<<BGqLL""2r2r222F!'BdD$!'BdD$<<dD$// 	3NN4tT222<<dD$// 	3NN4tT222<<dD$// 	3NN4tT222<<dD$// 	3NN4tT22222	3 	3r.   N)r/   r   r   r   r/   r   
r   r0   r   r0   r   r0   r   r0   r/   r   )
r   r0   r   r0   r   r0   r   r0   r/   r   )rl   rm   rn   __annotations__r-   abcabstractmethodr   r   r   r   r   rr   r.   r,   r   r   o  s         LLLLLL% % % %
 	    	   - - - -( ( ( (,3 3 3 3 3 3r.   r   c                  2     e Zd Zdd fdZdd
ZddZ xZS )r   r   r   r   r   c                    t                                                       || _        || _        g | _        || _        d S rS   superr-   r   r   r   r   r*   r   r   r   r:   s       r,   r-   z _PolylineIntersection2d.__init__  :    )+r.   r   r   r/   r   c                     t          |          S rS   )r   r   s     r,   r   z_PolylineIntersection2d.bbox  s    V$$$r.   r   r0   r   r   r   r   c                $     j         |          j         |         f} j        |          j        |         f}t          ||d j                  =t	           fd j        D                       s j                                       d S d S d S )NFvirtualr   c              3  P   K   | ] }                     |j                   V  !dS )r   Nr'   r   r   ippr*   s     r,   r   z<_PolylineIntersection2d.line_intersection.<locals>.<genexpr>  F       %
 %
46AIIb$,I//%
 %
 %
 %
 %
 %
r.   )r   r   r   r   anyr   r(   r*   r   r   r   r   line1line2r   s   `      @r,   r   z)_PolylineIntersection2d.line_intersection      TWR[(TWR[(%5%
 
 
 = %
 %
 %
 %
 %
:>:L%
 %
 %
 "
 "
= %%a((((( ===r.   r   )r   r   r   r   r   r   rl   rm   rn   r-   r   r   __classcell__r:   s   @r,   r   r     sj              % % % %	) 	) 	) 	) 	) 	) 	) 	)r.   r   c                  2     e Zd Zdd fdZdd
ZddZ xZS )r   r   r   r   r   c                    t                                                       || _        || _        g | _        || _        d S rS   r   r   s       r,   r-   z _PolylineIntersection3d.__init__  r   r.   r   r   r/   r   c                     t          |          S rS   )r   r   s     r,   r   z_PolylineIntersection3d.bbox  s    6"""r.   r   r0   r   r   r   r   c                $     j         |          j         |         f} j        |          j        |         f}t          ||d j                  =t	           fd j        D                       s j                                       d S d S d S )NFr   c              3  P   K   | ] }                     |j                   V  !dS r   r   r   s     r,   r   z<_PolylineIntersection3d.line_intersection.<locals>.<genexpr>  r   r.   )r   r   r   r   r   r   r(   r   s   `      @r,   r   z)_PolylineIntersection3d.line_intersection  r   r.   r   )r   r   r   r   r   r   r   r   s   @r,   r   r     sj              # # # #	) 	) 	) 	) 	) 	) 	) 	)r.   r   )r   rs   r/   rt   r   )r   r   r   r   r/   r   )r   r   r   r   r/   r   )r   r0   r   r0   r/   r   )(
__future__r   typingr   r   r   r   r   r   typing_extensionsr	   r
   numpyrd   
ezdxf.mathr   r   r   r   r   r   r   r   r   rT   __all__rp   r   r)   r{   r   r   r   rf   r0   r   r   r   r   r   rr   r.   r,   <module>r      s   # " " " " " "              


 1 1 1 1 1 1 1 1    
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
    o% o% o% o% o%8 o% o% o%d        (   
J8 J8 J8 J8 J8 J8 J8 J8\ 5:# # # # #, 5:# # # # #*   
 sC}-/BBC C C C C=3 =3 =3 =3 =3 =3 =3 =3@) ) ) ) )3 ) ) ).) ) ) ) )3 ) ) ) ) )r.   