
    'jS/                        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d4dZdefd5dZd6dZefd7dZd8dZd8dZefd9d$Zd%Zd&Zd'Zd(Zd)Zd*Zd:d.Zd;d<d3ZdS )=    )annotations)IterableSequenceOptionalTYPE_CHECKINGN   )Vec2Vec3)UVecg|=gV瞯<gvIh%<=verticesIterable[UVec]returnboolc           	     L   t          j        |           } t          |           dk     rt          d          | d                             | d                   s|                     | d                    t          d t          | | dd                   D                       dk    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  Z   K   | ]&\  }}|j         |j         z
  |j        |j        z   z  V  'd S )N)xy).0p1p2s      O/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/math/_construct.py	<genexpr>z,has_clockwise_orientation.<locals>.<genexpr>(   sO       
 
B TBD[RTBD[)
 
 
 
 
 
    r   N        )r	   listlen
ValueErroriscloseappendsumzip)r   s    r   has_clockwise_orientationr$      s     y""H
8}}q8999 A;x|,, %$$$ 	 
 
h55
 
 
 	
 	
 		r   Tline1Sequence[Vec2]line2Optional[Vec2]c                   | \  }}|\  }}|j         }|j        }	|j         }
|j        }|j         }|j        }|j         }|j        }||z
  |
|z
  z  ||z
  ||	z
  z  z
  }t          j        |          |k    rdS ||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 n,|
|z
  |	|z
  z  ||	z
  ||z
  z  z
  |z  }||cxk    r|k    rn n|S dS )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	   )r%   r'   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_2drA   0   sq   2 FBFB
$C
$C
$C
$C
$C
$C
$C
$C9s
#sSyS3Y&?
?Cy~~  t9s
#sSyS3Y&?
?3	FBcB#)$44cB#)<L6LMM "!!
 C
C
bCSyS3Y'39s*CCsJ"%%4r   floatc                    | \  }}}|\  }}}|\  }	}
}||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   _determinantrQ   i   s    MCcMCcMCc 	c	C
)c/	
)c/	 )c/	 )c/		
 )c/	r   ray1Sequence[Vec3]ray2c                   | \  }}||z
                                   }|\  }}||z
                                   }|                    |          }	|	j        }
|
|k    rt                      S ||z
  }t	          |||	          }t	          |||	          }||||
z  z  z   }||||
z  z  z   }|                    ||          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tuplerQ   r    )rR   rT   r.   o1r   d1o2r   d2d1xd2denominatoro2_o1det1det2s                 r   intersection_ray_ray_3drd   y   s     FB
r'				BFB
r'				BHHRLLE(KgwwRE2u--E2u--"{*++"{*++::b':** 	5L r6Mr   startendc                    t          j        | |t                    rdS | dz  } t          j        | |dz  t                    rdS 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.

    rV   r   g     v@)r+   r    DEG_ABS_TOL)re   rf   s     r   arc_angle_span_degri      s     |E3444 s 
UNE|E3;<<< u <UK888 u
U{{u;r   c                   t           j        }t          j        | |t                    rdS | |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.

    rV   r   )r+   taur    RAD_ABS_TOL)re   rf   rk   s      r   arc_angle_span_radrm      s     (C|E3444 s 
SLE|E39k::: 
 <S+666 s

U{{s
;r   pointr	   polygon
list[Vec2]intc                   t          |t                    sJ t          |          dk     rdS |d                             |d                   r
|dd         }t          |          dk     rdS | j        }| j        }d}|d         \  }}|D ]\  }}	||k     r||fn||f\  }
}|
|cxk    r|k    rUn nR|	|k     r|	|fn||	f\  }}||cxk    r|k    r4n n1t          |	|z
  |z  ||z
  |z  z
  ||z  |	|z  z
  z             |k    r dS ||cxk    r|	k     sn |	|cxk    r|k     rn n|||z
  ||z
  z  |	|z
  z  |z   k     r| }|}|	}|rdS dS )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)rn   ro   r.   r   r   insidex1y1x2y2abcds                 r   is_point_in_polygon_2dr~      s   . gt$$$$$
7||arqz'"+&& #2#,
7||arAAFR[FB  B 77BxxR1;;;;Q;;;;;!BwwB88RHDAqQ!bAbA-b271BC" "" " qq1\\\\r\\\\rQ|||||||||bQV$R02555ZF qrr   iRa gQ?XAg9=?giW
?g-DT!?g-DT!?	longitudelatitudetuple[float, float]c                ^   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)r   r   rz   e	e_sin_latr|   r   r   s           r   gps_to_world_mercatorr   &  s    & Y''I|H%%HA!A""Q&I#	/cIo6C@@A	DHTXj8c>9::Q>???A	IAa4Kr   ư>r   r   tolc                   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|
}Z| |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

    r   Tr*   )	r   r   
CONST_PI_2r+   r   atanr   rt   degrees)r   r   r   rz   r   e2pi2t	latitude_r   r   r   s               r   world_mercator_to_gpsr   D  s    , 	A!A	
SB
CA26AcDIaLL((IHY''!+	ty#	/cIo62== 
  
 
 
 x)#$$s**	 AI<	""DL$:$:::r   )r   r   r   r   )r%   r&   r'   r&   r   r(   )r   rB   )rR   rS   rT   rS   r   rS   )re   rB   rf   rB   r   rB   )rn   r	   ro   rp   r   rq   )r   rB   r   rB   r   r   )r   )r   rB   r   rB   r   rB   r   r   )
__future__r   typingr   r   r   r   r+   _vectorr	   r
   
ezdxf.mathr   	TOLERANCErl   rh   r$   rA   rQ   rd   ri   rm   r~   r   WGS84_SEMI_MINOR_AXISr   CONST_E2r   r   r   r   rD   r   r   <module>r      s  
 # " " " " " > > > > > > > > > > > >            	   > 	6 6 6 6 6r   " 9B$ $ $ $ $N   <   @ /87 7 7 7 7|   $ /  

   <&; &; &; &; &; &; &;r   