
    hS/                       S SK Jr  S SKJrJrJrJr  S SKrSSKJ	r	J
r
  \(       a  S SKJr  SrSrS	rSS
 jrS\4     SS jjrSS jr\4     SS jjrSS jrSS jr\4     SS jjrSrSrSrSrSrSrS S jrS!S"S jjrg)#    )annotations)IterableSequenceOptionalTYPE_CHECKINGN   )Vec2Vec3)UVecg|=gV瞯<gvIh%<=c           	        [         R                  " U 5      n [        U 5      S:  a  [        S5      eU S   R	                  U S   5      (       d  U R                  U S   5        [        S [        X SS 5       5       5      S:  $ )	zReturns ``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     #    U  H:  u  pUR                   UR                   -
  UR                  UR                  -   -  v   M<     g 7f)N)xy).0p1p2s      G/var/www/html/env/lib/python3.13/site-packages/ezdxf/math/_construct.py	<genexpr>,has_clockwise_orientation.<locals>.<genexpr>(   s6      
5 TTBDD[RTTBDD[)5s   AAr   N        )r	   listlen
ValueErroriscloseappendsumzip)verticess    r   has_clockwise_orientationr!      s     yy"H
8}q899 A;x|,,$ 	 
h5
 	
 		    Tc                   U u  pEUu  pgUR                   nUR                  n	UR                   n
UR                  nUR                   nUR                  nUR                   nUR                  nX-
  X-
  -  X-
  X-
  -  -
  n[        R                  " U5      U::  a  gX-
  X-
  -  X-
  X-
  -  -
  U-  n[	        UUX-
  -  -   U	UX-
  -  -   5      nU(       a  U$ SnSnUUs=::  a  U::  a+  O  gX-
  X-
  -  X-
  X-
  -  -
  U-  nUUs=::  a  U::  a   U$   gg)a  
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   s4   2 FBFB
$$C
$$C
$$C
$$C
$$C
$$C
$$C
$$C9
#sySY&?
?Cyy~ 9
#sySY&?
?3	FBcB#)$44cB#)<L6LM!!
 C
C
bC  ySY'39*CCsJ"%% r"   c                ~    U u  p4nUu  pgnUu  pnX7-  U-  XH-  U	-  -   XV-  U
-  -   XW-  U	-  -
  X8-  U
-  -
  XF-  U-  -
  $ )zReturns determinant. )v1v2v3e11e12e13e21e22e23e31e32e33s               r   _determinantrL   i   sy    MCcMCcMCc 		C
)c/	
)c/	 )c/	 )c/		
 )c/	r"   c                B   U u  p4XC-
  R                  5       nUu  pgXv-
  R                  5       nUR                  U5      n	U	R                  n
X::  a
  [        5       $ Xc-
  n[	        XU	5      n[	        XU	5      nX5X-  -  -   nXhX-  -  -   nUR                  XrS9(       a  U4$ XG4$ )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tuplerL   r   )ray1ray2r*   o1r   d1o2r   d2d1xd2denominatoro2_o1det1det2s                 r   intersection_ray_ray_3dr^   y   s     FB
'			BFB
'			BHHRLE((KwEu-Eu-*++*++::b:*5L 6Mr"   c                    [         R                  " X[        S9(       a  gU S-  n [         R                  " XS-  [        S9(       a  g[         R                  " US[        S9(       d  US-  nX:  a  US-  nX-
  $ )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.

rN   r   g     v@)r%   r   DEG_ABS_TOL)startends     r   arc_angle_span_degrc      sf     ||E4 
UNE||E;< <<UK8u
{u;r"   c                   [         R                  n[         R                  " X[        S9(       a  gX-  n [         R                  " XU-  [        S9(       a  U$ [         R                  " X[        S9(       d  X-  nX:  a  X-  nX-
  $ )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.

rN   r   )r%   taur   RAD_ABS_TOL)ra   rb   re   s      r   arc_angle_span_radrg      si     ((C||E4 
LE||E9k:
 <<+6

{
;r"   c                V   [        U[        5      (       d   e[        U5      S:  a  gUS   R                  US   5      (       a  USS n[        U5      S:  a  gU R                  nU R
                  nSnUS   u  pgU H  u  pX:  a  X4OXh4u  pXs=::  a  U::  aG  O  ODX:  a  X4OXy4u  pXs=::  a  U::  a+  O  O([        X-
  U-  X-
  U-  -
  X-  X-  -
  -   5      U::  a    gXts=::  a  U	:  d  O  Xs=::  a  U:  a  O  OX8U-
  XG-
  -  X-
  -  U-   :  a  U(       + nUnU	nM     U(       a  gg)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_2drv      s=   . gt$$$$
7|aqz'"+&&#2,
7|aAAFR[FB 7x;Q;!wB8RHDA!AA-271BC"" \r\r||bQV$0255ZF! " r"   iRa gQ?XAg9=?giW
?g-DT!?g-DT!?c                l   [         R                  " U 5      n [         R                  " U5      n[        n[        n[         R                  " U5      U-  n[         R
                  " SU-
  SU-   -  US-  5      nU[         R                  " [         R                  " [        US-  -   5      U-  5      -  nX -  nXv4$ )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latituderr   e	e_sin_latrt   r   r   s           r   gps_to_world_mercatorr   &  s    & Y'I||H%HA!A"Q&I#	/cIo6C@A	DHHTXXj8c>9:Q>??A	A4Kr"   c                   [         n[        nUS-  n[        n[        R                  U* U-  -  nUS[        R
                  " U5      -  -
  n [        R                  " U5      U-  n	US[        R
                  " USU	-
  SU	-   -  U-  -  5      -  -
  n
[        X-
  5      U:  a  OU
nMZ  X-  n[        R                  " U5      [        R                  " U
5      4$ )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

rx   r$   )	rz   r{   
CONST_PI_2r%   r   atanr|   rj   degrees)r   r   tolrr   r   e2pi2t	latitude_r   r   r   s               r   world_mercator_to_gpsr   D  s    , 	A!A	
SB
CA26AcDIIaL((I
HHY'!+	tyy#	/cIo62== 
 
 
 x#$s*	  I<<	"DLL$:::r"   )r    zIterable[UVec]returnbool)r'   Sequence[Vec2]r(   r   r   zOptional[Vec2])r   float)rS   Sequence[Vec3]rT   r   r   r   )ra   r   rb   r   r   r   )rk   r	   rl   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   	TOLERANCErf   r`   r!   r=   rL   r^   rc   rg   rv   rz   WGS84_SEMI_MINOR_AXISr{   CONST_E2r   r   r   r   r?   r"   r   <module>r      s   
 # > >   	> 	666
 6r" 9B$
$ .$$N<@ /877$77|   $ /  

<&;r"   