Ë
    £èhd.  ã                  óD  — U d dl mZ d dlmZmZmZmZmZmZ d dl	Z	ddl
mZmZ ddlmZ ddlmZ erd dlmZ d d	lmZ g d
¢Z edee«      Z G d„ dee   «      Z	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd„Ze	j2                  dz  Zded<   	 d	 	 	 	 	 dd„ZdZdZeZ	 d	 	 	 	 	 	 	 dd„Z y)é    )Ú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                  óz   — e Zd ZdZdZdd„Zedd„«       Zdd„Zdd„Z	dd„Z
ddd„Zdd	„Zdd
„Zddd„Zdd„Zdd„Zy)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                óì   ‡— t        |«      dk7  rt        d«      ‚|d   j                  }|j                  dvrt	        d|j                  › �«      ‚|d   Š‰| _        t        ˆfd„|D «       «      | _        y )Né   zFour control points required.r   )r   r   zinvalid point type: c              3  ó(   •K  — | ]	  }|‰z
  –— Œ y ­w©N© )Ú.0ÚpÚoffsets     €ú4lib/python3.12/site-packages/ezdxf/math/_bezier4p.pyÚ	<genexpr>z$Bezier4P.__init__.<locals>.<genexpr>=   s   øè ø€ Ð3RÉ	À1°A¸µJÉ	ùs   ƒ)ÚlenÚ
ValueErrorÚ	__class__Ú__name__Ú	TypeErrorr   Útupler   )ÚselfÚ	defpointsÚ
point_typer!   s      @r"   Ú__init__zBezier4P.__init__2   sx   ø€ Üˆy‹>˜QÒÜÐ<Ó=Ð=Ø˜q‘\×+Ñ+ˆ
Ø×"Ñ"Ð&6Ñ6ÜÐ2°:×3FÑ3FÐ2GÐHÓIÐIð ˜a‘LˆØ ˆŒä.3Ó3RÉ	Ó3RÓ.RˆÕó    c                óZ   — | j                   \  }}}}| j                  }|||z   ||z   ||z   fS )zBControl points as tuple of :class:`Vec3` or :class:`Vec2` objects.r   )r*   Úp0Úp1Úp2Úp3r!   s         r"   Úcontrol_pointszBezier4P.control_points?   s;   € ð ×-Ñ-‰ˆˆB��BØ—‘ˆØ�r˜F‘{ B¨¡K°°f±Ð<Ð<r.   c                óh   — d|cxk  rdk  st        d«      ‚ t        d«      ‚| j                  |«      S )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"   ÚtangentzBezier4P.tangentG   s=   € ð �Q”˜#’ÜÐ6Ó7Ð7ð ÜÐ6Ó7Ð7Ø×&Ñ& qÓ)Ð)r.   c                óh   — d|cxk  rdk  st        d«      ‚ t        d«      ‚| j                  |«      S )uƒ   Returns point for location `t` at the BÃ¨zier-curve.

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

        r   r6   r7   )r%   Ú_get_curve_pointr9   s     r"   ÚpointzBezier4P.pointS   s=   € ð �Q”˜#’ÜÐ6Ó7Ð7ð ÜÐ6Ó7Ð7Ø×$Ñ$ QÓ'Ð'r.   c              #  ó¸   K  — |dk  rt        |«      ‚d|z  }| j                  }|d   –— t        d|«      D ]  }| j                  ||z  «      –— Œ |d   –— y­w)u¾   Approximate `BÃ©zier curve`_ by vertices, yields `segments` + 1
        vertices as ``(x, y[, z])`` tuples.

        Args:
            segments: count of segments for approximation

        r
   r6   r   é   N)r%   r4   Úranger=   )r*   ÚsegmentsÚdelta_tÚcpÚsegments        r"   ÚapproximatezBezier4P.approximate^   sg   è ø€ ð �aŠ<Ü˜XÓ&Ð&Ø˜‘.ˆØ× Ñ ˆØ�‰eŠÜ˜Q Ö)ˆGØ×'Ñ'¨°'Ñ(9Ó:Ó:ð *à�‰e‹ùs   ‚AAc              #  ó¸  K  — g }d|z  }d}| j                   }|d   }|–— |dk  r³||z   }t        j                  |d«      r|d   }	d}n| j                  |«      }		 ||z   dz  }
| j                  |
«      }|j	                  |	«      }|j                  |«      }||k  r|	–— |}|	}|r|j                  «       \  }}	nn|j                  ||	f«       |
}|}	Œw|dk  rŒ²yy­w)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

        r6   ç        r   r@   g      à?N)r4   ÚmathÚiscloser=   ÚlerpÚdistanceÚpopÚappend)r*   rL   rB   ÚstackÚdtÚt0rD   Ústart_pointÚt1Ú	end_pointÚmid_tÚ	mid_pointÚ	chk_pointÚds                 r"   Ú
flatteningzBezier4P.flatteningo   s  è ø€ ð (*ˆØ˜(‘NˆØˆà× Ñ ˆØ˜A™ˆð ÒØ�3ŠhØ�b‘ˆBÜ�|‰|˜B Ô$Ø˜q™E�	Ø‘à ×1Ñ1°"Ó5�	àØ " R¡¨3™�Ø#×4Ñ4°UÓ;�	Ø*×/Ñ/°	Ó:�	à×&Ñ& yÓ1�Ø�x’<Ø#’OØ�BØ"+�KÙØ(-¯	©	«™˜™Iàà—L‘L " i Ô1Ø�BØ )�Ið# ð �3�hùs   ‚CCÃCc                ó¤   — | j                   \  }}}}||z  }d|z
  }d|z  |z  |z  }d|z  |z  }	||z  }
||z  ||	z  z   ||
z  z   | j                  z   S )Nr6   ç      @r   )r*   r:   Ú_r1   r2   r3   Út2Ú
_1_minus_tÚbÚcrX   s              r"   r=   zBezier4P._get_curve_point¡   sy   € ð ×,Ñ,‰ˆˆ2ˆr�2Ø�‰UˆØ˜1‘Wˆ
à�*Ñ˜zÑ)¨AÑ-ˆØ�*Ñ˜rÑ!ˆØ�‰FˆØ�A‰v˜˜Q™‰  a¡Ñ'¨$¯,©,Ñ6Ð6r.   c                ó˜   — | j                   \  }}}}||z  }ddd|z  z
  d|z  z   z  }d|z  dd|z  z
  z  }d|z  }	||z  ||z  z   ||	z  z   S )Nr[   r6   ç      @ç       @)r   )
r*   r:   r\   r1   r2   r3   r]   r_   r`   rX   s
             r"   r8   zBezier4P._get_curve_tangent®   su   € ð ×,Ñ,‰ˆˆ2ˆr�2Ø�‰Uˆà�3˜˜q™‘= 3¨¡8Ñ+Ñ,ˆØ�!‰G�s˜S 1™W‘}Ñ%ˆØ�"‰HˆØ�A‰v˜˜Q™‰  a¡Ñ'Ð'r.   c                ój   — d}d}| j                  |«      D ]  }|�||j                  |«      z  }|}Œ |S )u_   Returns estimated length of BÃ¨zier-curve as approximation by line
        `segments`.
        rH   N)rF   rL   )r*   rB   ÚlengthÚ
prev_pointr>   s        r"   Úapproximated_lengthzBezier4P.approximated_lengthº   sJ   € ð ˆØˆ
Ø×%Ñ% hÖ/ˆEØÐ%Ø˜*×-Ñ-¨eÓ4Ñ4�Ø‰Jð 0ð ˆr.   c                óP   — t        t        t        | j                  «      «      «      S )u>   Returns a new BÃ¨zier-curve with reversed control point order.)r   ÚlistÚreversedr4   )r*   s    r"   ÚreversezBezier4P.reverseÆ   s   € äœœX d×&9Ñ&9Ó:Ó;Ó<Ð<r.   c                ó†   — t        j                  | j                  «      }t        t	        |j                  |«      «      «      S )z¬General transformation interface, returns a new :class:`Bezier4p`
        curve as a 3D curve.

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

        )r   Úgenerater4   r   r)   Útransform_vertices)r*   Úmr+   s      r"   Ú	transformzBezier4P.transformÊ   s3   € ô —M‘M $×"5Ñ"5Ó6ˆ	Üœ˜a×2Ñ2°9Ó=Ó>Ó?Ð?r.   N)r+   úSequence[T])Úreturnrq   )r:   Úfloatrr   r   )rB   Úintrr   úIterator[T])r   )rL   rs   rB   rt   rr   ru   )é€   )rB   rt   rr   rs   )rr   zBezier4P[T])ro   r   rr   zBezier4P[Vec3])r'   Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r-   Úpropertyr4   r;   r>   rF   rY   r=   r8   rg   rk   rp   r   r.   r"   r   r   !   sW   „ ñð /€IóSð ò=ó ð=ó
*ó	(óô"0*ód7ó
(ô
ó=ô	@r.   r   rs   c              #  óœ  K  — t        | «      }t        |«      }t        ||«      }t        |«      dk  ry|}t	        j
                  |«      t        j                  z  }t	        j
                  ||z   «      }||kD  r|t        j                  z  }||kD  rŒt        |||«      D ]$  }|D �	cg c]
  }	||	|z  z   ‘Œ }
}	t        |
«      –— Œ& yc c}	w ­w)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   rs   r   ÚabsrI   ÚradiansÚtaur   r   )ÚcenterÚradiusÚstart_angleÚ	end_anglerB   Úcenter_Ú
angle_spanÚsr4   r    r+   s              r"   r   r   Ö   sÃ   è ø€ ô& ˜“L€GÜ�6‹]€FÜ*¨;¸	ÓB€JÜ
ˆ:ƒ˜ÒØà€AÜ—,‘,˜q“/¤D§H¡HÑ,€KÜ—‘˜Q ™^Ó,€IØ
˜	Ò
!Ø”T—X‘XÑˆ	ð ˜	Ó
!ô 6°kÀ9ÈhÖWˆÙ5CÓD±^°�W  F¡
Ó+°^ˆ	ÐDÜ�yÓ!Ó!ñ XùÚDùs   ‚BCÂCÂ&CÂ5Crc   ÚPI_2c              #  ó,  ‡ K  — ‰ j                   }t        |«      dk  ry‰ j                  t        j                  z  }||z   }||kD  r|t        j                  z  }||kD  rŒdˆ fd„}t        |||«      D ]  }t        t         ||«      «      «      –— Œ  y­w)uM  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  ó¾   •K  — t        ‰j                  «      }‰j                  }‰j                  }| D ]&  }|||j                  z  z   ||j
                  z  z   –— Œ( y ­wr   )r   r�   Ú
major_axisÚ
minor_axisÚxÚy)Úpointsr�   Úx_axisÚy_axisr    Úellipses        €r"   rp   z,cubic_bezier_from_ellipse.<locals>.transform  sU   øè ø€ Ü�g—n‘nÓ%ˆØ×)Ñ)ˆØ×)Ñ)ˆÛˆAØ˜6 A§C¡C™<Ñ'¨&°1·3±3©,Ñ6Ó6ñ ùs   ƒAA)r�   zIterable[Vec3]rr   zIterator[Vec3])Ú
param_spanr~   Ústart_paramrI   r€   r   r   r)   )r’   rB   r“   rƒ   r„   rp   r+   s   `      r"   r   r   ý   s‘   øè ø€ ð  ×*Ñ*€JÜ
ˆ:ƒ˜ÒØØ ×,Ñ,¬t¯x©xÑ7€KØ" ZÑ/€IØ
˜	Ò
!Ø”T—X‘XÑˆ	ð ˜	Ó
!õ7ô 1°¸iÈÖRˆ	Ü”u™Y yÓ1Ó2Ó3Ó3ñ Sùs   ƒABÁ5BgUUUUUUõ?gI›ð`­Qõ?c              #  ó$  K  — |dk  rt        d«      ‚|| z
  }|dkD  r4t        t        j                  |t        j                  z  dz  «      |«      }nt        d«      ‚||z  }t
        t        j                  |dz  «      z  }| }t        j                  |«      }t        |«      D ]j  }	|}
||z  }t        j                  |«      }|
|
j                   |z  |
j                  |z  fz   }||j                  |z  |j                   |z  fz   }|
|||f–— Œl y­w)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   rc   z3Delta angle from start- to end angle has to be > 0.rb   N)r%   ÚmaxrI   ÚceilÚpiÚTANGENT_FACTORÚtanr   Ú
from_anglerA   rŽ   r�   )rƒ   r„   rB   Údelta_angleÚ	arc_countÚsegment_angleÚtangent_lengthÚanglerT   r\   rR   Úcontrol_point_1Úcontrol_point_2s                r"   r   r   )  s!  è ø€ ð �!‚|ÜÐ<Ó=Ð=Ø" [Ñ0€KØ�Q‚ÜœŸ	™	 +´·±Ñ"7¸#Ñ"=Ó>ÀÓI‰	äÐNÓOÐOà&¨Ñ2€MÜ*¬T¯X©X°mÀcÑ6IÓ-JÑJ€Nà€EÜ—o‘o eÓ,€IÜ�9ÖˆØˆØ�ÑˆÜ—O‘O EÓ*ˆ	Ø%Ø�]‰]ˆN˜^Ñ+Ø�M‰M˜NÑ*ð)
ñ 
ˆð $Ø�K‰K˜.Ñ(Ø�[‰[ˆL˜>Ñ)ð'
ñ 
ˆð ˜?¨O¸YÐFÓFñ ùs   ‚DD))r   r   r   r
   r   ih  r
   )r�   r   r‚   rs   rƒ   rs   r„   rs   rB   rt   rr   úIterator[Bezier4P[Vec3]])r
   )r’   z'ConstructionEllipse'rB   rt   rr   r£   )rƒ   rs   r„   rs   rB   rt   rr   z'Iterator[tuple[Vec3, Vec3, Vec3, Vec3]])!Ú
__future__r   Útypingr   r   r   r   r   r	   rI   Ú_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   r.   r"   Ú<module>r¯      s#  ðö #÷÷ ó ÷  Ý Ý *áÝÝ6ò€ñ ˆC��tÓ€ôr@ˆw�q‰zô r@ðl ØØØØð!"Øð!"àð!"ð ð!"ð ð	!"ð
 ð!"ð ó!"ðH �g‰g˜‰m€€eÓ ð 56ð4Ø"ð4Ø.1ð4àó4ðH #Ð à-Ð ð (€ð ;<ð'GØð'GØ#(ð'GØ47ð'Gà,ô'Gr.   