
    h                       S SK Jr  S SKJrJrJrJrJr  S SKJ	r	  S SK
r
S SK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Jr  / SQr " S S	\	5      r        S.S
 jr " S S5      r " S S5      r " S S5      r      S/S jrS0S jr\4       S1S jjr  " S S\5      r!\4     S2S jjr"      S3S jr# " S S5      r$ " S S\%5      r& " S S5      r'S4S jr(S5S jr)S r*\4           S6S! jjr+ " S" S#\RX                  5      r-      S7S$ jr.      S7S% jr/S7S& jr0        S8S' jr1S(r2S)r3S*r4S+r5 " S, S-5      r6g)9    )annotations)IterableSequenceOptionalIteratorCallable)ProtocolN)Vec2UVecintersection_line_line_2dis_point_in_polygon_2dhas_clockwise_orientationpoint_to_line_relation	TOLERANCEBoundingBox2d)take2pairwise)	greiner_hormann_uniongreiner_hormann_differencegreiner_hormann_intersectionClippingConvexClippingPolygon2dConcaveClippingPolygon2dClippingRect2dInvertedClippingPolygon2dCohenSutherlandLineClipping2dc                  <    \ rS rSrSS jrS	S jrS
S jrSS jrSrg)r   #   c                    g)z)Returns the parts of the clipped polygon.N selfpolygons     E/var/www/html/env/lib/python3.13/site-packages/ezdxf/math/clipping.pyclip_polygonClipping.clip_polygon$           c                    g)*Returns the parts of the clipped polyline.Nr    r"   polylines     r$   clip_polylineClipping.clip_polyline'   r'   r(   c                    g)&Returns the parts of the clipped line.Nr    )r"   startends      r$   	clip_lineClipping.clip_line*   r'   r(   c                    g)z8Returns ``True`` if `point` is inside the clipping path.Nr    r"   points     r$   	is_insideClipping.is_inside-   r'   r(   r    Nr#   Sequence[Vec2]returnSequence[Sequence[Vec2]]r,   r;   r<   r=   r1   r
   r2   r
   r<   zSequence[tuple[Vec2, Vec2]]r7   r
   r<   bool)	__name__
__module____qualname____firstlineno__r%   r-   r3   r8   __static_attributes__r    r(   r$   r   r   #   s    895Gr(   r   c                l   [        U 5      S:  a  / $ / n/ nU S   nU SS  Hx  nUnUnU" Xv5       He  n[        U5      S:w  a  M  U(       a?  Uu  pUS   R                  XS9(       a  UR                  U
5        MI  UR                  U5        [        U5      nMg     Mz     U(       a  UR                  U5        U$ )r*      r      Nabs_tol)leniscloseappendlist)r,   line_clipperrL   resultparts
next_startr2   r1   clipped_line
clip_startclip_ends              r$   _clip_polylinerX   1   s     8}q	F E!J|
(4L< A%'3$
":%%j%BMM(+V$,'F 5  VLr(   c                  R    \ rS rSrSrS\4SS jjrSS jrSS jrSS jr	SS jr
S	rg
)r   N   z4The clipping path is an arbitrary convex 2D polygon.Tc                <   X0l         [        U5      n[        U5      S:  a5  US   R                  US   U R                   S9(       a  UR	                  5         [        U5      S:  a  [        S5      eU(       a   [        U5      (       a  UR                  5         X@l        g NrI   r   rJ   rK      1more than 3 vertices as clipping polygon required)	rL   rP   rM   rN   pop
ValueErrorr   reverse_clipping_polygon)r"   vertices	ccw_checkrL   clips        r$   __init__ ConvexClippingPolygon2d.__init__Q   st    H~t9q=AwtBx>
t9q=PQQ2488LLN-1r(   c                >    [        XR                  U R                  S9$ )r*   rK   rX   r3   rL   r+   s     r$   r-   %ConvexClippingPolygon2d.clip_polyline]   s    hMMr(   c                4  ^ ^^^^ SUU4S jjnSUUUUU 4S jjnT R                   S   mUmUmT R                    HW  mU" T5      (       a  U" T5      (       d  U" T5      mO/U" T5      (       a  U" T5      (       d  U" T5      mO[        5       s  $ TmMY     TT44$ )r0   c                   > TR                   TR                   -
  U R                  TR                  -
  -  TR                  TR                  -
  U R                   TR                   -
  -  -
  S:  $ N        xyr7   rW   rV   s    r$   r8   4ConvexClippingPolygon2d.clip_line.<locals>.is_insided   s]    JJ-%''JLL2HI

Z\\):<<'M) ),/0 0r(   c                D   > [        TT4TT4TR                  S9nUc  U $ U$ NrK   )r   rL   )defaultiprW   rV   edge_end
edge_startr"   s     r$   edge_intersection<ConvexClippingPolygon2d.clip_line.<locals>.edge_intersectionj   s3    *X&X(>B zIr(   rJ   r@   )rv   r
   r<   r
   )rb   tuple)	r"   r1   r2   r8   rz   rW   rV   rx   ry   s	   `    @@@@r$   r3   !ConvexClippingPolygon2d.clip_linea   s    	0 	0	 	 ++B/

..H$$ **0:H8$$ ,,!2:!>Jw!J / X&((r(   c                *  ^ ^^^^^	 SUU4S jjnSUUUUU	U 4S jjnT R                   S   m[        U5      mT R                    H  mT(       d    T4$ TR                  5       n[        U5      S:  a5  US   R	                  US   T R
                  S9(       a  UR                  5         TR                  5         US   m	U HL  mU" T5      (       a&  U" T	5      (       d  U" 5         TR                  T5        OU" T	5      (       a  U" 5         Tm	MN     TmM     T4$ )	IReturns the parts of the clipped polygon. A polygon is a closed polyline.c                   > TR                   TR                   -
  U R                  TR                  -
  -  TR                  TR                  -
  U R                   TR                   -
  -  -
  S:  $ rm   ro   rr   s    r$   r8   7ConvexClippingPolygon2d.clip_polygon.<locals>.is_inside   s]    JJ-%''JLL2HI

Z\\):<<'M) )+./ /r(   c                 b   > [        TT4TT4TR                  S9n U b  TR                  U 5        g g ru   )r   rL   rO   )rw   rW   rV   clippedrx   ry   r"   s    r$   rz   ?ConvexClippingPolygon2d.clip_polygon.<locals>.edge_intersection   s:    *X&X(>B ~r" r(   rJ   rI   r   rK   r@   )r<   None)	rb   rP   copyrM   rN   rL   r_   clearrO   )
r"   r#   r8   rz   rc   rW   rV   r   rx   ry   s
   `    @@@@@r$   r%   $ConvexClippingPolygon2d.clip_polygon   s   	/ 	/	# 	# ++B/
w-..H( z% ||~H8}q Xa[%8%8dll &9 & MMO!"J$X&&$Z00)+NN8,z**%'%
 % "J- /. zr(   c                2    [        XR                  5      S:  $ );Returns ``True`` if `point` is inside the clipping polygon.r   r   rb   r6   s     r$   r8   !ConvexClippingPolygon2d.is_inside   s    %e-C-CDIIr(   )rb   rL   Nrc   Iterable[Vec2]r>   r?   r:   r@   )rB   rC   rD   rE   __doc__r   rf   r-   r3   r%   r8   rF   r    r(   r$   r   r   N   s'    >;? 
2N)B*XJr(   r   c                  Z    \ rS rSrSr\4SS jjrSS jrSS jrSS jr	SS jr
SS jrS	rg
)r      zcThe clipping path is an axis-aligned rectangle, where all sides are parallel to
the x- and y-axis.
c           	        X0l         [        X45      U l        U R                  R                  nU R                  R                  n[        U[        UR                  UR                  5      U[        UR                  UR                  5      /SU R                   S9U l	        [        U R                  R                  U R                  R                  5      U l        g )NF)rd   rL   )rL   r   _bboxextminextmaxr   r
   rp   rq   rb   r   _line_clipper)r"   bottom_left	top_rightrL   s       r$   rf   ClippingRect2d.__init__   s    "K#;<
jj''JJ%%	!8Y[[+--0[]]IKK0	 LL	"
 ;JJtzz00
r(   c                8    U R                   R                  U5      $ )r   )rb   r%   r!   s     r$   r%   ClippingRect2d.clip_polygon   s    %%227;;r(   c                B    [        XR                  U R                  5      $ )r*   ri   r+   s     r$   r-   ClippingRect2d.clip_polyline   s    hEEr(   c                p    U R                   R                  X5      n[        U5      S:X  a  U4$ [        5       $ )Returns the clipped line.rH   )r   r3   rM   r|   )r"   r1   r2   rR   s       r$   r3   ClippingRect2d.clip_line   s3    ##--e9v;!9wr(   c                8    U R                   R                  U5      $ )z=Returns ``True`` if `point` is inside the clipping rectangle.)r   insider6   s     r$   r8   ClippingRect2d.is_inside   s    zz  ''r(   c                8    U R                   R                  U5      $ )zKReturns ``True`` if `other` bounding box intersects the clipping rectangle.)r   has_intersection)r"   others     r$   r   ClippingRect2d.has_intersection   s    zz**511r(   )r   rb   r   rL   N)r   r
   r   r
   r:   r>   r?   r@   )r   r   r<   rA   )rB   rC   rD   rE   r   r   rf   r%   r-   r3   r8   r   rF   r    r(   r$   r   r      s-     DM 
&<F(2r(   r   c                  P    \ rS rSrSr\4S
S jjrSS jrSS jrSS jr	SS jr
Srg	)r      z5The clipping path is an arbitrary concave 2D polygon.c                   X l         [        U5      n[        U5      S:  a5  US   R                  US   U R                   S9(       a  UR	                  5         [        U5      S:  a  [        S5      eX0l        [        U5      U l        g r\   )	rL   rP   rM   rN   r_   r`   rb   r   r   )r"   rc   rL   re   s       r$   rf   !ConcaveClippingPolygon2d.__init__   si    H~t9q=AwtBx>
t9q=PQQ!%"4(
r(   c                    U R                   R                  U5      (       d  g[        XR                  U R                  S9S:  $ )r   FrK   r   )r   r   r   rb   rL   r6   s     r$   r8   "ConcaveClippingPolygon2d.is_inside   s;    zz  ''"5*@*@$,,W	
r(   c                0   U R                   nX4nU R                  R                  [        U5      5      (       d
  [	        5       $ [        U R                  U5      n[        XR                  5      S:  n[        U5      S:X  a  U(       a  U4$ [	        5       $ [        X R                  US9S:  nU(       a(  US   R                  X#S9(       d  UR                  U5        U(       a)  US   R                  XS9(       d  UR                  SU5        [        U5      S:  a,  US   R                  US   US9(       a  UR                  S5        [        U5      S:  a+  US   R                  US   US9(       a  UR                  5         [        U R                  X5      (       aj  / n[        U5       HW  u  pU	R                  XS9(       a  M  [        U	R                  U
5      U R                  US9S:  d  ME  UR                  X45        MY     U$ [!        [#        U5      5      $ )r   r   rK   rJ   rI   )rL   r   has_overlapr   r|   polygon_line_intersections_2drb   r   rM   rN   rO   insertr_   has_collinear_edger   lerprP   r   )r"   r1   r2   rL   lineintersectionsstart_is_insideend_is_insidesegmentsabs              r$   r3   "ConcaveClippingPolygon2d.clip_line   s   ,,|zz%%mD&9::7N5d6L6LdS08N8NOSTT}"w7N"3(>(>PTUU 	 r!2!:!:3!:!P  %=#3#;#;E#;#S  E* }!mA&6&>&>!g '? '
 a }!mB&7&?&?"w '@ '
 d44eAA 13H /99Q90*q	4#9#97 
 OOQF+ 0 O
 E-())r(   c                   U R                   n/ n[        U5       Hg  u  pEU R                  XE5       HM  u  pgU(       a/  US   nUS   R                  XbS9(       a  UR	                  U5        M;  UR	                  Xg/5        MO     Mi     U$ )r*   rJ   rK   )rL   r   r3   rN   rO   )	r"   r,   rL   r   r1   r2   r   r   last_segs	            r$   r-   &ConcaveClippingPolygon2d.clip_polyline6  s{    ,,%'"8,JEu2'|H|++A+? * ' 3 - r(   c                  ^ ^ [        U5      nT R                  m[        U5      S:  a+  US   R                  US   TS9(       a  UR	                  5         [        U5      S:  a
  [        5       $ [        U5      nT R                  R                  U5      (       d
  [        5       $ [        T R                  U5      n[        U5      S:X  a*  [        UU 4S jU 5       5      nU(       a
  [        5       $ U4$ U$ )r   rI   r   rJ   rK   r]   c              3  T   >#    U  H  n[        UTR                  TS 9S:  v   M     g7f)rK   r   Nr   ).0vrL   r"   s     r$   	<genexpr>8ConcaveClippingPolygon2d.clip_polygon.<locals>.<genexpr>R  s-      !A 'q$*@*@'RUVV!s   %()rP   rL   rM   rN   r_   r|   r   r   r   clip_arbitrary_polygonsrb   any)r"   r#   rc   polygon_boxrR   
is_outsiderL   s   `     @r$   r%   %ConcaveClippingPolygon2d.clip_polygonD  s    =,,x=1{""8B<"Ax=17N#H-zz**;777N()?)?Jv;! ! J w;r(   r   rb   rL   Nr   r@   r?   r>   r:   )rB   rC   rD   rE   r   r   rf   r8   r3   r-   r%   rF   r    r(   r$   r   r      s"    ?9B 
)
9*vr(   r   c                x    [         R                  U 5      n[         R                  U5      nUR                  U5      $ )zReturns the parts of the clipped subject. Both polygons can be concave

Args:
    clipper: clipping window closed polygon
    subject: closed polygon to clip

)	GHPolygon	from_vec2intersection)clippersubject
gh_clipper
gh_subjects       r$   r   r   ]  s5     $$W-J$$W-J"":..r(   c                t    U S   n[        X1U5      nU  H!  n[        XQU5      nUS:X  a  US:X  a    gUnUnM#     g)zJReturns ``True`` if `polygon` has any collinear edge to line `start->end`.rJ   r   TF)r   )r#   r1   r2   r   rel_ar   rel_bs          r$   r   r   m  sL    A"1S1E&q5A:%1*  r(   c                  ^ / nUu  mn[        U 5      n[        U5       H  nXS-
     nX   n[        Xx4USUS9n	U	c  M   U	R                  XrS9(       a%  XS-
     n
[	        U
TXBS9n[	        UTXBS9nX:X  a  MX  O;U	R                  XS9(       a'  XS-   U-     n[	        UTXBS9n[	        UTXBS9nX:X  a  M  UR                  U	5        M     UR                  U4S jS9  U$ )a>  Returns all intersections of polygon with line.
All intersections points are ordered from start to end of line.
Start and end points are not included if not explicit intersection points.

.. Note::

    Returns duplicate intersections points when the line intersects at
    the connection point of two polygon edges!

rI   F)virtualrL   rK   rH   c                &   > U R                  T5      $ N)distance)rw   r1   s    r$   <lambda>/polygon_line_intersections_2d.<locals>.<lambda>  s    BKK,>r(   )key)rM   ranger   rN   r   rO   sort)r#   r   rL   intersection_pointsr2   sizeindexr   r   rw   a_prevrel_prevrel_nextb_nextr1   s                 @r$   r   r   z  s    ')JE3w<DtAIN&vtUGT: ::a:)QY'F-feSRH-aMH# $ ZZZ+ai4/0F-aMH-feSRH#""2&+ . !>?r(   c                  .    \ rS rSrSr\4   SS jjrSrg)r   i  a  This class represents an inverted clipping path.  Everything between the inner
polygon and the outer extents is considered as inside.  The inner clipping path is
an arbitrary 2D polygon.

.. Important::

    The `outer_bounds` must be larger than the content to clip to work correctly.

c                   X0l         [        U5      n[        U5      S:  a/  US   R                  US   US9(       d  UR	                  US   5        [        U5      S:  a  [        S5      e[        XBU5      U l        X l        g )NrI   r   rJ   rK      r^   )	rL   rP   rM   rN   rO   r`   make_inverted_clipping_polygonrb   r   )r"   inner_polygonouter_boundsrL   re   s        r$   rf   "InvertedClippingPolygon2d.__init__  sy     M"t9q=7??48W?=DG$t9q=PQQ
 "@"
 "
r(   r   N)r   r   r   r   )rB   rC   rD   rE   r   r   rf   rF   r    r(   r$   r   r     s(     	"%" $" "r(   r   c                   UR                   SL d   eU R                  5       n U S   R                  U S   US9(       a  U R                  5         [	        U 5      S:  d   e[        UR                  5       5      nUR                  5         [        X5      u  pEXS nUR                  U SUS-    5        UR                  X5S 5        UR                  USUS-    5        UR                  US   5        U$ )zCreates a closed inverted clipping polygon by connecting the inner polygon with
the surrounding rectangle at their closest vertices.
Tr   rJ   rK   rH   NrI   )has_datar   rN   r_   rM   rP   rect_verticesra   find_closest_verticesextendrO   )r   r   rL   
outer_rectcicorR   s          r$   r   r     s       D(((!&&(MQb 17C}!!!l0023J"==FB3F
MM-"q&)*
MM*S/"
MM*XrAv&'
MM&)Mr(   c                    [         R                  nSn[        U 5       H6  u  pE[        U5       H"  u  pgUR                  U5      nX:  d  M  UnXF4nM$     M8     U$ )z:Returns the indices of the closest vertices of both lists.)r   r   )mathinf	enumerater   )		vertices0	vertices1min_distrR   i0v0i1v1r   s	            r$   r   r     sZ     xxH"FI&	*FB{{2H"#	 + ' Mr(   c                  6    \ rS rSr    S   SS jjrS rSrg)_Nodei  c                j    Xl         S U l        S U l        S U l        X@l        X l        X0l        XPl        g r   )vtxnextprevneighborentryalpha	intersectchecked)r"   r  r
  r  r	  r  s         r$   rf   _Node.__init__  s@       	  	  $ !
 "
  ) %r(   c                    SU l         U R                  (       a7  U R                  R                   (       d  U R                  R                  5         g g g NT)r  r  set_checked)r"   s    r$   r  _Node.set_checked  s3    ==!6!6MM%%' "7=r(   )r
  r  r	  r  r  r  r  r  N)rn   FTF)r  r
   r
  float)rB   rC   rD   rE   rf   r  rF   r    r(   r$   r  r    s,     %% %>(r(   r  c                      \ rS rSrSrg)IntersectionErrori  r    N)rB   rC   rD   rE   rF   r    r(   r$   r  r    s    r(   r  c                      \ rS rSr% SrS\S'   SrS\S'   SS jr\SS	 j5       r	\SS
 j5       r
\SS j5       rSS jr\SS j5       r\SS j5       rS rSS jrSS jrSS jrSS jrSrg)r   i  Nr  firstg    .Ar  max_xc                *   [        U R                  UR                  R                  5      U l        U R                  c'  Xl        XR                  l        XR                  l        gU R                  nUR                  nXl        X!l        X1l        Xl        g)zAdd a polygon vertex node.N)maxr  r  rp   r  r  r  )r"   noder  lasts       r$   addGHPolygon.add   se     TXXZZ0
::J"JJO"JJOJJE::DJIIIr(   c                T    [         R                  [        R                  " U 5      5      $ z3Build a new GHPolygon from an iterable of vertices.)r   r   r
   rP   )rc   s    r$   buildGHPolygon.build0  s     ""499X#677r(   c                `    [        5       nU  H  nUR                  [        U5      5        M     U$ r  )r   r  r  )rc   r#   r   s      r$   r   GHPolygon.from_vec25  s*     +AKKa! r(   c                    UnX2:w  aG  UR                   U R                   :  a-  UR                  nX2:w  a  UR                   U R                   :  a  M-  X0l        UR                  nX@l        Xl        Xl        g)a  Insert and sort an intersection node.

This function inserts an intersection node between two other
start- and end node of an edge. The start and end node cannot be
an intersection node (that is, they must be actual vertex nodes of
the original polygon). If there are multiple intersection nodes
between the start- and end node, then the new node is inserted
based on its alpha value.
N)r
  r  r  )vertexr1   r2   currr  s        r$   r   GHPolygon.insert=  s[     kdjj6<<799D kdjj6<<7 yy		r(   c              #     #    U R                   c   eU R                   n Uv   UR                  nXR                   L a  g M!  7fr   )r  r  )r"   ss     r$   __iter__GHPolygon.__iter__R  s@     zz%%%JJGAJJ	 s   >A c                f    U  H+  nUR                   (       d  M  UR                  (       a  M)  Us  $    g r   r  r  r"   r   s     r$   first_intersectGHPolygon.first_intersect[  s'    A{{{1999  r(   c                    U  Vs/ s H  oR                   PM     nnUS   R                  US   5      (       d  UR                  US   5        U$ s  snf )Nr   rJ   )r  rN   rO   )r"   r   pointss      r$   r2  GHPolygon.pointsb  sK    !%&A%%&ay  ,,MM&)$ 's   Ac                b    U  H)  nUR                   (       d  M  UR                  (       a  M)    g   g)NTFr-  r.  s     r$   unprocessedGHPolygon.unprocessedi  s%    A{{{1999  r(   c                (    U R                  USS5      $ )NFre   r"   re   s     r$   unionGHPolygon.uniono  s    yyue,,r(   c                (    U R                  USS5      $ r  r8  r9  s     r$   r   GHPolygon.intersectionr  s    yytT**r(   c                (    U R                  USS5      $ )NFTr8  r9  s     r$   
differenceGHPolygon.differenceu  s    yyud++r(   c           
     r   U  GH  nUR                   (       a  M  U H  nUR                   (       a  M  [        UR                  [        UR                  5      R                  UR                  [        UR                  5      R                  5      u  pgnUc  Mz  [        XgSSS9n	[        XhSSS9n
Xl        Xl        U R                  U	U[        UR                  5      5        UR                  U
U[        UR                  5      5        M     GM     U[        U R                  R                  U5      -  nU  H#  nUR                   (       d  M  X$l
        U(       + nM%     U[        UR                  R                  U 5      -  nU H#  nUR                   (       d  M  X5l
        U(       + nM%     / nU R                  5       (       a  U R                  nUR                  /n UR                  5         UR                  (       a<   UR                  nUR                  UR                  5        UR                   (       a  O>M;   UR                  nUR                  UR                  5        UR                   (       a  OM;  UR                  nUR                   (       a  OM  UR                  U5        U R                  5       (       a  M  U$ )a  Clip this polygon using another one as a clipper.

This is where the algorithm is executed. It allows you to make
a UNION, INTERSECT or DIFFERENCE operation between two polygons.

Given two polygons A, B the following operations may be performed:

A|B ... A OR B  (Union of A and B)
A&B ... A AND B (Intersection of A and B)
A\B ... A - B
B\A ... B - A

The entry records store the direction the algorithm should take when
it arrives at that entry point in an intersection. Depending on the
operation requested, the direction is set as follows for entry points
(f=forward, b=backward; exit points are always set to the opposite):

      Entry
      A   B
      -----
A|B   b   b
A&B   f   f
A\B  b   f
B\A  f   b

f = True, b = False when stored in the entry record
TF)r  r	  )r  line_intersectionr  next_vertex_noder  r  r  r   is_inside_polygonr  r	  r5  r/  r  rO   r  r  )r"   re   s_entryc_entrysubject_vertexclipper_vertexrw   usucsubject_nodeclipper_nodeclipped_polygonscurrentr   s                 r$   re   GHPolygon.clipy  sN   : #N!+++&*N)333%6*..,^-@-@AEE*..,^-@-@AEE	&
 :$',Rt5'Q',Rt5'Q0<-0<-(*,^-@-@A
 (*,^-@-@A) '+ #: 	$TZZ^^T::"N''''.$%+ #
 	$TZZ^^T::"N''''.$%+ # .0  !11G#*;;-G##%=="),,w{{3",,!	  "),,w{{3",,!	  "**??# $ ##G,+   ,  r(   )r  r  )r  r  )rc   Iterable[UVec]r<   r   )rc   r;   r<   r   )r%  r  r1   r  r2   r  )r<   zIterator[_Node])r<   zOptional[_Node])r<   
list[Vec2])re   r   r<   list[list[Vec2]])rB   rC   rD   rE   r  __annotations__r  r  staticmethodr   r   r   r*  propertyr/  r2  r5  r:  r   r?  re   rF   r    r(   r$   r   r     s    E5E5  8 8    (    -+,^ r(   r   c                j    U nUR                   (       a  UR                  nUR                   (       a  M  U$ )z@Return the next non-intersecting vertex after the one specified.)r  r  )r   cs     r$   rC  rC    s'    	A
++FF +++Hr(   c                8    [        XR                  [        S9S:  $ )z2Returns ``True`` if  `vertex` is inside `polygon`.rK   r   )r   r2  r   )r%  r#   s     r$   rD  rD    s     "&..)LPQQQr(   )Nr   r   c                   UR                   UR                   -
  UR                  U R                  -
  -  UR                  UR                  -
  UR                   U R                   -
  -  -
  n[        U5      U:  a  [        $ UR                  UR                  -
  U R                   UR                   -
  -  UR                   UR                   -
  U R                  UR                  -
  -  -
  U-  nSU-   nSU-
  nXvs=:  a  U:  d   [        $   [        $ UR                  U R                  -
  U R                   UR                   -
  -  UR                   U R                   -
  U R                  UR                  -
  -  -
  U-  n	Xys=:  a  U:  ac  O  [        $ [	        U R                  XaR                  U R                  -
  -  -   U R                   XaR                   U R                   -
  -  -   5      UU	4$ [        $ )zReturns the intersection point between two lines.

This special implementation excludes the line end points as intersection
points!

Algorithm based on: http://paulbourke.net/geometry/lineline2d/
rn   g      ?)rq   rp   abs_ERRORr
   )
s1s2c1c2toldenrI  lwruprrJ  s
             r$   rB  rB    sy    44"$$;244"$$;
'244"$$;244"$$;*G
GC
3x#~44"$$;244"$$;
'244"$$;244"$$;*G
G3	NB
)C
)C NsN 44"$$;244"$$;
'244"$$;244"$$;*G
G3	NB
~#~ M	 ddRTTk**BDD23E,EF
 	

 Mr(   c                       \ rS rSrSrSrSrSrg)BooleanOperationi  r:  r?  r   r    N)rB   rC   rD   rE   UNION
DIFFERENCEINTERSECTIONrF   r    r(   r$   re  re    s    EJ!Lr(   re  c                6    [        X[        R                  5      $ )zReturns the INTERSECTION of polygon `p1` &  polygon `p2`.
This algorithm works only for polygons with real intersection points
and line end points on face edges are not considered as such intersection
points!

)greiner_hormannre  rh  p1p2s     r$   r   r     s     2#3#@#@AAr(   c                6    [        X[        R                  5      $ )zReturns the DIFFERENCE of polygon `p1` - polygon `p2`.
This algorithm works only for polygons with real intersection points
and line end points on face edges are not considered as such intersection
points!

)rj  re  rg  rk  s     r$   r   r     s     2#3#>#>??r(   c                6    [        X[        R                  5      $ )zReturns the UNION of polygon `p1` | polygon `p2`.
This algorithm works only for polygons with real intersection points
and line end points on face edges are not considered as such intersection
points!

)rj  re  rf  rk  s     r$   r   r   )  s     2#3#9#9::r(   c                P   [         R                  U 5      n[         R                  U5      nU[        R                  :X  a  UR	                  U5      $ U[        R
                  :X  a  UR                  U5      $ U[        R                  :X  a  UR                  U5      $ [        SU 35      e)u  Implements a 2d clipping function to perform 3 boolean operations:

- UNION: p1 | p2 ... p1 OR p2
- INTERSECTION: p1 & p2 ... p1 AND p2
- DIFFERENCE: p1 \ p2 ... p1 - p2

Based on the paper "Efficient Clipping of Arbitrary Polygons" by
Günther Greiner and Kai Hormann.
This algorithm works only for polygons with real intersection points
and line end points on face edges are not considered as such intersection
points!

z*unknown or unsupported boolean operation: )
r   r   re  rf  r:  rg  r?  rh  r   r`   )rl  rm  oppolygon1polygon2s        r$   rj  rj  3  s      r"Hr"H	###~~h''	**	*""8,,	,,	,$$X..
A"F
GGr(   rI   rH   r      c                  :    \ rS rSrSrSrS	S jrS
S jrSS jrSr	g)r   iU  zCohen-Sutherland 2D line clipping algorithm, source:
https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm

Args:
    w_min: bottom-left corner of the clipping rectangle
    w_max: top-right corner of the clipping rectangle

)x_minx_maxy_miny_maxc                @    Uu  U l         U l        Uu  U l        U l        g r   )rv  rx  rw  ry  )r"   w_minw_maxs      r$   rf   &CohenSutherlandLineClipping2d.__init__a  s    !&
DJ!&
DJr(   c                    SnXR                   :  a
  U[        -  nOXR                  :  a	  U[        -  nX R                  :  a  U[
        -  nU$ X R                  :  a	  U[        -  nU$ )Nr   )rv  LEFTrw  RIGHTrx  BOTTOMry  TOP)r"   rp   rq   codes       r$   encode$CohenSutherlandLineClipping2d.encodee  s]    zz>DLD^EMDzz>FND  ^CKDr(   c                   Uu  p4Uu  pVU R                  X45      nU R                  XV5      nUn	Un
 Xx-  (       d  [        X45      [        XV5      4$ Xx-  (       a
  [        5       $ X:  a  UOUnU[        -  (       a)  X5U-
  U R                  U-
  -  Xd-
  -  -   n	U R                  n
OU[
        -  (       a)  X5U-
  U R                  U-
  -  Xd-
  -  -   n	U R                  n
OmU[        -  (       a)  XFU-
  U R                  U-
  -  XS-
  -  -   n
U R                  n	O6U[        -  (       a(  XFU-
  U R                  U-
  -  XS-
  -  -   n
U R                  n	X:X  a  U	nU
nU R                  X45      nOU	nU
nU R                  XV5      nGMI  )zReturns the clipped line part as tuple[Vec2, Vec2] or an empty tuple.

Args:
    p0: start-point of the line to clip
    p1: end-point of the line to clip

)r  r
   r|   r  ry  r  rx  r  rw  r  rv  )r"   p0rl  x0y0x1y1code0code1rp   rq   r  s               r$   r3   'CohenSutherlandLineClipping2d.clip_lineq  sm    B#B#= B|T"\11} w
 "M5uD czr'djj2o6"'BBJJr'djj2o6"'BBJJr'djj2o6"'BBJJr'djj2o6"'BBJJ}B+B+W r(   )rw  rv  ry  rx  N)r{  r
   r|  r
   r<   r   )rp   r  rq   r  r<   int)r  r
   rl  r
   r<   r;   )
rB   rC   rD   rE   r   	__slots__rf   r  r3   rF   r    r(   r$   r   r   U  s     5I'
9,r(   r   )r,   r;   rQ   z3Callable[[Vec2, Vec2], Sequence[tuple[Vec2, Vec2]]]rL   r  r<   r=   )r   rQ  r   rQ  r<   r=   )r#   rQ  r1   r
   r2   r
   r<   rA   )r#   rQ  r   ztuple[Vec2, Vec2]rL   r  r<   rQ  )r   rQ  r   r   r<   rQ  )r   rQ  r   rQ  r<   ztuple[int, int])r   r  r<   r  )r%  r
   r#   r   r<   rA   )r\  r
   r]  r
   r^  r
   r_  r
   r`  r  r<   z#tuple[Optional[Vec2], float, float])rl  rP  rm  rP  r<   rR  )rl  rP  rm  rP  rq  re  r<   rR  )7
__future__r   typingr   r   r   r   r   typing_extensionsr	   r   enum
ezdxf.mathr
   r   r   r   r   r   r   r   ezdxf.toolsr   r   __all__r   rX   r   r   r   r   r   r   r   r   r   r  	Exceptionr  r   rC  rD  r[  rB  Enumre  r   r   r   rj  r  r  r  r  r   r    r(   r$   <module>r     sD   # C C &  	 	 	 (
Gx GE  	:bJ bJJ-2 -2`w wt//",// 
 DM((0(;@((V" 8 "F EN-:,&0*#( #(L		 	{  { |R 
 :C &*16(>"tyy "	B	B*	B	B	@	@*	@	@;HH*H0@HH8 		U, U,r(   