Ë
    £èh½0  ã                  óê   — d dl mZ d dlmZmZmZmZ d dlZddlm	Z	m
Z
 erd dlmZ dZdZd	Zdd
„Zdef	 	 	 	 	 dd„Zdd„Zef	 	 	 	 	 dd„Zdd„Zdd„Zef	 	 	 	 	 dd„ZdZdZdZdZdZdZd d„Zd!d"d„Zy)#é    )Úannotations)ÚIterableÚSequenceÚOptionalÚTYPE_CHECKINGNé   )ÚVec2ÚVec3)ÚUVecg»½×Ùß|Û=gVçž¯Ò<g‚vIhÂ%<=c           	     óø   — t        j                  | «      } t        | «      dk  rt        d«      ‚| d   j	                  | d   «      s| j                  | d   «       t        d„ t        | | dd «      D «       «      dkD  S )	zõReturns ``True`` if the given 2D `vertices` have clockwise orientation.
    Ignores the z-axis of all vertices.

    Args:
        vertices: iterable of :class:`Vec2` compatible objects

    Raises:
        ValueError: less than 3 vertices

    é   zAt least 3 vertices required.r   éÿÿÿÿc              3  óˆ   K  — | ]:  \  }}|j                   |j                   z
  |j                  |j                  z   z  –— Œ< y ­w)N)ÚxÚy)Ú.0Úp1Úp2s      ú5lib/python3.12/site-packages/ezdxf/math/_construct.pyÚ	<genexpr>z,has_clockwise_orientation.<locals>.<genexpr>(   s9   è ø€ ð 
á5‘��Bð �T‰T�B—D‘D‰[˜RŸT™T B§D¡D™[Õ)Ù5ùs   ‚A Ar   Nç        )r	   ÚlistÚlenÚ
ValueErrorÚiscloseÚappendÚsumÚzip)Úverticess    r   Úhas_clockwise_orientationr       s…   € ô �y‰y˜Ó"€HÜ
ˆ8ƒ}�qÒÜÐ8Ó9Ð9ð �A‰;×Ñ˜x¨™|Ô,Ø�‰˜ ™Ô$ô 	ñ 
ä˜h¨°°¨Ô5ó
ó 	
ð ñ		ðó    Tc                ó&  — | \  }}|\  }}|j                   }|j                  }	|j                   }
|j                  }|j                   }|j                  }|j                   }|j                  }||z
  |
|z
  z  ||z
  ||	z
  z  z
  }t        j                  |«      |k  ry||z
  |	|z
  z  ||z
  ||z
  z  z
  |z  }t	        |||
|z
  z  z   |	|||	z
  z  z   «      }|r|S d}d}||cxk  r|k  r,n y|
|z
  |	|z
  z  ||	z
  ||z
  z  z
  |z  }||cxk  r|k  r|S  yy)a9  
    Compute the intersection of two lines in the xy-plane.

    Args:
        line1: start- and end point of first line to test
            e.g. ((x1, y1), (x2, y2)).
        line2: start- and end point of second line to test
            e.g. ((x3, y3), (x4, y4)).
        virtual: ``True`` returns any intersection point, ``False`` returns
            only real intersection points.
        abs_tol: tolerance for intersection test.

    Returns:
        ``None`` if there is no intersection point (parallel lines) or
        intersection point as :class:`Vec2`

    Nr   ç      ð?)r   r   ÚmathÚfabsr	   )Úline1Úline2ÚvirtualÚabs_tolÚs1Ús2Úc1Úc2Ús1xÚs1yÚs2xÚs2yÚc1xÚc1yÚc2xÚc2yÚdenÚusÚintersection_pointÚlwrÚuprÚucs                         r   Úintersection_line_line_2dr<   0   sT  € ð2 �F€BˆØ�F€BˆØ
�$‰$€CØ
�$‰$€CØ
�$‰$€CØ
�$‰$€CØ
�$‰$€CØ
�$‰$€CØ
�$‰$€CØ
�$‰$€Cà�‰9˜˜s™Ñ
# s¨S¡y°S¸3±YÑ&?Ñ
?€CÜ‡y�y�ƒ~˜Ò Øà�‰9˜˜s™Ñ
# s¨S¡y°S¸3±YÑ&?Ñ
?À3Ñ	F€BÜ˜c B¨#°©)Ñ$4Ñ4°c¸BÀ#ÈÁ)Ñ<LÑ6LÓMÐÙØ!Ð!ð
 €CØ
€CØ
ˆbÔ�CÔð ð �S‰y˜S 3™YÑ'¨3°©9¸¸s¹Ñ*CÑCÀsÑJˆØ�"Ô˜ÒØ%Ð%ð ár!   c                ó�   — | \  }}}|\  }}}|\  }	}
}||z  |z  ||z  |	z  z   ||z  |
z  z   ||z  |	z  z
  ||z  |
z  z
  ||z  |z  z
  S )zReturns determinant.© )Úv1Úv2Úv3Úe11Úe12Úe13Úe21Úe22Úe23Úe31Úe32Úe33s               r   Ú_determinantrK   i   s‹   € à�M€CˆˆcØ�M€CˆˆcØ�M€Cˆˆcð 	ˆc‰	�C‰Ø
�‰)�c‰/ñ	à
�‰)�c‰/ñ	ð �‰)�c‰/ñ	ð �‰)�c‰/ñ		ð
 �‰)�c‰/ñ	ðr!   c                óX  — | \  }}||z
  j                  «       }|\  }}||z
  j                  «       }|j                  |«      }	|	j                  }
|
|k  r
t        «       S ||z
  }t	        |||	«      }t	        |||	«      }||||
z  z  z   }||||
z  z  z   }|j                  ||¬«      r|fS ||fS )a¸  
    Calculate intersection of two 3D rays, returns a 0-tuple for parallel rays,
    a 1-tuple for intersecting rays and a 2-tuple for not intersecting and not
    parallel rays with points of the closest approach on each ray.

    Args:
        ray1: first ray as tuple of two points as :class:`Vec3` objects
        ray2: second ray as tuple of two points as :class:`Vec3` objects
        abs_tol: absolute tolerance for comparisons

    ©r)   )Ú	normalizeÚcrossÚmagnitude_squareÚtuplerK   r   )Úray1Úray2r)   Úo1r   Úd1Úo2r   Úd2Úd1xd2ÚdenominatorÚo2_o1Údet1Údet2s                 r   Úintersection_ray_ray_3dr]   y   sÐ   € ð �F€BˆØ
ˆr‰'×	Ñ	Ó	€BØ�F€BˆØ
ˆr‰'×	Ñ	Ó	€BØ�H‰H�R‹L€EØ×(Ñ(€KØ�gÒä‹wˆà�R‘ˆÜ˜E 2 uÓ-ˆÜ˜E 2 uÓ-ˆØ�"˜˜{Ñ*Ñ+Ñ+ˆØ�"˜˜{Ñ*Ñ+Ñ+ˆØ�:‰:�b 'ˆ:Ô*à�5ˆLð �r�6ˆMr!   c                óæ   — t        j                  | |t        ¬«      ry| dz  } t        j                  | |dz  t        ¬«      ryt        j                  |dt        ¬«      s|dz  }|| k  r|dz  }|| z
  S )uõ  Returns the counter-clockwise angle span from `start` to `end` in degrees.

    Returns the angle span in the range of [0, 360], 360 is a full circle.
    Full circle handling is a special case, because normalization of angles
    which describe a full circle would return 0 if treated as regular angles.
    e.g. (0, 360) â†’ 360, (0, -360) â†’ 360, (180, -180) â†’ 360.
    Input angles with the same value always return 0 by definition: (0, 0) â†’ 0,
    (-180, -180) â†’ 0, (360, 360) â†’ 0.

    rM   r   g     €v@)r$   r   ÚDEG_ABS_TOL)ÚstartÚends     r   Úarc_angle_span_degrb       sn   € ô ‡|�|�E˜3¬Õ4Øð 
ˆU�N€EÜ‡|�|�E˜3 ™;´Õ<Øô �<‰<˜˜U¬KÕ8Øˆu‰ˆà
ˆU‚{Øˆu‰ˆØ�‰;Ðr!   c                ó  — t         j                  }t        j                  | |t        ¬«      ry| |z  } t        j                  | ||z  t        ¬«      r|S t        j                  ||t        ¬«      s||z  }|| k  r||z  }|| z
  S )uñ  Returns the counter-clockwise angle span from `start` to `end` in radians.

    Returns the angle span in the range of [0, 2Ï€], 2Ï€ is a full circle.
    Full circle handling is a special case, because normalization of angles
    which describe a full circle would return 0 if treated as regular angles.
    e.g. (0, 2Ï€) â†’ 2Ï€, (0, -2Ï€) â†’ 2Ï€, (Ï€, -Ï€) â†’ 2Ï€.
    Input angles with the same value always return 0 by definition: (0, 0) â†’ 0,
    (-Ï€, -Ï€) â†’ 0, (2Ï€, 2Ï€) â†’ 0.

    rM   r   )r$   Útaur   ÚRAD_ABS_TOL)r`   ra   rd   s      r   Úarc_angle_span_radrf   ¾   sy   € ô �(‰(€Cä‡|�|�E˜3¬Õ4Øð 
ˆS�L€EÜ‡|�|�E˜3 ™9¬kÕ:Øˆ
ô �<‰<˜˜S¬+Õ6Øˆs‰
ˆà
ˆU‚{Øˆs‰
ˆØ�‰;Ðr!   c                ó:  — t        |t        «      sJ ‚t        |«      dk  ry|d   j                  |d   «      r|dd }t        |«      dk  ry| j                  }| j
                  }d}|d   \  }}|D ]¥  \  }}	||k  r||fn||f\  }
}|
|cxk  r|k  rLn nI|	|k  r|	|fn||	f\  }}||cxk  r|k  r.n n+t        |	|z
  |z  ||z
  |z  z
  ||z  |	|z  z
  z   «      |k  r y||cxk  r|	k  sn |	|cxk  r|k  rn n|||z
  ||z
  z  |	|z
  z  |z   k  r| }|}|	}Œ§ |ryy)a  
    Test if `point` is inside `polygon`.  Returns +1 for inside, 0 for on the 
    boundary and  -1 for outside.

    Supports convex and concave polygons with clockwise or counter-clockwise oriented
    polygon vertices.  Does not raise an exception for degenerated polygons.


    Args:
        point: 2D point to test as :class:`Vec2`
        polygon: list of 2D points as :class:`Vec2`
        abs_tol: tolerance for distance check

    Returns:
        +1 for inside, 0 for on the boundary, -1 for outside

    r   r   r   NFr   )Ú
isinstancer   r   r   r   r   Úabs)ÚpointÚpolygonr)   r   r   ÚinsideÚx1Úy1Úx2Úy2ÚaÚbÚcÚds                 r   Úis_point_in_polygon_2dru   Ý   sa  € ô. �gœtÔ$Ð$Ð$Ü
ˆ7ƒ|�aÒØàˆq�z×Ñ˜' "™+Ô&Ø˜#˜2�,ˆÜ
ˆ7ƒ|�aÒØØ�‰€AØ�‰€AØ€FØ�R‰[�F€BˆÛ‰ˆˆBð  š7��B‰x¨¨R¨‰ˆˆ1Ø�Œ;�Q�;à! Bšw�B˜‘8¨R°¨H‰DˆAˆqØ�Q”˜!•¤Ø�b‘˜A‘  b¡¨A¡Ñ-°°b±¸2À¹7Ñ1BÑCó"àò"ñ Ø�1Œ\�rŒ\˜r Qœ|¨�|Ø��b‘˜Q ™VÑ$¨¨R©Ñ0°2Ñ5Ò5à�ZˆFØˆØ‰ð! ñ" Øàr!   i™Ra gQÚÄ?XAgšŽ9=ò´?giW‹
¿õ?g-DTû!ù?g-DTû!é?c                ód  — t        j                  | «      } t        j                  |«      }t        }t        }t        j                  |«      |z  }t        j
                  d|z
  d|z   z  |dz  «      }|t        j                  t        j                  t        |dz  z   «      |z  «      z  }|| z  }||fS )aí  Transform GPS (long/lat) to World Mercator.
    
    Transform WGS84 `EPSG:4326 <https://epsg.io/4326>`_ location given as
    latitude and longitude in decimal degrees as used by GPS into World Mercator
    cartesian 2D coordinates in meters `EPSG:3395 <https://epsg.io/3395>`_.

    Args:
        longitude: represents the longitude value (East-West) in decimal degrees 
        latitude: represents the latitude value (North-South) in decimal degrees.
    
    .. versionadded:: 1.3.0

    r#   ç       @)	r$   ÚradiansÚWGS84_SEMI_MAJOR_AXISÚWGS84_ELLIPSOID_ECCENTRICÚsinÚpowÚlogÚtanÚ
CONST_PI_4)Ú	longitudeÚlatituderq   ÚeÚ	e_sin_latrs   r   r   s           r   Úgps_to_world_mercatorr„   &  sš   € ô& —‘˜YÓ'€IÜ�|‰|˜HÓ%€HÜ€AÜ!€AÜ—‘˜Ó" QÑ&€IÜ�‰�#˜	‘/ c¨I¡oÑ6¸¸C¹Ó@€AØ	ŒD�H‰H”T—X‘Xœj¨8°c©>Ñ9Ó:¸QÑ>Ó?Ñ?€AØ	ˆI‰€AØˆaˆ4€Kr!   c                ó¢  — t         }t        }|dz  }t        }t        j                  | |z  z  }|dt        j
                  |«      z  z
  }	 t        j                  |«      |z  }	|dt        j
                  |d|	z
  d|	z   z  |z  z  «      z  z
  }
t        |
|z
  «      |k  rn|
}ŒW| |z  }t        j                  |«      t        j                  |
«      fS )aÊ  Transform World Mercator to GPS.

    Transform WGS84 World Mercator `EPSG:3395 <https://epsg.io/3395>`_
    location given as cartesian 2D coordinates x, y in meters into WGS84 decimal
    degrees as longitude and latitude `EPSG:4326 <https://epsg.io/4326>`_ as
    used by GPS.

    Args:
        x: coordinate WGS84 World Mercator
        y: coordinate WGS84 World Mercator
        tol: accuracy for latitude calculation

    .. versionadded:: 1.3.0

    rw   r#   )	ry   rz   Ú
CONST_PI_2r$   r‚   Úatanr{   ri   Údegrees)r   r   Útolrq   r‚   Úe2Úpi2ÚtÚ	latitude_rƒ   r�   r€   s               r   Úworld_mercator_to_gpsrŽ   D  sÜ   € ô, 	€AÜ!€AØ	
ˆS‰€BÜ
€CÜ�‰�A�2˜‘6Ñ€AØ�cœDŸI™I a›LÑ(Ñ(€IØ
Ü—H‘H˜YÓ'¨!Ñ+ˆ	Ø˜œtŸy™yØ�#˜	‘/ c¨I¡oÑ6¸2Ñ=Ñ=ó 
ñ 
ñ 
ˆô ˆx˜)Ñ#Ó$ sÒ*ØØˆ	ð ð �A‘€IÜ�<‰<˜	Ó"¤D§L¡L°Ó$:Ð:Ð:r!   )r   zIterable[UVec]ÚreturnÚbool)r&   úSequence[Vec2]r'   r‘   r�   zOptional[Vec2])r�   Úfloat)rR   úSequence[Vec3]rS   r“   r�   r“   )r`   r’   ra   r’   r�   r’   )rj   r	   rk   z
list[Vec2]r�   Úint)r€   r’   r�   r’   r�   útuple[float, float])g�íµ ÷Æ°>)r   r’   r   r’   r‰   r’   r�   r•   )Ú
__future__r   Útypingr   r   r   r   r$   Ú_vectorr	   r
   Ú
ezdxf.mathr   Ú	TOLERANCEre   r_   r    r<   rK   r]   rb   rf   ru   ry   ÚWGS84_SEMI_MINOR_AXISrz   ÚCONST_E2r†   r   r„   rŽ   r>   r!   r   Ú<module>r�      sà   ðõ
 #ß >Ó >Û ÷  áÝà€	Ø€Ø€óð> Øð	6Øð6àð6ð
 ó6órð" 9Bð$Ø
ð$Ø .ð$àó$óNó<ð@ /8ð7Øð7Ø$ð7àó7ð|  Ð Ø$Ð Ø/Ð ð €Ø€
Ø€
óõ<&;r!   