Ë
    £èhµ‡  ã                  ó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     ú3lib/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Ø—M‘M (Ô+ØØ—‘˜VÔ$Ü˜,Ó'‰Fñ 5ð ñ Ø�‰�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‹~ˆÜˆt‹9�qŠ=Ø�A‰w�‰˜t B™x°·±ˆÔ>Ø—‘”
Üˆt‹9�qŠ=ÜÐPÓQÐQÙÔ2°4Ô8Ø�L‰LŒNØ-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]   ø€ à—J‘J §¡Ñ-°%·'±'¸J¿L¹LÑ2HÑ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]   ø€ à—J‘J §¡Ñ-°%·'±'¸J¿L¹LÑ2HÑ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Ò  X¨a¡[×%8Ñ%8Ø˜‘ d§l¡lð &9ô &ð —‘”à�M‰MŒOØ! "™ˆJÛ$�á˜XÔ&Ù$ ZÔ0Ù)Ô+Ø—N‘N 8Õ,Ù˜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   € ä% e¨T×-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°Ð#;Ó<ˆŒ
Ø—j‘j×'Ñ'ˆØ—J‘J×%Ñ%ˆ	Ü!8àÜ�Y—[‘[ +§-¡-Ó0ØÜ�[—]‘] I§K¡KÓ0ð	ð Ø—L‘Lô	"
ˆÔô ;Ø�J‰J×Ñ˜tŸz™z×0Ñ0ó
ˆÕr&   c                ó8   — | j                   j                  |«      S )rr   )rZ   r$   r    s     r#   r$   zClippingRect2d.clip_polygonË   s   € à×%Ñ%×2Ñ2°7Ó;Ð;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   € à×#Ñ#×-Ñ-¨e°SÓ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   € à�z‰z× Ñ  Ó'Ð'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   € à�z‰z×*Ñ*¨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‹~ˆÜˆt‹9�qŠ=Ø�A‰w�‰˜t B™x°·±ˆÔ>Ø—‘”
Üˆt‹9�qŠ=ÜÐ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:   € à�z‰z× Ñ  Ô'Øä" 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ˆ|ˆØ�z‰z×%Ñ%¤m°DÓ&9Ô:Ü“7ˆNä5°d×6LÑ6LÈdÓSˆÜ0°¸×8NÑ8NÓOÐSTÑTˆÜˆ}Ó Ò"ÙØ�w�Ü“7ˆNä" 3¨×(>Ñ(>ÈÔPÐTUÑUð 	ñ  ¨rÑ!2×!:Ñ!:¸3ÈÐ!:Ô!Pà× Ñ  Ô%Ù =°Ñ#3×#;Ñ#;¸EÈ7Ð#;Ô#Sà× Ñ   EÔ*ô ˆ}Ó Ò! m°AÑ&6×&>Ñ&>Ø˜!Ñ gð '?ô '
ð ×Ñ˜aÔ Üˆ}Ó Ò! m°BÑ&7×&?Ñ&?Ø˜"Ñ wð '@ô '
ð ×ÑÔä˜d×4Ñ4°e¸SÔAð 13ˆHÜ  Ö/‘��1Ø—9‘9˜Q¨�9Ô0Øä*ØŸ™˜q›	 4×#9Ñ#9À7ôð óð
 —O‘O Q¨ FÕ+ð 0ð ˆ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Ö,‰JˆE�3ØŸ™ u¨cÖ2‘��1ÙØ'¨™|�HØ ‘|×+Ñ+¨A°wÐ+Ô?Ø Ÿ™¨Ô*Ø Ø—‘  A Õ'ñ 3ð -ð ˆ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.   øè ø€ ð á!�Aô ' q¨$×*@Ñ*@È'ÔRÐUVÕ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ÒØ˜‰{×"Ñ" 8¨B¡<¸Ð"ÔAØ—‘”Üˆx‹=˜1ÒÜ“7ˆNÜ# HÓ-ˆØ�z‰z×*Ñ*¨;Ô7Ü“7ˆNÜ(¨×)?Ñ)?ÀÓ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 )z¯Returns 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  sP   € à�‰€AÜ" 1 e¨SÓ1€EÛˆÜ& q¨%°Ó5ˆØ�AŠ:˜% 1š*ÙØˆØ‰ð ð r&   c                óÜ  ‡— g }|\  Š}t        | «      }t        |«      D ]µ  }| |dz
     }| |   }t        ||f|d|¬«      }	|	€Œ$|	j                  ||¬«      r,| |dz
     }
t	        |
‰||¬«      }t	        |‰||¬«      }||k(  rCŒc|	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   ø€ ¨B¯K©K¸Ô,>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  ø€ ð ')ÐØ�J€Eˆ3Üˆw‹<€DÜ�t–ˆØ�E˜A‘IÑˆØ�E‰NˆÜ&¨¨1 v¨t¸UÈGÔTˆØˆ:Øð �:‰:�a ˆ:Ô)Ø˜U Q™YÑ'ˆFÜ-¨f°e¸SÈ'ÔRˆHÜ-¨a°¸ÀWÔMˆHØ˜8Ò#Øà�Z‰Z˜ 7ˆZÔ+Ø˜e a™i¨4Ñ/Ñ0ˆFÜ-¨a°¸ÀWÔMˆHÜ-¨f°e¸SÈ'ÔRˆHØ˜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Ó"ˆÜˆt‹9�qŠ=Ø˜‘7—?‘? 4¨¡8°W�?Ô=Ø—‘˜D ™GÔ$Üˆt‹9�qŠ=ÜÐ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 )z�Creates 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Ñ 1¸7ÐÔCØ×ÑÔÜˆ}Ó Ò!Ð!Ð!Ü�l×0Ñ0Ó2Ó3€JØ×ÑÔÜ" =°*Ó=�F€BˆØ˜2˜3Ð€FØ
‡M�M�-  " q¡&Ð)Ô*Ø
‡M�M�*˜R˜S�/Ô"Ø
‡M�M�*˜X˜r A™vÐ&Ô'Ø
‡M�M�&˜‘)ÔØ€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Ð   Ý  sb   € ô �x‰x€HØ"€FÜ˜IÖ&‰ˆˆBÜ 	Ö*‰FˆB�Ø—{‘{ 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Ø�M‰M×%Ñ%Õ'ð "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   € ô ˜Ÿ™ T§X¡X§Z¡ZÓ0ˆŒ
Ø�:‰:ÐØˆDŒJØ"ˆD�J‰JŒOØ"ˆD�J‰J�Oà—J‘JˆEØ—:‘:ˆDØˆEŒJØˆDŒIØˆDŒIØˆD�Ir&   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   € ô ×"Ñ"¤4§9¡9¨XÓ#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Ø�K‰Kœ˜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   € ð ˆØ�cŠk˜dŸj™j¨6¯<©<Ò7Ø—9‘9ˆDð �cŠk˜dŸj™j¨6¯<©<Ó7ð ˆŒØ�y‰yˆØˆŒØˆŒ	Øˆ�	r&   c              #  ó€   K  — | j                   €J ‚| j                   }	 |–— |j                  }|| j                   u ry Œ ­wrº   )rò   rä   )r!   Úss     r#   Ú__iter__zGHPolygon.__iter__R  sC   è ø€ Ø�z‰zÐ%Ð%Ð%Ø�J‰JˆØØŠGØ—‘ˆAØ�D—J‘J‰Øð	 ù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Ø�{‹{ 1§9£9Ø’ð ð 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  sJ   € á!%Ó&¡˜A�!—%“% ˆÐ&Ø�a‰y× Ñ  ¨¡Ô,Ø�M‰M˜& ™)Ô$Øˆùò 's   …Ac                óH   — | D ]  }|j                   sŒ|j                  rŒ y y)NTFr  r  s     r#   ÚunprocessedzGHPolygon.unprocessedi  s!   € ÛˆAØ�{‹{ 1§9£9Ùð ð r&   c                ó(   — | j                  |dd«      S )NF©r]   ©r!   r]   s     r#   ÚunionzGHPolygon.uniono  s   € Ø�y‰y˜˜u eÓ,Ð,r&   c                ó(   — | j                  |dd«      S rì   r  r  s     r#   r¯   zGHPolygon.intersectionr  s   € Ø�y‰y˜˜t TÓ*Ð*r&   c                ó(   — | j                  |dd«      S )NFTr  r  s     r#   Ú
differencezGHPolygon.differenceu  s   € Ø�y‰y˜˜u dÓ+Ð+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n7Œ5	 |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  sJ  € ó: #ˆNØ!×+Ó+Û&*�NØ)×3Ó3Ü%6Ø*×.Ñ.Ü,¨^×-@Ñ-@ÓA×EÑEØ*×.Ñ.Ü,¨^×-@Ñ-@ÓA×EÑEó	&™
˜˜B ð ˜:Ø$Ü',¨R°¸tÈ5Ô'Q˜Ü',¨R°¸tÈ5Ô'Q˜Ø0<˜Ô-Ø0<˜Ô-àŸ™Ø(Ø*Ü,¨^×-@Ñ-@ÓAôð
 Ÿ™Ø(Ø*Ü,¨^×-@Ñ-@ÓAõò) '+ð #ð: 	Ô$ T§Z¡Z§^¡^°TÓ:Ñ:ˆÛ"ˆNØ×'Ó'Ø'.�Ô$Ø%˜+‘ð #ð
 	Ô$ T§Z¡Z§^¡^°TÓ:Ñ:ˆÛ"ˆNØ×'Ó'Ø'.�Ô$Ø%˜+‘ð #ð .0ÐØ×ÑÔ Ø!×1Ñ1ˆGØ#*§;¡; -ˆ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ž   … Ø€Eˆ5ÓØ€Eˆ5Óóð  ò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Ø
�+Š+Ø�F‰Fˆð �+‹+à€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   € ô " &¨'¯.©.Ä)ÔLÐPQÑ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 )zÔReturns 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�  € ð �4‰4�"—$‘$‰;˜2Ÿ4™4 "§$¡$™;Ñ
'¨2¯4©4°"·$±$©;¸2¿4¹4À"Ç$Á$¹;Ñ*GÑ
G€CÜ
ˆ3ƒx�#‚~ÜˆØ�4‰4�"—$‘$‰;˜2Ÿ4™4 "§$¡$™;Ñ
'¨2¯4©4°"·$±$©;¸2¿4¹4À"Ç$Á$¹;Ñ*GÑ
GÈ3Ñ	N€BØ
�‰)€CØ
�‰)€Cð �"ŒN�sŠNÜˆð Üˆà�4‰4�"—$‘$‰;˜2Ÿ4™4 "§$¡$™;Ñ
'¨2¯4©4°"·$±$©;¸2¿4¹4À"Ç$Á$¹;Ñ*GÑ
GÈ3Ñ	N€BØ
ˆR„~�#„~ô €Mô	 �—‘˜˜bŸd™d R§T¡T™kÑ*Ñ*¨B¯D©D°2¸¿¹ÀÇÁ¹Ñ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 )zâReturns 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   € ô ˜2˜rÔ#3×#@Ñ#@ÓAÐAr&   c                ó8   — t        | |t        j                  «      S )zßReturns 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   € ô ˜2˜rÔ#3×#>Ñ#>Ó?Ð?r&   c                ó8   — t        | |t        j                  «      S )zÚReturns 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   € ô ˜2˜rÔ#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   € Ø!&ÑˆŒ
�D”JØ!&ÑˆŒ
�D•Jr&   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   € ØˆØˆt�z‰zŠ>Ø”D‰L‰DØ�—‘Š^Ø”E‰MˆDØˆt�z‰zŠ>Ø”F‰NˆDð ˆð �—‘Š^Ø”C‰KˆDØˆ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)z¼Returns 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�ð
 " EšM‘5¨uˆDð ”cŠzØ˜"˜r™' d§j¡j°2¡oÑ6¸"¸r¹'ÑBÑB�Ø—J‘J‘Øœ’Ø˜"˜r™' d§j¡j°2¡oÑ6¸"¸r¹'ÑBÑB�Ø—J‘J‘Øœ’Ø˜"˜r™' d§j¡j°2¡oÑ6¸"¸r¹'ÑBÑB�Ø—J‘J‘Øœ’Ø˜"˜r™' d§j¡j°2¡oÑ6¸"¸r¹'ÑBÑB�Ø—J‘J�à�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   „ ñð 5€Ió'ó
ô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ðà(óô>"�t—y‘yô "ð	BØð	BØ*ð	Bàó	Bð	@Øð	@Ø*ð	@àó	@ó;ðHØðHØ*ðHØ0@ðHàóHð8 €Ø€Ø	€Ø	€÷U,ò U,r&   