
    Og                    r   d dl mZ d dlmZmZmZmZmZ d dlm	Z	 d dl
Z
d dlZd dlmZmZmZmZmZmZmZmZ d dlmZmZ g dZ G d d	e	      Z	 	 	 	 	 	 	 	 d.d
Z G d d      Z G d d      Z G d d      Z	 	 	 	 	 	 d/dZd0dZef	 	 	 	 	 	 	 d1dZ  G d de      Z!ef	 	 	 	 	 d2dZ"	 	 	 	 	 	 d3dZ# G d d      Z$ G d de%      Z& G d d      Z'd4dZ(d5dZ)d Z*ef	 	 	 	 	 	 	 	 	 	 	 d6d!Z+ G d" d#ejX                        Z-	 	 	 	 	 	 d7d$Z.	 	 	 	 	 	 d7d%Z/d7d&Z0	 	 	 	 	 	 	 	 d8d'Z1d(Z2d)Z3d*Z4d+Z5 G d, d-      Z6y)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                  ,    e Zd ZddZddZddZd	dZy)
r   c                     y)z)Returns the parts of the clipped polygon.N selfpolygons     X/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/math/clipping.pyclip_polygonzClipping.clip_polygon$           c                     y)*Returns the parts of the clipped polyline.Nr   r!   polylines     r#   clip_polylinezClipping.clip_polyline'   r%   r&   c                     y)&Returns the parts of the clipped line.Nr   )r!   startends      r#   	clip_linezClipping.clip_line*   r%   r&   c                     y)z8Returns ``True`` if `point` is inside the clipping path.Nr   r!   points     r#   	is_insidezClipping.is_inside-   r%   r&   Nr"   Sequence[Vec2]returnSequence[Sequence[Vec2]]r*   r6   r7   r8   r.   r
   r/   r
   r7   zSequence[tuple[Vec2, Vec2]]r3   r
   r7   bool)__name__
__module____qualname__r$   r+   r0   r4   r   r&   r#   r   r   #   s    895Gr&   r   c                J   t        |       dk  rg S g }g }| d   }| dd D ]n  }|}|} |||      D ]\  }t        |      dk7  r|r>|\  }	}
|d   j                  |	|      r|j                  |
       A|j                  |       t        |      }^ p |r|j                  |       |S )r(      r      Nabs_tol)leniscloseappendlist)r*   line_clipperrE   resultparts
next_startr/   r.   clipped_line
clip_startclip_ends              r#   _clip_polylinerQ   1   s     8}q	F E!J| (
(4 		(L< A%'3$
H":%%j'%BMM(+V$,'F		(( VLr&   c                  >    e Zd ZdZdefd	dZd
dZddZddZddZ	y)r   z4The clipping path is an arbitrary convex 2D polygon.Tc                $   || _         t        |      }t        |      dkD  r3|d   j                  |d   | j                         r|j	                          t        |      dk  rt        d      |rt        |      r|j                          || _        y NrB   r   rC   rD      1more than 3 vertices as clipping polygon required)	rE   rI   rF   rG   pop
ValueErrorr   reverse_clipping_polygon)r!   vertices	ccw_checkrE   clips        r#   __init__z ConvexClippingPolygon2d.__init__Q   su    H~t9q=AwtBx>
t9q=PQQ248LLN-1r&   c                F    t        || j                  | j                        S )r(   rD   rQ   r0   rE   r)   s     r#   r+   z%ConvexClippingPolygon2d.clip_polyline]   s    hMMr&   c                     dfd}d fd} j                   d   || j                   D ]B   |      r |      s. |      n% |      r |      s |      nt               c S D ffS )r-   c                    j                   j                   z
  | j                  j                  z
  z  j                  j                  z
  | j                   j                   z
  z  z
  dk\  S N        xyr3   rP   rO   s    r#   r4   z4ConvexClippingPolygon2d.clip_line.<locals>.is_insided   s]    JJ-%''JLL2HI

Z\\):<<'M) ),/0 0r&   c                H    t        ffj                        }|| S |S NrD   )r   rE   )defaultiprP   rO   edge_end
edge_startr!   s     r#   edge_intersectionz<ConvexClippingPolygon2d.clip_line.<locals>.edge_intersectionj   s3    *X&X(>B zIr&   rC   r;   )rk   r
   r7   r
   )rZ   tuple)	r!   r.   r/   r4   ro   rP   rO   rm   rn   s	   `    @@@@r#   r0   z!ConvexClippingPolygon2d.clip_linea   s    	0	 	 ++B/

.. 		"H$ *0:H8$ ,!2:!>Jw!J		" X&((r&   c                   	 dfd}d	 fd} j                   d   t        |       j                   D ]  s fS j                         }t        |      dkD  r3|d   j	                  |d    j
                        r|j                          j                          |d   	|D ]<   |      r! |	      s |        j                         n |	      r |        	>  fS )	IReturns the parts of the clipped polygon. A polygon is a closed polyline.c                    j                   j                   z
  | j                  j                  z
  z  j                  j                  z
  | j                   j                   z
  z  z
  dkD  S rc   re   rh   s    r#   r4   z7ConvexClippingPolygon2d.clip_polygon.<locals>.is_inside   s]    JJ-%''JLL2HI

Z\\):<<'M) )+./ /r&   c                 f    t        ffj                        } | j                  |        y y rj   )r   rE   rH   )rl   rP   rO   clippedrm   rn   r!   s    r#   ro   z?ConvexClippingPolygon2d.clip_polygon.<locals>.edge_intersection   s:    *X&X(>B ~r" r&   rC   rB   r   rD   r;   )r7   None)	rZ   rI   copyrF   rG   rE   rW   clearrH   )
r!   r"   r4   ro   r[   rP   rO   ru   rm   rn   s
   `    @@@@@r#   r$   z$ConvexClippingPolygon2d.clip_polygon   s    	/	# 	# ++B/
w-.. 	"H( z% ||~H8}q Xa[%8%8dll &9 & MMO!"J$ &X&$Z0)+NN8,z*%'%
& "J-	". zr&   c                4    t        || j                        dk\  S );Returns ``True`` if `point` is inside the clipping polygon.r   r   rZ   r2   s     r#   r4   z!ConvexClippingPolygon2d.is_inside   s    %eT-C-CDIIr&   Nr[   Iterable[Vec2]r9   r:   r5   r;   )
r=   r>   r?   __doc__r   r^   r+   r0   r$   r4   r   r&   r#   r   r   N   s'    >;? 
2N)B*XJr&   r   c                  D    e Zd ZdZefd	dZd
dZddZddZddZ	ddZ
y)r   zkThe clipping path is an axis-aligned rectangle, where all sides are parallel to
    the x- and y-axis.
    c           	        || _         t        ||f      | _        | j                  j                  }| j                  j                  }t        |t        |j                  |j                        |t        |j                  |j                        gd| j                         | _	        t        | j                  j                  | j                  j                        | _        y )NF)r\   rE   )rE   r   _bboxextminextmaxr   r
   rf   rg   rZ   r   _line_clipper)r!   bottom_left	top_rightrE   s       r#   r^   zClippingRect2d.__init__   s    "K#;<
jj''JJ%%	!8Y[[+--0[]]IKK0	 LL	"
 ;JJtzz00
r&   c                8    | j                   j                  |      S )rr   )rZ   r$   r    s     r#   r$   zClippingRect2d.clip_polygon   s    %%227;;r&   c                D    t        || j                  | j                        S )r(   r`   r)   s     r#   r+   zClippingRect2d.clip_polyline   s    hEEr&   c                p    | j                   j                  ||      }t        |      dk(  r|fS t               S )Returns the clipped line.rA   )r   r0   rF   rp   )r!   r.   r/   rK   s       r#   r0   zClippingRect2d.clip_line   s5    ##--eS9v;!9wr&   c                8    | j                   j                  |      S )z=Returns ``True`` if `point` is inside the clipping rectangle.)r   insider2   s     r#   r4   zClippingRect2d.is_inside   s    zz  ''r&   c                8    | j                   j                  |      S )zKReturns ``True`` if `other` bounding box intersects the clipping rectangle.)r   has_intersection)r!   others     r#   r   zClippingRect2d.has_intersection   s    zz**511r&   N)r   r
   r   r
   r5   r9   r:   r;   )r   r   r7   r<   )r=   r>   r?   r~   r   r^   r$   r+   r0   r4   r   r   r&   r#   r   r      s-     DM 
&<F(2r&   r   c                  <    e Zd ZdZefddZd	dZd
dZddZddZ	y)r   z5The clipping path is an arbitrary concave 2D polygon.c                
   || _         t        |      }t        |      dkD  r3|d   j                  |d   | j                         r|j	                          t        |      dk  rt        d      || _        t        |      | _        y rT   )	rE   rI   rF   rG   rW   rX   rZ   r   r   )r!   r[   rE   r]   s       r#   r^   z!ConcaveClippingPolygon2d.__init__   sm    H~t9q=AwtBx>
t9q=PQQ!%"4(
r&   c                    | j                   j                  |      syt        || j                  | j                        dk\  S )rz   FrD   r   )r   r   r   rZ   rE   r2   s     r#   r4   z"ConcaveClippingPolygon2d.is_inside   s:    zz  '"5$*@*@$,,W	
r&   c                   | j                   }||f}| j                  j                  t        |            s
t	               S t        | j                  |      }t        || j                        dk\  }t        |      dk(  r|r|fS t	               S t        || j                  |      dk\  }|r'|d   j                  ||      s|j                  |       |r(|d   j                  ||      s|j                  d|       t        |      dkD  r*|d   j                  |d   |      r|j                  d       t        |      dkD  r)|d   j                  |d   |      r|j                          t        | j                  ||      rig }t        |      D ]W  \  }	}
|	j                  |
|      rt        |	j                  |
      | j                  |      dk\  sE|j                  |	|
f       Y |S t!        t#        |            S )r   r   rD   rC   rB   )rE   r   has_overlapr   rp   polygon_line_intersections_2drZ   r   rF   rG   rH   insertrW   has_collinear_edger   lerprI   r   )r!   r.   r/   rE   lineintersectionsstart_is_insideend_is_insidesegmentsabs              r#   r0   z"ConcaveClippingPolygon2d.clip_line   s   ,,s|zz%%mD&9:7N5d6L6LdS08N8NOSTT}"w7N"3(>(>PTUU 	 r!2!:!:3!:!P  %=#3#;#;E7#;#S  E* }!mA&6&>&>!g '? '
 a }!mB&7&?&?"w '@ '
 d44eSA 13H / 	,199Q90*q	4#9#97 
 OOQF+	, O
 E-())r&   c                    | j                   }g }t        |      D ]a  \  }}| j                  ||      D ]G  \  }}|r-|d   }|d   j                  ||      r|j	                  |       5|j	                  ||g       I c |S )r(   rC   rD   )rE   r   r0   rG   rH   )	r!   r*   rE   r   r.   r/   r   r   last_segs	            r#   r+   z&ConcaveClippingPolygon2d.clip_polyline6  s    ,,%'"8, 	(JE3uc2 (1'|H|++Aw+? * A'(	( r&   c                    t        |      } j                  t        |      dkD  r)|d   j                  |d         r|j	                          t        |      dk  r
t               S t        |      } j                  j                  |      s
t               S t         j                  |      }t        |      dk(  r$t         fd|D              }|r
t               S |fS |S )rr   rB   r   rC   rD   rU   c              3  T   K   | ]  }t        |j                         dk   ! yw)rD   r   Nr{   ).0vrE   r!   s     r#   	<genexpr>z8ConcaveClippingPolygon2d.clip_polygon.<locals>.<genexpr>R  s.       'q$*@*@'RUVVs   %()rI   rE   rF   rG   rW   rp   r   r   r   clip_arbitrary_polygonsrZ   any)r!   r"   r[   polygon_boxrK   
is_outsiderE   s   `     @r#   r$   z%ConcaveClippingPolygon2d.clip_polygonD  s    =,,x=1{""8B<"Ax=17N#H-zz**;77N()?)?Jv;! ! J w;r&   Nr|   r;   r:   r9   r5   )
r=   r>   r?   r~   r   r^   r4   r0   r+   r$   r   r&   r#   r   r      s"    ?9B 
)
9*vr&   r   c                x    t         j                  |       }t         j                  |      }|j                  |      S )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                p    | d   }t        |||      }| D ]  }t        |||      }|dk(  r|dk(  r y|}|}! y)zJReturns ``True`` if `polygon` has any collinear edge to line `start->end`.rC   r   TF)r   )r"   r.   r/   r   rel_ar   rel_bs          r#   r   r   m  sU    A"1eS1E &q%5A:%1* r&   c                   g }|\  }t        |       }t        |      D ]  }| |dz
     }| |   }t        ||f|d|      }	|	$|	j                  ||      r,| |dz
     }
t	        |
||      }t	        |||      }||k(  rCc|	j                  ||      r/| |dz   |z     }t	        |||      }t	        |||      }||k(  r|j                  |	        |j                  fd       |S )aV  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!

    rB   F)virtualrE   rD   rA   c                &    | j                        S N)distance)rl   r.   s    r#   <lambda>z/polygon_line_intersections_2d.<locals>.<lambda>  s    BKK,> r&   )key)rF   ranger   rG   r   rH   sort)r"   r   rE   intersection_pointsr/   sizeindexr   r   rl   a_prevrel_prevrel_nextb_nextr.   s                 @r#   r   r   z  s$    ')JE3w<Dt 'EAIEN&1vtUGT: ::a:)UQY'F-feS'RH-aWMH8#ZZ7Z+eai4/0F-aWMH-feS'RH8#""2&+'. !>?r&   c                  "    e Zd ZdZef	 	 	 ddZy)r   a3  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                   || _         t        |      }t        |      dkD  r-|d   j                  |d   |      s|j	                  |d          t        |      dk  rt        d      t        |||      | _        || _        y )NrB   r   rC   rD      rV   )	rE   rI   rF   rG   rH   rX   make_inverted_clipping_polygonrZ   r   )r!   inner_polygonouter_boundsrE   r]   s        r#   r^   z"InvertedClippingPolygon2d.__init__  s     M"t9q=7??48W?=DG$t9q=PQQ
 "@,"
 "
r&   N)r   r}   r   r   )r=   r>   r?   r~   r   r^   r   r&   r#   r   r     s#     	"%" $"r&   r   c                   |j                   du sJ | j                         } | d   j                  | d   |      r| j                          t	        |       dkD  sJ t        |j                               }|j                          t        | |      \  }}| |d }|j                  | d|dz           |j                  ||d        |j                  |d|dz           |j                  |d          |S )zCreates a closed inverted clipping polygon by connecting the inner polygon with
    the surrounding rectangle at their closest vertices.
    Tr   rC   rD   rA   NrB   )has_datarw   rG   rW   rF   rI   rect_verticesrY   find_closest_verticesextendrH   )r   r   rE   
outer_rectcicorK   s          r#   r   r     s       D(((!&&(MQb 17C}!!!l0023J"=*=FB23F
MM-"q&)*
MM*RS/"
MM*XrAv&'
MM&)Mr&   c                    t         j                  }d}t        |       D ]5  \  }}t        |      D ]"  \  }}|j                  |      }||k  s|}||f}$ 7 |S )z:Returns the indices of the closest vertices of both lists.)r   r   )mathinf	enumerater   )		vertices0	vertices1min_distrK   i0v0i1v1r   s	            r#   r   r     sl     xxH"FI&  B	* 	 FB{{2H("#R		   Mr&   c                  *    e Zd Z	 	 	 	 d	 	 	 ddZd Zy)_Nodec                t    || _         d | _        d | _        d | _        || _        || _        || _        || _        y r   )vtxnextprevneighborentryalpha	intersectchecked)r!   r   r   r   r   r   s         r#   r^   z_Node.__init__  sJ       	  	  $ !
 "
  ) %r&   c                    d| _         | j                  r2| j                  j                   s| j                  j                          y y y NT)r   r   set_checked)r!   s    r#   r   z_Node.set_checked  s3    ==!6!6MM%%' "7=r&   N)rd   FTF)r   r
   r   float)r=   r>   r?   r^   r   r   r&   r#   r   r     s,     %% %>(r&   r   c                      e Zd Zy)IntersectionErrorN)r=   r>   r?   r   r&   r#   r   r     s    r&   r   c                      e Zd ZU dZded<   dZded<   ddZedd       Zedd	       Z	edd
       Z
ddZedd       Zedd       Zd ZddZddZddZddZy)r   Nr   firstg    .Ar   max_xc                6   t        | j                  |j                  j                        | _        | j                  *|| _        || j                  _        || j                  _        y| j                  }|j                  }||_        ||_        ||_        ||_        y)zAdd a polygon vertex node.N)maxr   r   rf   r   r   r   )r!   noder   lasts       r#   addzGHPolygon.add   ss     TXXZZ0
::DJ"DJJO"DJJOJJE::DEJDIDIDIr&   c                R    t         j                  t        j                  |             S z3Build a new GHPolygon from an iterable of vertices.)r   r   r
   rI   )r[   s    r#   buildzGHPolygon.build0  s     ""499X#677r&   c                \    t               }| D ]  }|j                  t        |              |S r   )r   r   r   )r[   r"   r   s      r#   r   zGHPolygon.from_vec25  s/     + 	"AKKa!	"r&   c                    |}||k7  rD|j                   | j                   k  r+|j                  }||k7  r|j                   | j                   k  r+|| _        |j                  }|| _        | |_        | |_        y)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   )vertexr.   r/   currr   s        r#   r   zGHPolygon.insert=  sg     ckdjj6<<799D ckdjj6<<7 yy		r&   c              #     K   | j                   J | j                   }	 | |j                  }|| j                   u ry  wr   )r   r   )r!   ss     r#   __iter__zGHPolygon.__iter__R  sC     zz%%%JJGADJJ	 s   <>c                L    | D ]  }|j                   s|j                  r|c S  y r   r   r   r!   r   s     r#   first_intersectzGHPolygon.first_intersect[  s(     	A{{199	 r&   c                    | D cg c]  }|j                    }}|d   j                  |d         s|j                  |d          |S c c}w )Nr   rC   )r   rG   rH   )r!   r   pointss      r#   r  zGHPolygon.pointsb  sI    !%&A!%%&&ay  ,MM&)$ 's   Ac                H    | D ]  }|j                   s|j                  r y y)NTFr  r  s     r#   unprocessedzGHPolygon.unprocessedi  s&     	A{{199	 r&   c                (    | j                  |dd      S )NFr]   r!   r]   s     r#   unionzGHPolygon.uniono  s    yyue,,r&   c                (    | j                  |dd      S r   r  r  s     r#   r   zGHPolygon.intersectionr  s    yytT**r&   c                (    | j                  |dd      S )NFTr  r  s     r#   
differencezGHPolygon.differenceu  s    yyud++r&   c           
        | D ]  }|j                   r|D ]  }|j                   rt        |j                  t        |j                        j                  |j                  t        |j                        j                        \  }}}|st        ||dd      }	t        ||dd      }
|
|	_        |	|
_        | j                  |	|t        |j                               |j                  |
|t        |j                                 |t        | j                  j                  |      z  }| D ]  }|j                   s||_
        | } |t        |j                  j                  |       z  }|D ]  }|j                   s||_
        | } g }| j                         r| j                  }|j                  g}	 |j                          |j                  r6	 |j                  }|j                  |j                         |j                   rn75	 |j                  }|j                  |j                         |j                   rn5|j                  }|j                   rn|j                  |       | j                         r|S )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   r
  r  r   rH   r   r   )r!   r]   s_entryc_entrysubject_vertexclipper_vertexrl   usucsubject_nodeclipper_nodeclipped_polygonscurrentru   s                 r#   r]   zGHPolygon.clipy  s^   : # 	N!++&* N)33%6*..,^-@-@AEE*..,^-@-@AEE	&
B :$',Rt5'Q',Rt5'Q0<-0<-(*,^-@-@A
 (*,^-@-@A)	: 	$TZZ^^T::" 	&N'''.$%+	&
 	$TZZ^^T::" 	&N'''.$%+	& .0 !11G#*;;-G##%=="),,w{{3",,!	  "),,w{{3",,!	  "**??# $ ##G,+  ,  r&   )r   r   )r[   Iterable[UVec]r7   r   )r[   r6   r7   r   )r   r   r.   r   r/   r   )r7   zIterator[_Node])r7   zOptional[_Node])r7   
list[Vec2])r]   r   r7   list[list[Vec2]])r=   r>   r?   r   __annotations__r   r   staticmethodr   r   r   r  propertyr  r  r
  r  r   r  r]   r   r&   r#   r   r     s    E5E5  8 8    (    -+,^ r&   r   c                T    | }|j                   r|j                  }|j                   r|S )z@Return the next non-intersecting vertex after the one specified.)r   r   )r   cs     r#   r  r    s%    	A
++FF ++Hr&   c                @    t        | |j                  t              dk\  S )z2Returns ``True`` if  `vertex` is inside `polygon`.rD   r   )r   r  r   )r   r"   s     r#   r  r    s     "&'..)LPQQQr&   )Nr   r   c                   |j                   |j                   z
  |j                  | j                  z
  z  |j                  |j                  z
  |j                   | j                   z
  z  z
  }t        |      |k  rt        S |j                  |j                  z
  | j                   |j                   z
  z  |j                   |j                   z
  | j                  |j                  z
  z  z
  |z  }d|z   }d|z
  }||cxk  r
|k  st        S  t        S |j                  | j                  z
  | j                   |j                   z
  z  |j                   | j                   z
  | j                  |j                  z
  z  z
  |z  }	||	cxk  r|k  ren t        S t	        | j                  ||j                  | j                  z
  z  z   | j                   ||j                   | j                   z
  z  z         ||	fS t        S )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/
    rd   g      ?)rg   rf   abs_ERRORr
   )
s1s2c1c2toldenr  lwruprr  s
             r#   r  r    s    44"$$;244"$$;
'244"$$;244"$$;*G
GC
3x#~44"$$;244"$$;
'244"$$;244"$$;*G
G3	NB
)C
)C "NsN 44"$$;244"$$;
'244"$$;244"$$;*G
G3	NB
R~#~ M	 bddRTTk**BDD23E,EF
 	

 Mr&   c                      e Zd ZdZdZdZy)BooleanOperationr  r  r   N)r=   r>   r?   UNION
DIFFERENCEINTERSECTIONr   r&   r#   r5  r5    s    EJ!Lr&   r5  c                8    t        | |t        j                        S )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_hormannr5  r8  p1p2s     r#   r   r     s     2r#3#@#@AAr&   c                8    t        | |t        j                        S )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!

    )r:  r5  r7  r;  s     r#   r   r     s     2r#3#>#>??r&   c                8    t        | |t        j                        S )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!

    )r:  r5  r6  r;  s     r#   r   r   )  s     2r#3#9#9::r&   c                J   t         j                  |       }t         j                  |      }|t        j                  k(  r|j	                  |      S |t        j
                  k(  r|j                  |      S |t        j                  k(  r|j                  |      S t        d|       )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   r5  r6  r  r7  r  r8  r   rX   )r<  r=  oppolygon1polygon2s        r#   r:  r:  3  s      r"Hr"H	###~~h''	**	*""8,,	,,	,$$X..
A"F
GGr&   rB   rA   r      c                  ,    e Zd ZdZdZddZddZd	dZy)
r   a   Cohen-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                @    |\  | _         | _        |\  | _        | _        y r   )rF  rH  rG  rI  )r!   w_minw_maxs      r#   r^   z&CohenSutherlandLineClipping2d.__init__a  s    !&
DJ!&
DJr&   c                    d}|| j                   k  r
|t        z  }n|| j                  kD  r	|t        z  }|| j                  k  r|t
        z  }|S || j                  kD  r	|t        z  }|S )Nr   )rF  LEFTrG  RIGHTrH  BOTTOMrI  TOP)r!   rf   rg   codes       r#   encodez$CohenSutherlandLineClipping2d.encodee  se    tzz>DLD^EMDtzz>FND  ^CKDr&   c                   |\  }}|\  }}| j                  ||      }| j                  ||      }|}	|}
	 ||z  st        ||      t        ||      fS ||z  r
t               S ||kD  r|n|}|t        z  r+|||z
  | j                  |z
  z  ||z
  z  z   }	| j                  }
n|t
        z  r+|||z
  | j                  |z
  z  ||z
  z  z   }	| j                  }
ng|t        z  r+|||z
  | j                  |z
  z  ||z
  z  z   }
| j                  }	n3|t        z  r*|||z
  | j                  |z
  z  ||z
  z  z   }
| j                  }	||k(  r|	}|
}| j                  ||      }n|	}|
}| j                  ||      }8)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

        )rS  r
   rp   rQ  rI  rP  rH  rO  rG  rN  rF  )r!   p0r<  x0y0x1y1code0code1rf   rg   rR  s               r#   r0   z'CohenSutherlandLineClipping2d.clip_lineq  s    BBB#B#5= B|T"b\11u} w
 "EM5uD cz"r'djj2o6"r'BBJJ"r'djj2o6"r'BBJJ"r'djj2o6"r'BBJJ"r'djj2o6"r'BBJJu}B+B+W r&   N)rK  r
   rL  r
   r7   rv   )rf   r   rg   r   r7   int)rU  r
   r<  r
   r7   r6   )r=   r>   r?   r~   	__slots__r^   rS  r0   r   r&   r#   r   r   U  s     5I'
9,r&   r   )r*   r6   rJ   z3Callable[[Vec2, Vec2], Sequence[tuple[Vec2, Vec2]]]rE   r   r7   r8   )r   r!  r   r!  r7   r8   )r"   r!  r.   r
   r/   r
   r7   r<   )r"   r!  r   ztuple[Vec2, Vec2]rE   r   r7   r!  )r   r!  r   r   r7   r!  )r   r!  r   r!  r7   ztuple[int, int])r   r   r7   r   )r   r
   r"   r   r7   r<   )r,  r
   r-  r
   r.  r
   r/  r
   r0  r   r7   z#tuple[Optional[Vec2], float, float])r<  r   r=  r   r7   r"  )r<  r   r=  r   rA  r5  r7   r"  )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   rQ   r   r   r   r   r   r   r   r   r   r   	Exceptionr   r   r  r  r+  r  Enumr5  r   r   r   r:  rN  rO  rP  rQ  r   r   r&   r#   <module>rg     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&   