
    hR                    v   S SK Jr  S SKJrJrJr  S SKrS SKrS SK	J
r
JrJrJrJrJrJrJrJrJr  \(       a  S SKJr  S SKJr  / SQrS \R2                  S-  \R2                  \R2                  S	-  /r\R2                  S
-  r " S S5      rSS jrSS jr            SS jrSS jr SS jr!SS jr"SS jr#g)    )annotations)TYPE_CHECKINGIterableAnyN)
Vec3UVecNULLVECX_AXISZ_AXISOCSMatrix44arc_angle_span_raddistance_point_line_3denclosing_angles)
BaseLayoutEllipse)ConstructionEllipseangle_to_paramparam_to_anglerytz_axis_construction      ?g      ?       @c                  X   \ rS rSrSr\\\SS\R                  S4             SS jjr
\\S\SSS4             SS jj5       rS	 r\SS
 j5       r\SS j5       rSS jrSS jrSS jr\S S j5       rS!S jrS"S jrS#S$S jjrS%S jrS"S jrS&S jrS'S(S jjrS)S jrSrg)*r   #   ac  Construction tool for 3D ellipsis.

Args:
    center: 3D center point
    major_axis: major axis as 3D vector
    extrusion: normal vector of ellipse plane
    ratio: ratio of minor axis to major axis
    start_param: start param in radians
    end_param: end param in radians
    ccw: is counter-clockwise flag - swaps start- and end param if ``False``

   r   Tc                4   [        U5      U l        [        U5      U l        U R                  R                  [        5      (       a  [        S5      e[        U5      U l        U R                  R                  [        5      (       a  [        S5      e[        U5      U l        [        U5      U l	        [        U5      U l
        U(       d#  U R                  U R                  sU l	        U l
        [        U R                  U R                  U R                  5      U l        g )Nz!Invalid major axis (null vector).z'Invalid extrusion vector (null vector).)r   center
major_axisiscloser	   
ValueError	extrusionfloatratiostart_param	end_param
minor_axis)selfr   r   r"   r$   r%   r&   ccws           D/var/www/html/env/lib/python3.13/site-packages/ezdxf/math/ellipse.py__init__ConstructionEllipse.__init__1   s     6lz*??""7++@BBi??""7++FHH5\
 -y)/3~~t?O?O,Ddn$T__dnndjjQ    ih  c                v   [        U5      n[        R                  " U5      (       a  [        S[	        U5       35      eSn[        U5      nUR                  U5      nUR                  [        USS5      5      n	[        R                  " U5      n
[        R                  " U5      nU " UU	UUU
U[        U5      5      $ )ad  Returns :class:`ConstructionEllipse` from arc or circle.

Arc and Circle parameters defined in OCS.

Args:
     center: center in OCS
     radius: arc or circle radius
     extrusion: OCS extrusion vector
     start_angle: start angle in degrees
     end_angle: end angle in degrees
     ccw: arc curve goes counter clockwise from start to end if ``True``
zInvalid extrusion:       ?r   )absr	   r    r!   strr   to_wcsr   mathradiansbool)clsr   radiusr"   start_angle	end_angler)   r$   ocsr   r%   r&   s               r*   from_arcConstructionEllipse.from_arcI   s    , V??9%%23y>2BCDD)nF#ZZVQ 23
ll;/LL+	I
 	
r-   c                    U R                  U R                  U R                  U R                  U R                  U R
                  U R                  5      $ N)	__class__r   r   r"   r$   r%   r&   r(   s    r*   __copy__ConstructionEllipse.__copy__t   s?    ~~KKOONNJJNN
 	
r-   c                    [        U R                  U R                  U R                  U R                  U R
                  5      $ )z'Returns start point of ellipse as Vec3.)vertexr%   r   r'   r   r$   r@   s    r*   start_pointConstructionEllipse.start_point~   s6     OOOOKKJJ
 	
r-   c                    [        U R                  U R                  U R                  U R                  U R
                  5      $ )z%Returns end point of ellipse as Vec3.)rD   r&   r   r'   r   r$   r@   s    r*   	end_pointConstructionEllipse.end_point   s4     NNOOOOKKJJ
 	
r-   c                   U R                   S:  a!  U R                  5       nUR                  5         OU nUR                  UR                  UR
                  [        UR                   S5      UR                  UR                  S.$ )zyReturns required DXF attributes to build an ELLIPSE entity.

Entity ELLIPSE has always a ratio in range from 1e-6 to 1.

r   ư>)r   r   r"   r$   r%   r&   )	r$   rA   	swap_axisr   r   r"   maxr%   r&   )r(   es     r*   
dxfattribsConstructionEllipse.dxfattribs   sc     ::>AKKMAhh,,$'==
 	
r-   c              #     #    U R                   nU R                  n[         HO  n[        X1U5      (       d  M  [	        UU R
                  U R                  U R                  U R                  5      v   MQ     g7f)zJYields main axis points of ellipse in the range from start- to end
param.
N)	r%   r&   QUARTER_PARAMSr   rD   r   r'   r   r$   )r(   startendparams       r*   main_axis_points$ConstructionEllipse.main_axis_points   s^        nn#Ec22OOOOKKJJ  $s
   1A5>A5c           	       ^^^ UR                  U R                  5      nU R                  =p4U R                  =pV[	        U R
                  U R                  U R                  5      nUR                  U R
                  U45      u  pUR                  5       R                  U	R                  5       5      n
[        U
5      S:  a0  [        X5      u  pmUR                  U	5      R                  5       nSnOFU	R                  UR                  -  mUR                  U	5      R                  5       n[	        XT5      n	SnU(       Ga  [        R                   " XFSS9(       Gd  UR                  5       mU	R                  5       mXd-
  [        R"                  -  nSUUU4S jjnUR                  [%        UU R
                  UU R                  U R                  5      5      nUR                  [%        UU R
                  UU R                  U R                  5      5      nU" X-
  5      nU" UU-
  5      n[        R                   " U[        R&                  SS9(       d3  Xd-
  [        R"                  -  n[        R                   " UUSS9(       d  XdpdOtUR                  [%        [)        X55      U R
                  UU R                  U R                  5      5      n[%        [)        XF5      UU	UT5      nUR!                  USS9(       d  XdpdTS:  au  [	        XT5      nST-  m[	        XT5      n	[        R                   " US	5      (       a*  [        R                   " U[        R"                  5      (       d  U[*        -  nU[*        -  nU[        R"                  -  nU[        R"                  -  n[        R                   " XF5      (       a  S
n[        R"                  nX l        Xl        Xl        Xl        TU l        X@l        X`l        g)z8Transform ellipse in place by transformation matrix `m`.rK   TF&.>abs_tolc                   > TR                  U 5      T-  nTR                  U 5      n[        R                  " X5      [        R                  -  $ r>   )dotr3   atan2tau)vecdydx	new_ratiox_axisy_axiss      r*   rU   ,ConstructionEllipse.transform.<locals>.param   s:    ZZ_y0ZZ_zz")DHH44r-   r   r/   r           N)r`   z'Vec3'returnr#   )	transformr   r%   r&   r'   r   r"   r$   transform_directions	normalizer]   r0   r   cross	magnituder3   r    r_   rD   pi	mid_paramHALF_PI)r(   m
new_centerold_start_paramr%   old_end_paramr&   old_minor_axisnew_major_axisnew_minor_axisdot_productnew_extrusionadjust_paramsold_param_spanrU   rE   rH   new_param_spanold_chk_pointnew_chk_pointrc   rd   re   s                       @@@r*   ri   ConstructionEllipse.transform   sP   [[-
(,(8(88$(NN2#DOOT^^TZZP)*)?)?__n-*
& %..044^5M5M5OP{d"8N95NI +00@JJLM M '00>3K3KKI*00@JJLM'yQN!Mkd!S!S#--/F#--/F (5AN5 5 ++OO"KKJJK OO"KKJJI   89Ki*45I <<F
 #,"9TXX!E||NNDQ-6 !"!/A&

! !'k5""! %,,]D,I-6q='yQNiI'yQNLLa00T\\)TXX5V5Vw&W$	 "DHH,(	<<//KI ((&
&"r-   c                B    [        U R                  U R                  5      $ )zReturns the counter-clockwise params span from start- to end param,
see also :func:`ezdxf.math.ellipse_param_span` for more information.

)r   r%   r&   r@   s    r*   
param_spanConstructionEllipse.param_span-  s     "$"2"2DNNCCr-   c              #  b   #    [        U R                  U R                  U5       Sh  vN   g N7f)u   Returns `num` params from start- to end param in counter-clockwise
order.

All params are normalized in the range from [0, 2π).

N)
get_paramsr%   r&   )r(   nums     r*   paramsConstructionEllipse.params5  s#      d..DDDs   %/-/c              #  l  #    U R                   nU R                  nU R                  R                  5       nU R                  R                  5       nU R                  R
                  nXc-  nU HD  n[        R                  " U5      U-  U-  n	[        R                  " U5      U-  U-  n
X)-   U
-   v   MF     g7f)u   Yields vertices on ellipse for iterable `params` in WCS.

Args:
    params: param values in the range from [0, 2π) in radians,
        param goes counter-clockwise around the extrusion vector,
        major_axis = local x-axis = 0 rad.

N)	r   r$   r   rk   r'   rm   r3   cossin)r(   r   r   r$   rd   re   radius_xradius_yrU   xys              r*   verticesConstructionEllipse.vertices>  s      

**,**,??,,#E(*V3A(*V3A*q.  s   B2B4c              #  >  ^ ^^	^
^^^^#    SU	U
U UU4S jjmSUUU4S jjmT R                   R                  5       mT R                  R                  5       mT R                   R                  m	T	T R                  -  m
T R
                  U-  nUS:X  a  gT R                  [        R                  -  n[        R                  " T R                  [        R                  5      (       a  [        R                  nOT R                  [        R                  -  n[        R                  " XE5      (       a  gXE:  a  U[        R                  -  nT" U5      nUv   XE:  aF  XC-   n[        R                  " Xu5      (       a  UnT" U5      nT" XhXG5       Sh  vN   UnUnXE:  a  ME  gg N7f)a  Adaptive recursive flattening. The argument `segments` is the
minimum count of approximation segments, if the distance from the center
of the approximation segment to the curve is bigger than `distance` the
segment will be subdivided. Returns a closed polygon for a full ellipse:
start vertex == end vertex.

Args:
    distance: maximum distance from the projected curve point onto the
        segment chord.
    segments: minimum segment count

c                   > [         R                  " U 5      T-  T-  n[         R                  " U 5      T-  T-  nTR                  U-   U-   $ r>   )r3   r   r   r   )pr   r   r   r   r(   rd   re   s      r*   vertex_/ConstructionEllipse.flattening.<locals>.vertex_a  sD    h&/Ah&/A;;?Q&&r-   c              3     >#    X#-   S-  nT	" U5      n[        XPU5      nUT:  a  Uv   g T" XX$5       S h  vN   T" XQXC5       S h  vN   g  N N7f)Nr   )r   )
srN   s_parame_paramm_paramrq   ddistancesubdivr   s
          r*   r   .ConstructionEllipse.flattening.<locals>.subdivf  s]     (C/G A&qQ/A8|!!999!!999 :9s!   3AAAAAArg   N)r   r#   rh   r   )r   r   rN   r   r   r#   r   r#   )r   rk   r'   rm   r$   r   r%   r3   r_   r    r&   )r(   r   segmentsdeltarU   r&   rE   next_end_paramrH   r   r   r   r   rd   re   s   ``       @@@@@@r*   
flatteningConstructionEllipse.flatteningS  sE    	' 	'
	: 	: **,**,??,,djj((*C<  488+<<11I1I<<))!Ien"]N||N66!*/IkeLLL"E#K 
 Ms   E?F	F
FFc              #  |  #    U R                   R                  5       nU R                  R                  5       nU R                  nU R                  n[
        R                  " U5       HR  nXe-  n[        R                  " UR                  U5      U-  UR                  U5      5      [        R                  -  v   MT     g7f)u  Yields ellipse params for all given `vertices`.

The vertex don't have to be exact on the ellipse curve or in the range
from start- to end param or even in the ellipse plane. Param is
calculated from the intersection point of the ray projected on the
ellipse plane from the center of the ellipse through the vertex.

.. warning::

    An input for start- and end vertex at param 0 and 2π return
    unpredictable results because of floating point inaccuracy,
    sometimes 0 and sometimes 2π.

N)r   rk   r'   r$   r   r   generater3   r^   r]   r_   )r(   r   rd   re   r$   r   vs          r*   params_from_vertices(ConstructionEllipse.params_from_vertices  s      **,**,

x(AKA**VZZ]U2FJJqMBTXXMM )s   B:B<c              #  2  #    U R                   nU R                  R                  5       nU R                  R                  5       nU HM  n[        R
                  " U5      * U-  n[        R                  " U5      U-  U-  nXg-   R                  5       v   MO     g7f)u  Yields tangents on ellipse for iterable `params` in WCS as direction
vectors.

Args:
    params: param values in the range from [0, 2π] in radians, param
        goes counter-clockwise around the extrusion vector,
        major_axis = local x-axis = 0 rad.

N)r$   r   rk   r'   r3   r   r   )r(   r   r$   rd   re   rU   r   r   s           r*   tangentsConstructionEllipse.tangents  s{      

**,**,E% 6)A%'&0A5##%% s   BBc                    U R                   U l        SU R                  -  n[        US5      U l        [        U R                  U R                  U R                  5      U l         U R
                  nU R                  n[        R                  " US5      (       a+  [        R                  " U[        R                  5      (       a  gU[        -
  [        R                  -  U l        U[        -
  [        R                  -  U l        g)z.Swap axis and adjust start- and end parameter.r/   rK   r   N)r'   r   r$   rM   r"   r%   r&   r3   r    r_   rp   )r(   r$   r%   r&   s       r*   rL   ConstructionEllipse.swap_axis  s    //djj %
$T__dnndjjQ&&NN	<<Q''DLLDHH,M,M''1TXX=#g-9r-   Nc                    SSK Jn  [        U=(       d    0 5      nUR                  U R	                  5       5        UR
                  " X!R                  S9nUR                  U5        U$ )zAdd ellipse as DXF :class:`~ezdxf.entities.Ellipse` entity to a
layout.

Args:
    layout: destination layout as :class:`~ezdxf.layouts.BaseLayout`
        object
    dxfattribs: additional DXF attributes for the ELLIPSE entity

r   r   )rO   doc)ezdxf.entitiesr   dictupdaterO   newr   
add_entity)r(   layoutrO   r   rN   s        r*   add_to_layout!ConstructionEllipse.add_to_layout  sP     	+**+
$//+,KK:::>!r-   c                   [        U R                  5      nU R                  UR                  U R                  5      UR                  U R
                  5      R                  SS9U R                  U R                  U R                  S9$ )zaReturns ellipse parameters as OCS representation.

OCS elevation is stored in :attr:`center.z`.

rg   )z)r   r   r$   r%   r&   )
r   r"   r?   from_wcsr   r   replacer$   r%   r&   )r(   r:   s     r*   to_ocsConstructionEllipse.to_ocs  sm     $..!~~<<,||DOO4<<s<C**((nn  
 	
r-   )r   r&   r"   r   r'   r$   r%   )r   r   r   r   r"   r   r$   r#   r%   r#   r&   r#   r)   r5   )r   r   r7   r#   r"   r   r8   r#   r9   r#   r)   r5   rh   r   )rh   r   )rh   zdict[str, Any])rh   Iterable[Vec3])rq   r   rh   None)rh   r#   )r   intrh   Iterable[float])r   r   rh   r   )   )r   r#   r   r   rh   r   )r   zIterable[UVec]rh   r   )rh   r   r>   )r   r   rh   r   )rh   r   )__name__
__module____qualname____firstlineno____doc__r	   r
   r   r3   r_   r+   classmethodr;   rA   propertyrE   rH   rO   rV   ri   r   r   r   r   r   r   rL   r   r   __static_attributes__ r-   r*   r   r   #   s_    ! 88RR R 	R
 R R R R0   (
(
 (
 	(

 (
 (
 (
 
(
 (
T
 
 
 
 

( s#j D DE!*:$xN.&&:$
r-   r   c                @    X:  a  U[         R                  -  nX-   S-  $ )Nr   )r3   r_   )rS   rT   s     r*   ro   ro     s!    
{txxK3r-   c                \    UR                  U 5      R                  U R                  U-  5      $ r>   )rl   rk   rm   )r   r"   r$   s      r*   r'   r'     s'    ??:&001E1E1MNNr-   c                    UR                  5       nUR                  5       nUR                  nXt-  n[        R                  " U 5      U-  U-  n	[        R                  " U 5      U-  U-  n
X9-   U
-   $ r>   )rk   rm   r3   r   r   )rU   r   r'   r   r$   rd   re   r   r   r   r   s              r*   rD   rD     sm     !!#F!!#F##HH("V+A("V+A:>r-   c              #     #    US:  a  [        S5      eX::  a  U[        R                  -  n[        R                  " XU5       H  nU[        R                  -  v   M     g7f)u   Returns `num` params from start- to end param in counter-clockwise order.

All params are normalized in the range from [0, 2π).

   znum >= 2N)r!   r3   r_   nplinspace)rS   rT   r   rU   s       r*   r   r     sO      Qw$$
|txxU-dhh .s   AA c                    [         R                  " [         R                  " U5      U -  [         R                  " U5      5      [         R                  -  $ )u+  Returns ellipse parameter for argument `angle`.

Args:
    ratio: minor axis to major axis ratio as stored in the ELLIPSE entity
        (always <= 1).
    angle: angle between major axis and line from center to point on the
        ellipse

Returns:
    the ellipse parameter in the range [0, 2π)
)r3   r^   r   r   r_   )r$   angles     r*   r   r     s3     ::dhhuo-txx?$((JJr-   c                    [         R                  " [         R                  " U5      U -  [         R                  " U5      5      $ )u6  Returns circle angle from ellipse parameter for argument `angle`.

Args:
    ratio: minor axis to major axis ratio as stored in the ELLIPSE entity
        (always <= 1).
    param: ellipse parameter between major axis and point on the ellipse
        curve

Returns:
    the circle angle in the range [0, 2π)
)r3   r^   r   r   )r$   rU   s     r*   r   r     s*     ::dhhuo-txx??r-   c                T   [        U 5      n[        R                  " U R                  SSS9(       a>  [        R                  " UR                  SSS9(       a  [        U5      R	                  SS9nO;U R                  U5      nUR                  U5      R                  UR                  5      nUR                  U5      nUR                  nX#-
  R                  U5      nXW-
  nXW-   n	UR                  [        5      (       d  U	R                  [        5      (       a  [        S5      eX-
  R                  n
X-
  R                  n[        R                  " U
S5      (       d  [        R                  " US5      (       a  [        S5      eX-  nU	R                  U
5      nUR                  U5      nXU4$ )u  The Rytz’s axis construction is a basic method of descriptive Geometry
to find the axes, the semi-major axis and semi-minor axis, starting from two
conjugated half-diameters.

Source: `Wikipedia <https://en.m.wikipedia.org/wiki/Rytz%27s_construction>`_

Given conjugated diameter `d1` is the vector from center C to point P and
the given conjugated diameter `d2` is the vector from center C to point Q.
Center of ellipse is always ``(0, 0, 0)``. This algorithm works for
2D/3D vectors.

Args:
    d1: conjugated semi-major axis as :class:`Vec3`
    d2: conjugated semi-minor axis as :class:`Vec3`

Returns:
     Tuple of (major axis, minor axis, ratio)

r   rY   rZ   F)r)   z.Conjugated axis required, invalid source data.rg   )r   r3   r    r   
orthogonalrl   rk   rm   lerpr	   ArithmeticError)d1d2QP1r"   Dr7   radius_vectorABmajor_axis_lengthminor_axis_lengthr$   r   r'   s                  r*   r   r   ,  sR   ( 	RA||BDD!T*t||BDD!T/R"X  U +HHRL	__R **2<<8

A[[FV&&v.M	A	AyyQYYw//NOO))))||%s++t||<Ms/S/SNOO1E./J./J5((r-   )rS   r#   rT   r#   rh   r#   )r   r   r"   r   r$   r#   rh   r   )rU   r#   r   r   r'   r   r   r   r$   r#   rh   r   )rS   r#   rT   r#   r   r   rh   r   )r$   r#   r   r#   rh   r#   )r$   r#   rU   r#   rh   r#   )r   r   r   r   rh   ztuple[Vec3, Vec3, float])$
__future__r   typingr   r   r   numpyr   r3   
ezdxf.mathr   r   r	   r
   r   r   r   r   r   r   ezdxf.layoutsr   r   r   __all__rn   rR   rp   r   ro   r'   rD   r   r   r   r   r   r-   r*   <module>r      s    # / /     (& TWWs]DGGTWWs];
''C-C
 C
LO		"	04	>B	KP			K@+)r-   