
    h-                    Z   % S SK Jr  S SKJrJrJrJrJrJr  S SK	r	SSK
JrJr  SSKJr  SSKJr  \(       a  S SKJr  S S	KJr  / S
Qr\" S\\5      r " S S\\   5      r     S           SS jjr\	R2                  S-  rS\S'    S     SS jjrSrSr\r S       SS jjr g)    )annotations)TYPE_CHECKINGIterableIteratorSequenceTypeVarGenericN   )Vec3Vec2)Matrix44)arc_angle_span_deg)UVec)ConstructionEllipse)Bezier4Pcubic_bezier_arc_parameterscubic_bezier_from_arccubic_bezier_from_ellipseTc                      \ rS rSrSrSrSS jr\SS j5       rSS j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S jjrSS jrSS jrSrg)r   !   u  Implements an optimized cubic `Bézier curve`_ for exact 4 control points.

A `Bézier curve`_ is a parametric curve, parameter `t` goes from 0 to 1,
where 0 is the first control point and 1 is the fourth control point.

The class supports points of type :class:`Vec2` and :class:`Vec3` as input, the
class instances are immutable.

Args:
    defpoints: sequence of definition points as :class:`Vec2` or
        :class:`Vec3` compatible objects.

_control_points_offsetc                   ^ [        U5      S:w  a  [        S5      eUS   R                  nUR                  S;  a  [	        SUR                   35      eUS   mTU l        [        U4S jU 5       5      U l        g )N   zFour control points required.r   )r   r   zinvalid point type: c              3  ,   >#    U  H	  oT-
  v   M     g 7fN ).0poffsets     F/var/www/html/env/lib/python3.13/site-packages/ezdxf/math/_bezier4p.py	<genexpr>$Bezier4P.__init__.<locals>.<genexpr>=   s     3R	1J	s   )len
ValueError	__class____name__	TypeErrorr   tupler   )self	defpoints
point_typer"   s      @r#   __init__Bezier4P.__init__2   sx    y>Q<==q\++
""&662:3F3F2GHII aL .33R	3R.R    c                P    U R                   u  pp4U R                  nXRU-   X5-   XE-   4$ )zBControl points as tuple of :class:`Vec3` or :class:`Vec2` objects.r   )r,   p0p1p2p3r"   s         r#   control_pointsBezier4P.control_points?   s1     --F{BK<<r1   c                X    SUs=::  a  S::  d  O  [        S5      eU R                  U5      $ )u   Returns direction vector of tangent for location `t` at the
Bèzier-curve.

Args:
    t: curve position in the range ``[0, 1]``

r         ?t not in range [0 to 1])r'   _get_curve_tangentr,   ts     r#   tangentBezier4P.tangentG   s,     Q#677&&q))r1   c                X    SUs=::  a  S::  d  O  [        S5      eU R                  U5      $ )uk   Returns point for location `t` at the Bèzier-curve.

Args:
    t: curve position in the range ``[0, 1]``

r   r:   r;   )r'   _get_curve_pointr=   s     r#   pointBezier4P.pointS   s,     Q#677$$Q''r1   c              #     #    US:  a  [        U5      eSU-  nU R                  nUS   v   [        SU5       H  nU R                  X$-  5      v   M     US   v   g7f)u   Approximate `Bézier curve`_ by vertices, yields `segments` + 1
vertices as ``(x, y[, z])`` tuples.

Args:
    segments: count of segments for approximation

r
   r:   r      N)r'   r7   rangerB   )r,   segmentsdelta_tcpsegments        r#   approximateBezier4P.approximate^   sd      a<X&&.  eQ)G''(9:: *es   AAc              #    #    / nSU-  nSnU R                   nUS   nUv   US:  a  XT-   n[        R                  " US5      (       a  US   n	SnOU R                  U5      n	 XX-   S-  n
U R                  U
5      nUR	                  U	5      nUR                  U5      nX:  a#  U	v   UnU	nU(       a  UR                  5       u  pOOUR                  X45        U
nUn	Mz  US:  a  M  gg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.

Args:
    distance: maximum distance from the center of the cubic (C3)
        curve to the center of the linear (C1) curve between two
        approximation points to determine if a segment should be
        subdivided.
    segments: minimum segment count

r:           r   rF   g      ?N)r7   mathiscloserB   lerpdistancepopappend)r,   rS   rH   stackdtt0rJ   start_pointt1	end_pointmid_t	mid_point	chk_pointds                 r#   
flatteningBezier4P.flatteningo   s      (*(N  A 3hB||B$$qE	 11"5	 "3#44U;	*//	:	&&y1<#OB"+K(-		ILL"1B )I#  3hs   CC%#C%c                    U R                   u  p#pEX-  nSU-
  nSU-  U-  U-  nSU-  U-  n	Xa-  n
X8-  XI-  -   XZ-  -   U R                  -   $ )Nr:         @r   )r,   r>   _r4   r5   r6   t2
_1_minus_tbcr_   s              r#   rB   Bezier4P._get_curve_point   sk     ,,rU1W
*z)A-*r!Fv'$,,66r1   c                    U R                   u  p#pEX-  nSSSU-  -
  SU-  -   -  nSU-  SSU-  -
  -  nSU-  n	X7-  XH-  -   XY-  -   $ )Nrc   r:         @       @)r   )
r,   r>   rd   r4   r5   r6   re   rg   rh   r_   s
             r#   r<   Bezier4P._get_curve_tangent   si     ,,rU3q=38+,!GsS1W}%"Hv''r1   c                n    SnSnU R                  U5       H  nUb  X#R                  U5      -  nUnM     U$ )uO   Returns estimated length of Bèzier-curve as approximation by line
`segments`.
rO   N)rL   rS   )r,   rH   length
prev_pointrC   s        r#   approximated_lengthBezier4P.approximated_length   sH     
%%h/E%--e44J 0 r1   c                P    [        [        [        U R                  5      5      5      $ )u>   Returns a new Bèzier-curve with reversed control point order.)r   listreversedr7   )r,   s    r#   reverseBezier4P.reverse   s    Xd&9&9:;<<r1   c                    [         R                  " U R                  5      n[        [	        UR                  U5      5      5      $ )zGeneral transformation interface, returns a new :class:`Bezier4p`
curve as a 3D curve.

Args:
     m: 4x4 transformation :class:`Matrix44`

)r   generater7   r   r+   transform_vertices)r,   mr-   s      r#   	transformBezier4P.transform   s3     MM$"5"56	a229=>??r1   N)r-   Sequence[T])returnr~   )r>   floatr   r   )rH   intr   Iterator[T])r   )rS   r   rH   r   r   r   )   )rH   r   r   r   )r   zBezier4P[T])r{   r   r   zBezier4P[Vec3])r)   
__module____qualname____firstlineno____doc__	__slots__r/   propertyr7   r?   rC   rL   r`   rB   r<   rq   rv   r|   __static_attributes__r   r1   r#   r   r   !   sW     /IS = =
*	("0*d7
(
=	@r1   r   r   c              #    #    [        U 5      n[        U5      n[        X#5      n[        U5      S:  a  gUn[        R
                  " U5      [        R                  -  n[        R
                  " Xv-   5      nX#:  a  U[        R                  -  nX#:  a  M  [        X#U5       H&  nU V	s/ s H	  oX-  -   PM     n
n	[        U
5      v   M(     gs  sn	f 7f)u}  Returns an approximation for a circular 2D arc by multiple cubic
Bézier-curves.

Args:
    center: circle center as :class:`Vec3` compatible object
    radius: circle radius
    start_angle: start angle in degrees
    end_angle: end angle in degrees
    segments: count of Bèzier-curve segments, at least one segment for each
        quarter (90 deg), 1 for as few as possible.

&.>N)	r   r   r   absrP   radianstaur   r   )centerradiusstart_angle	end_anglerH   center_
angle_spansr7   r!   r-   s              r#   r   r      s     & LG6]F*;BJ
:A,,q/DHH,KQ^,I

!TXX	 
! 6khW5CD^
+^	Dy!! XDs   BCC'C7Crl   PI_2c              #  4  ^ #    T R                   n[        U5      S:  a  gT R                  [        R                  -  nX2-   nX4:  a  U[        R                  -  nX4:  a  M  SU 4S jjn[        X4U5       H  n[        [        U" U5      5      5      v   M!     g7f)u1  Returns an approximation for an elliptic arc by multiple cubic
Bézier-curves.

Args:
    ellipse: ellipse parameters as :class:`~ezdxf.math.ConstructionEllipse`
        object
    segments: count of Bèzier-curve segments, at least one segment for each
        quarter (π/2), 1 for as few as possible.

r   Nc              3     >#    [        TR                  5      nTR                  nTR                  nU  H%  nXUR                  -  -   X4R
                  -  -   v   M'     g 7fr   )r   r   
major_axis
minor_axisxy)pointsr   x_axisy_axisr!   ellipses        r#   r|   ,cubic_bezier_from_ellipse.<locals>.transform  sP     gnn%))))AACC<'&33,66 s   AA)r   zIterable[Vec3]r   zIterator[Vec3])
param_spanr   start_paramrP   r   r   r   r+   )r   rH   r   r   r   r|   r-   s   `      r#   r   r      s       **J
: ,,txx7K"/I

!TXX	 
!7 1R	uYy1233 Ss   AB 8BgUUUUUU?gI`Q?c              #  *  #    US:  a  [        S5      eX-
  nUS:  a5  [        [        R                  " U[        R                  -  S-  5      U5      nO[        S5      eX4-  n[
        [        R                  " US-  5      -  nU n[        R                  " U5      n[        U5       Hi  n	Un
Xu-  n[        R                  " U5      nU
U
R                  * U-  U
R                  U-  4-   nUUR                  U-  UR                  * U-  4-   nXX4v   Mk     g7f)u  Yields cubic Bézier-curve parameters for a circular 2D arc with center
at (0, 0) and a radius of 1 in the form of [start point, 1. control point,
2. control point, end point].

Args:
    start_angle: start angle in radians
    end_angle: end angle in radians (end_angle > start_angle!)
    segments: count of Bèzier-curve segments, at least one segment for each
        quarter (π/2)

r
   z!Invalid argument segments (>= 1).r   rl   z3Delta angle from start- to end angle has to be > 0.rk   N)r'   maxrP   ceilpiTANGENT_FACTORtanr   
from_anglerG   r   r   )r   r   rH   delta_angle	arc_countsegment_angletangent_lengthangler[   rd   rY   control_point_1control_point_2s                r#   r   r   )  s     !|<=="0KQ		+"7#"=>I	NOO&2M*TXXmc6I-JJNEooe,I9OOE*	%]]N^+MMN*)
 
 $KK.([[L>)'
 
 OFF s   DD))r   r   r   r
   r   ih  r
   )r   r   r   r   r   r   r   r   rH   r   r   Iterator[Bezier4P[Vec3]])r
   )r   z'ConstructionEllipse'rH   r   r   r   )r   r   r   r   rH   r   r   z'Iterator[tuple[Vec3, Vec3, Vec3, Vec3]])!
__future__r   typingr   r   r   r   r   r	   rP   _vectorr   r   	_matrix44r   
_constructr   
ezdxf.mathr   ezdxf.math.ellipser   __all__r   r   r   r   r   __annotations__r   DEFAULT_TANGENT_FACTOROPTIMIZED_TANGENT_FACTORr   r   r   r1   r#   <module>r      s#   #      *6 Ctr@wqz r@l !"!"!" !" 	!"
 !" !"H ggme  564"4.144H # -  ( ;<'G'G#('G47'G,'Gr1   