Ë
    £èh¸ ã                  óf  — d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
 ddlZddlZddlmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZ dd	lmZ erdd
lmZmZmZm Z  g d¢Z!	 d9	 	 	 	 	 d:d„Z"d;d„Z#	 	 	 d<	 	 	 	 	 	 	 	 	 d=d„Z$	 	 d>	 	 	 	 	 	 	 d?d„Z%d@d„Z&dAdBd„Z'dBd„Z(dCd„Z)dDdEd„Z*dDdEd„Z+	 dF	 	 	 	 	 	 	 dGd„Z,dHd„Z-dHd„Z.dHd„Z/dHd„Z0dHd„Z1dId„Z2	 dJ	 	 	 	 	 	 	 	 	 dKd„Z3	 dJ	 	 	 	 	 	 	 	 	 	 	 	 	 dLd„Z4	 	 	 	 dMd „Z5	 	 	 	 	 	 	 	 	 	 dNd!„Z6	 	 	 	 	 	 dOd"„Z7 G d#„ d«      Z8dPd$„Z9	 	 dQ	 	 	 	 	 	 	 dRd%„Z:	 	 dQ	 	 	 	 	 	 	 dRd&„Z;	 	 	 	 	 dS	 	 	 	 	 	 	 	 	 	 	 dTd'„Z<ejz                  d(z  Z>	 dU	 	 	 	 	 dVd)„Z?dUdWd*„Z@dXd+„ZA	 	 	 	 	 	 	 	 	 	 dYd,„ZBe
dZd-„«       ZCd[d.„ZD	 	 	 	 d\d/„ZEd0d1d2d3œ	 	 	 	 	 d]d4„ZF G d5„ d6«      ZGd^d7„ZHd_d8„ZIy)`aG  
B-Splines
=========

https://www.cl.cam.ac.uk/teaching/2000/AGraphHCI/SMEG/node4.html

Rational B-splines
==================

https://www.cl.cam.ac.uk/teaching/2000/AGraphHCI/SMEG/node5.html:

"The NURBS Book" by Les Piegl and Wayne Tiller

https://books.google.at/books/about/The_NURBS_Book.html?id=7dqY5dyAwWkC&redir_esc=y

é    )Úannotations)ÚIterableÚIteratorÚSequenceÚTYPE_CHECKINGÚOptionalÚAnyÚno_type_checkN)	ÚVec3ÚUVecÚNULLVECÚBasisÚ	EvaluatorÚcreate_t_vectorÚestimate_end_tangent_magnitudeÚdistance_point_line_3dÚarc_angle_span_degé   )ÚBoundingBox)Úlinalg)ÚDXFValueError)ÚConstructionArcÚConstructionEllipseÚMatrix44ÚBezier4P)Úfit_points_to_cad_cvÚglobal_bspline_interpolationÚ!local_cubic_bspline_interpolationÚrational_bspline_from_arcÚrational_bspline_from_ellipseÚfit_points_to_cubic_bezierÚopen_uniform_bsplineÚclosed_uniform_bsplineÚBSplineÚ*unconstrained_global_bspline_interpolationÚ)global_bspline_interpolation_end_tangentsÚcad_fit_point_interpolationÚ.global_bspline_interpolation_first_derivativesÚ/local_cubic_bspline_interpolation_from_tangentsÚknots_from_parametrizationÚaveraged_knots_unconstrainedÚaveraged_knots_constrainedÚnatural_knots_unconstrainedÚnatural_knots_constrainedÚdouble_knotsÚrequired_knot_valuesÚuniform_knot_vectorÚopen_uniform_knot_vectorÚrequired_fit_pointsÚrequired_control_pointsÚround_knotsr$   c                óV  — t        j                  | «      }t        |«      dk  rt        d«      ‚|€t	        |«      \  }}t        |d|¬«      S t        j                  |«      }t        |d¬«      \  }}|d   j                  |«      }|d   j                  |«      }	t        |d	||	fd¬
«      S )a¹  Returns a cubic :class:`BSpline` from fit points as close as possible
    to common CAD applications like BricsCAD.

    There exist infinite numerical correct solution for this setup, but some
    facts are known:

    - CAD applications use the global curve interpolation with start- and end
      derivatives if the end tangents are defined otherwise the equation system will
      be completed by setting the second derivatives of the start and end point to 0,
      for more information read this answer on stackoverflow: https://stackoverflow.com/a/74863330/6162864
    - The degree of the B-spline is always 3 regardless which degree is stored in the
      SPLINE entity, this is only valid for B-splines defined by fit points
    - Knot parametrization method is "chord"
    - Knot distribution is "natural"

    Args:
        fit_points: points the spline is passing through
        tangents: start- and end tangent, default is autodetect

    é   útwo or more points required é   ©ÚorderÚknotsÚchord©Úmethodr   éÿÿÿÿé   )ÚdegreeÚtangentsr?   )	r   ÚlistÚlenÚ
ValueErrorr'   r$   r   Ú	normalizer   )
Ú
fit_pointsrC   ÚpointsÚcontrol_pointsr<   ÚtÚm1Úm2Ústart_tangentÚend_tangents
             ú2lib/python3.12/site-packages/ezdxf/math/bspline.pyr   r   [   s­   € ô2 �Y‰Y�zÓ"€FÜ
ˆ6ƒ{�Q‚ÜÐ7Ó8Ð8àÐÜ ;¸FÓ CÑˆ˜Ü�~¨Q°eÔ<Ð<Ü�	‰	�(Ó€AÜ+¨F¸7ÔC�F€BˆØ�a‘D—N‘N 2Ó&€MØ�B‘%—/‘/ "Ó%€Kä'ØØØ Ð-Øô	ð ó    c                óŽ   — t        j                  | «      }t        |«      dk  rt        d«      ‚ddlm}m}  ||«      } ||«      S )u«  Returns a cubic :class:`BSpline` from fit points **without** end
    tangents.

    This function uses the cubic BÃ¨zier interpolation to create multiple BÃ¨zier
    curves and combine them into a single B-spline, this works for short simple
    splines better than the :func:`fit_points_to_cad_cv`, but is worse
    for longer and more complex splines.

    Args:
        fit_points: points the spline is passing through

    r7   r8   r   )Úcubic_bezier_interpolationÚbezier_to_bspline)r   rD   rE   rF   Ú
ezdxf.mathrS   rT   )rH   rI   rS   rT   Úbezier_curvess        rP   r!   r!   ˆ   sA   € ô �Y‰Y�zÓ"€FÜ
ˆ6ƒ{�Q‚ÜÐ7Ó8Ð8çHá.¨vÓ6€MÙ˜]Ó+Ð+rQ   c                óè  — t        j                  | «      }t        |«      }|dz   }|r|dz  }||kD  r|€t        d|› �«      ‚t        t	        ||«      «      }|dz  rdnd}|�qt        j                  |«      }	t        |	«      dk(  rt        ||	d   |	d   |||«      \  }
}nEt        |	«      t        |«      k(  rt        ||	||«      \  }
}nt        d«      ‚t        ||||«      \  }
}t        |
||¬«      }|S )	a˜  `B-spline`_ interpolation by the `Global Curve Interpolation`_.
    Given are the fit points and the degree of the B-spline.
    The function provides 3 methods for generating the parameter vector t:

    - "uniform": creates a uniform t vector, from 0 to 1 evenly spaced, see
      `uniform`_ method
    - "chord", "distance": creates a t vector with values proportional to the
      fit point distances, see `chord length`_ method
    - "centripetal", "sqrt_chord": creates a t vector with values proportional
      to the fit point sqrt(distances), see `centripetal`_ method
    - "arc": creates a t vector with values proportional to the arc length
      between fit points.

    It is possible to constraint the curve by tangents, by start- and end
    tangent if only two tangents are given or by one tangent for each fit point.

    If tangents are given, they represent 1st derivatives and should be
    scaled if they are unit vectors, if only start- and end tangents given the
    function :func:`~ezdxf.math.estimate_end_tangent_magnitude` helps with an
    educated guess, if all tangents are given, scaling by chord length is a
    reasonable choice (Piegl & Tiller).

    Args:
        fit_points: fit points of B-spline, as list of :class:`Vec3` compatible
            objects
        tangents: if only two vectors are given, take the first and the last
            vector as start- and end tangent constraints or if for all fit
            points a tangent is given use all tangents as interpolation
            constraints (optional)
        degree: degree of B-spline
        method: calculation method for parameter vector t

    Returns:
        :class:`BSpline`

    r   r7   z$More fit points required for degree ÚnaturalÚaverager   zoInvalid count of tangents, two tangents as start- and end tangent constrains or one tangent for each fit point.r:   )	r   rD   rE   rF   r   r&   r(   r%   r$   )rH   rB   rC   r?   Ú_fit_pointsÚcountr;   Út_vectorÚknot_generation_methodÚ	_tangentsrJ   r<   Úbsplines                rP   r   r   Ÿ   s0  € ôT —)‘)˜JÓ'€KÜ�Ó€EØ˜!‘€Eáà�‰
ˆØˆu‚}˜Ð)ÜÐ?À¸xÐHÓIÐIä”O K°Ó8Ó9€Hà*0°1ª*™Y¸)ÐØÐÜ—I‘I˜hÓ'ˆ	Üˆy‹>˜QÒÜ$MØØ˜!‘Ø˜!‘ØØØ&ó%Ñ!ˆN™Eô �‹^œs ;Ó/Ò/ô ?Ø˜Y¨°óñØÙô
 ðHóð ô
 !KØ˜ Ð+Aó!
Ñˆ˜ô �n¨E¸Ô?€GØ€NrQ   c                ó´   — ddl m} t        j                  | «      }|rt        j                  |«      }n	 |||«      }t	        ||«      \  }}t        |d|¬«      S )a  `B-spline`_ interpolation by 'Local Cubic Curve Interpolation', which
    creates B-spline from fit points and estimated tangent direction at start-,
    end- and passing points.

    Source: Piegl & Tiller: "The NURBS Book" - chapter 9.3.4

    Available tangent estimation methods:

    - "3-points": 3 point interpolation
    - "5-points": 5 point interpolation
    - "bezier": cubic bezier curve interpolation
    - "diff": finite difference

    or pass pre-calculated tangents, which overrides tangent estimation.

    Args:
        fit_points: all B-spline fit points as :class:`Vec3` compatible objects
        method: tangent estimation method
        tangents: tangents as :class:`Vec3` compatible objects (optional)

    Returns:
        :class:`BSpline`

    r   )Úestimate_tangentsr9   r:   )Úparametrizera   r   rD   r)   r$   )rH   r?   rC   ra   rZ   r^   rJ   r<   s           rP   r   r   õ   sW   € õ: /ä—)‘)˜JÓ'€KÙÜ—I‘I˜hÓ'‰	á% k°6Ó:ˆ	ÜKØ�YóÑ€N�Eô �>¨°%Ô8Ð8rQ   c                ó˜   — t        |«      }t        | «      dz
  }|dz
  }d|cxk  r|dz   k  st        d«      ‚ t        d«      ‚||z   dz   S )uv  Returns the count of required knot-values for a B-spline of `order` and
    `count` control points.

    Args:
        count: count of control points, in text-books referred as "n + 1"
        order: order of B-Spline, in text-books referred as "k"

    Relationship:

    "p" is the degree of the B-spline, text-book notation.

    - k = p + 1
    - 2 â‰¤ k â‰¤ n + 1

    r   r7   zInvalid count/order combination)Úintr   )r[   r;   ÚkÚnÚps        rP   r0   r0     s_   € ô  	ˆE‹
€AÜˆE‹
�Q‰€AØ	ˆA‰€AØ�Ô�q˜1‘uÒÜÐ=Ó>Ð>ð ÜÐ=Ó>Ð>àˆq‰5�1‰9ÐrQ   c                ó(   — |r| dz  } t        | d«      S )zÎReturns the count of required fit points to calculate the spline
    control points.

    Args:
        order: spline order (degree + 1)
        tangents: start- and end tangent are given or estimated

    r7   ©Úmax)r;   rC   s     rP   r3   r3   8  s   € ñ ð 	�‰
ˆäˆu�a‹=ÐrQ   c                ó   — t        | d«      S )zÅReturns the required count of control points for a valid B-spline.

    Args:
        order: spline order (degree + 1)

    Required condition: 2 <= order <= count, therefore:  count >= order

    r7   ri   )r;   s    rP   r4   r4   J  s   € ô ˆu�a‹=ÐrQ   c                óR   — | d   }| d   |z
  }| D �cg c]
  }||z
  |z  ‘Œ c}S c c}w )z(Normalize knot vector into range [0, 1].r   r@   © )r<   Úmin_valÚmax_valÚvs       rP   Únormalize_knotsrq   V  s:   € à�A‰h€GØ�B‰i˜'Ñ!€GÙ-2Ó3©U¨ˆQ�‰[˜GÓ#¨UÑ3Ð3ùÒ3s   ’$c                óv   — |rt        | |z   dz
  «      }nd}t        | |z   «      D �cg c]  }||z  ‘Œ	 c}S c c}w )a  Returns an uniform knot vector for a B-spline of `order` and `count`
    control points.

    `order` = degree + 1

    Args:
        count: count of control points
        order: spline order
        normalize: normalize values in range [0, 1] if ``True``

    r   ç      ð?)ÚfloatÚrange)r[   r;   rG   Ú	max_valueÚ
knot_values        rP   r1   r1   ]  sG   € ñ Ü˜% %™-¨!Ñ+Ó,‰	àˆ	Ü5:¸5À5¹=Ô5IÓJÑ5I zˆJ˜Ó"Ð5IÑJÐJùÒJs   §6c                óÐ   ‡— | |z
  }|rt        | |z
  dz   «      Šdg|z  }ndŠd|z   g|z  }dg|z  }|j                  ˆfd„t        |«      D «       «       |j                  |«       |S )a  Returns an open (clamped) uniform knot vector for a B-spline of `order`
    and `count` control points.

    `order` = degree + 1

    Args:
        count: count of control points
        order: spline order
        normalize: normalize values in range [0, 1] if ``True``

    r   rs   ç        c              3  ó.   •K  — | ]  }d |z   ‰z  –— Œ y­w)rs   Nrm   )Ú.0rp   rv   s     €rP   Ú	<genexpr>z+open_uniform_knot_vector.<locals>.<genexpr>…  s   øè ø€ Ð9±¨1�#˜‘'˜YÕ&±ùó   ƒ)rt   Úextendru   )r[   r;   rG   re   Útailr<   rv   s         @rP   r2   r2   p  sv   ø€ ð 	�‰€AÙÜ˜% %™-¨!Ñ+Ó,ˆ	Øˆu�u‰}‰àˆ	Ø�a‘ˆy˜5Ñ ˆàˆE�E‰M€EØ	‡L�LÓ9´°a´Ó9Ô9Ø	‡L�L�ÔØ€LrQ   c                óv  — t        |dz   «      }|| dz   kD  rt        d«      ‚|D �cg c]  }t        |«      ‘Œ }}|d   dk7  st        j                  |d   d«      st        d«      ‚|dk(  r|rt        | ||«      S t        | ||«      S |d	k(  r|rt        | ||«      S t        | ||«      S t        d
|› �«      ‚c c}w )a¨  Returns a 'clamped' knot vector for B-splines. All knot values are
    normalized in the range [0, 1].

    Args:
        n: count fit points - 1
        p: degree of spline
        t: parametrization vector, length(t_vector) == n, normalized [0, 1]
        method: "average", "natural"
        constrained: ``True`` for B-spline constrained by end derivatives

    Returns:
        List of n+p+2 knot values as floats

    r   z2Invalid n/p combination, more fit points required.r   ry   r@   rs   z.Parametrization vector t has to be normalized.rY   rX   z Unknown knot generation method: )
rd   r   rt   ÚmathÚiscloserF   r,   r+   r.   r-   )rf   rg   rK   r?   Úconstrainedr;   rp   s          rP   r*   r*   Š  sê   € ô" ��A‘‹J€EØ��A‘‚ÜÐPÓQÐQáÓ™1�aŒˆq�˜1€AÐØˆ�tˆs‚{œ$Ÿ,™, q¨¡u¨cÔ2ÜÐIÓJÐJà�Òñ ô ' q¨!¨QÓ/ð	
ô .¨a°°AÓ6ð	
ð
 
�9Ò	ñ ô & a¨¨AÓ.ð	
ô -¨Q°°1Ó5ð	
ô Ð;¸F¸8ÐDÓEÐEùò# 	s   ¦B6c                ó  ‡‡— ‰d   dk(  sJ ‚t        j                  ‰d   d«      sJ ‚dg‰dz   z  }|j                  ˆˆfd„t        d| ‰z
  dz   «      D «       «       |d   dkD  rt	        d«      ‚|j                  dg‰dz   z  «       |S )záReturns an averaged knot vector from parametrization vector `t` for an
    unconstrained B-spline.

    Args:
        n: count of control points - 1
        p: degree
        t: parametrization vector, normalized [0, 1]

    r   ry   r@   rs   r   c              3  óF   •K  — | ]  }t        ‰||‰z    «      ‰z  –— Œ y ­w©N©Úsum©r{   Újrg   rK   s     €€rP   r|   z/averaged_knots_unconstrained.<locals>.<genexpr>Á  s(   øè ø€ ÐDÑ0C¨1”�Q�q˜1˜q™5�\Ó" QÕ&Ñ0Cùs   ƒ!z!Normalized [0, 1] values required)r�   r‚   r~   ru   rF   ©rf   rg   rK   r<   s    `` rP   r+   r+   ³  s�   ù€ ð ˆQ‰4�3Š;Ðˆ;Ü�<‰<˜˜"™˜sÔ#Ð#Ð#àˆE�Q˜‘U‰O€EØ	‡L�LÔD´°a¸¸Q¹À¹Ô0CÓDÔDØˆR�y�3‚ÜÐ<Ó=Ð=Ø	‡L�L�#�˜!˜a™%‘Ô!Ø€LrQ   c                óä   ‡‡— ‰d   dk(  sJ ‚t        j                  ‰d   d«      sJ ‚dg‰dz   z  }|j                  ˆˆfd„t        | ‰z
  «      D «       «       |j                  dg‰dz   z  «       |S )zÞReturns an averaged knot vector from parametrization vector `t` for a
    constrained B-spline.

    Args:
        n: count of control points - 1
        p: degree
        t: parametrization vector, normalized [0, 1]

    r   ry   r@   rs   r   c              3  óL   •K  — | ]  }t        ‰||‰z   d z
   «      ‰z  –— Œ y­w)r   Nr‡   r‰   s     €€rP   r|   z-averaged_knots_constrained.<locals>.<genexpr>Ö  s+   øè ø€ ÐA±L¨q”�Q�q˜1˜q™5 1™9Ð%Ó&¨Õ*±Lùs   ƒ!$)r�   r‚   r~   ru   r‹   s    `` rP   r,   r,   È  sq   ù€ ð ˆQ‰4�3Š;Ðˆ;Ü�<‰<˜˜"™˜sÔ#Ð#Ð#àˆE�Q˜‘U‰O€EØ	‡L�LÔA´E¸!¸a¹%´LÓAÔAØ	‡L�L�#�˜!˜a™%‘Ô!Ø€LrQ   c                óÆ   — |d   dk(  sJ ‚t        j                  |d   d«      sJ ‚dg|dz   z  }|j                  |d| |z
  dz    «       |j                  dg|dz   z  «       |S )záReturns a 'natural' knot vector from parametrization vector `t` for an
    unconstrained B-spline.

    Args:
        n: count of control points - 1
        p: degree
        t: parametrization vector, normalized [0, 1]

    r   ry   r@   rs   r   r7   ©r�   r‚   r~   r‹   s       rP   r-   r-   Û  óq   € ð ˆQ‰4�3Š;Ðˆ;Ü�<‰<˜˜"™˜sÔ#Ð#Ð#àˆE�Q˜‘U‰O€EØ	‡L�L��1�q˜1‘u˜q‘yÐ!Ô"Ø	‡L�L�#�˜!˜a™%‘Ô!Ø€LrQ   c                óÆ   — |d   dk(  sJ ‚t        j                  |d   d«      sJ ‚dg|dz   z  }|j                  |d| |z
  dz    «       |j                  dg|dz   z  «       |S )zÞReturns a 'natural' knot vector from parametrization vector `t` for a
    constrained B-spline.

    Args:
        n: count of control points - 1
        p: degree
        t: parametrization vector, normalized [0, 1]

    r   ry   r@   rs   r   r�   r‹   s       rP   r.   r.   î  r�   rQ   c                ó  — |d   dk(  sJ ‚t        j                  |d   d«      sJ ‚dg|dz   z  }d}g }|dd D ]€  }|dk(  r)|j                  ||z   dz  «       |j                  |«       nN|dk(  r|j                  |dz  «       n4|j                  d|z  |z   dz  «       |j                  |d|z  z   dz  «       |}Œ‚ |j                  |d	| dz  |z
   «       |j                  |d
   dz   dz  «       |j                  dg|dz   z  «       |S )a0  Returns a knot vector from parametrization vector `t` for B-spline
    constrained by first derivatives at all fit points.

    Args:
        n: count of fit points - 1
        p: degree of spline
        t: parametrization vector, first value has to be 0.0 and last value has
            to be 1.0

    r   ry   r@   rs   r   r7   ç       @ç      @Néþÿÿÿ)r�   r‚   Úappendr~   )rf   rg   rK   ÚuÚprev_tÚu1Út1s          rP   r/   r/     s  € ð ˆQ‰4�3Š;Ðˆ;Ü�<‰<˜˜"™˜sÔ#Ð#Ð#à	ˆ��Q‘‰€AØ€Fà	€BØ��"‹gˆØ�Š6à�I‰I�v ‘{ cÑ)Ô*Ø�I‰I�b�Mà˜Š}Ø—	‘	˜"˜q™&Õ!ð —	‘	˜1˜v™:¨™?¨cÑ1Ô2Ø—	‘	˜6 A¨¡F™?¨cÑ1Ô2Ø‰ð ð ‡H�HˆR��!�a‘%˜!‘)ˆ_ÔØ‡H�Hˆa�‰e�c‰k˜SÑ Ô!Ø‡H�HˆcˆU�a˜!‘e‰_ÔØ€HrQ   c                óL  — t        | t        j                  «      st        j                  | «      } | j                  dk  rt        j                  | j
                  «      S t        j                  | d¬«      \  }}t        j                  | ||«      }t        j                  |||«      S )zmReturns best suited linear equation solver depending on matrix configuration and
    python interpreter.
    é   F)Ú	check_all)	Ú
isinstancer   ÚMatrixÚnrowsÚNumpySolverÚmatrixÚdetect_banded_matrixÚcompact_banded_matrixÚBandedMatrixLU)r¢   rB   rL   rM   ÚAs        rP   Ú_get_best_solverr§   '  s‚   € ô �fœfŸm™mÔ,Ü—‘˜vÓ&ˆà‡|�|�bÒÜ×!Ñ! &§-¡-Ó0Ð0ô ×,Ñ,¨V¸uÔE‰ˆˆBÜ×(Ñ(¨°°RÓ8ˆÜ×$Ñ$ Q¨¨BÓ/Ð/rQ   c                ó€  — t        t        | «      dz
  |||d¬«      }t        ||dz   t        | «      ¬«      }t        |D �cg c]  }|j	                  |«      ‘Œ c}|«      }t        j                  | t
        j                  ¬«      }|j                  |«      }	t        j                  |	j                  «       «      |fS c c}w )ar  Interpolates the control points for a B-spline by global interpolation
    from fit points without any constraints.

    Source: Piegl & Tiller: "The NURBS Book" - chapter 9.2.1

    Args:
        fit_points: points the B-spline has to pass
        degree: degree of spline >= 2
        t_vector: parametrization vector, first value has to be 0 and last
            value has to be 1
        knot_generation_method: knot generation method from parametrization
            vector, "average" or "natural"

    Returns:
        2-tuple of control points as list of Vec3 objects and the knot vector
        as list of floats

    r   F©rƒ   ©r<   r;   r[   ©Údtype)r*   rE   r   r§   Úbasis_vectorÚnpÚarrayÚfloat64Úsolve_matrixr   rD   Úrows)
rH   rB   r\   r]   r<   ÚNrK   ÚsolverÚmat_BrJ   s
             rP   r%   r%   >  s©   € ô2 'ÜˆJ‹˜!ÑØØØØô€Eô 	�E ¨!¡´3°z³?ÔC€AÜ¹(ÓC¹(°Q˜qŸ~™~¨aÕ0¸(ÑCÀVÓL€FÜ�H‰H�Z¤r§z¡zÔ2€EØ×(Ñ(¨Ó/€NÜ�9‰9�^×(Ñ(Ó*Ó+¨UÐ2Ð2ùò Ds   Á B;c                ó6  — t        | «      dz
  }|}|dkD  rd}t        |dz   |||d¬«      }t        ||dz   |dz   ¬«      }	|D �
cg c]  }
|	j                  |
«      ‘Œ }}
dg|dz   z  }|j	                  dd	d
g|z   «       |j	                  d|d	d
gz   «       | j	                  d|||dz      |z  z  «       | j	                  d|d
||dz       z
  |z  z  «       t        ||«      }|j                  | «      }t        j                  |j                  «       «      |fS c c}
w )a¸  Calculates the control points for a B-spline by global interpolation
    from fit points and the 1st derivative of the start- and end point as constraints.
    These 'tangents' are 1st derivatives and not unit vectors, if an estimation
    of the magnitudes is required use the :func:`estimate_end_tangent_magnitude`
    function.

    Source: Piegl & Tiller: "The NURBS Book" - chapter 9.2.2

    Args:
        fit_points: points the B-spline has to pass
        start_tangent: 1st derivative as start constraint
        end_tangent: 1st derivative as end constrain
        degree: degree of spline >= 2
        t_vector: parametrization vector, first value has to be 0 and last
            value has to be 1
        knot_generation_method: knot generation method from parametrization
            vector, "average" or "natural"

    Returns:
        2-tuple of control points as list of Vec3 objects and the knot vector
        as list of floats

    r   rA   rX   r7   Tr©   rª   ry   ç      ð¿rs   r@   )
rE   r*   r   r­   Úinsertr§   r±   r   rD   r²   )rH   rN   rO   rB   r\   r]   rf   rg   r<   r³   r—   r²   Úspacingr´   rJ   s                  rP   r&   r&   e  s;  € ô> 	ˆJ‹˜!Ñ€AØ€AØ�‚zð "+ÐÜ&Ø	ˆA‰ˆq�(Ð2Àô€Eô 	�E  Q¡¨a°!©eÔ4€AÙ'/Ó0¡x !ˆA�N‰N˜1Õ x€DÐ0Øˆe�q˜1‘u‰o€GØ‡K�K��D˜$�< 'Ñ)Ô*Ø‡K�K��G˜t T˜lÑ*Ô+Ø×Ñ�a˜¨%°°A±©,¸Ñ*:Ñ;Ô<Ø×Ñ�b˜+¨#°¸¸A¹°h±Ñ*?À1Ñ)DÑEÔFä˜d FÓ+€FØ×(Ñ(¨Ó4€NÜ�9‰9�^×(Ñ(Ó*Ó+¨UÐ2Ð2ùò 1s   ÁDc                ól  ‡‡— dˆˆfd„}dˆˆfd„}t        t        | d«      «      }t        | «      dz
  }dŠt        |dz   ‰|dd¬	«      Št	        ‰‰dz   |dz   ¬
«      }|D �cg c]  }|j                  |«      ‘Œ }}dg|z  }|j                  d |«       |z   «       |j                  d| |«       z   «       | j                  dt        ddd«      «       | j                  dt        ddd«      «       t        |‰«      }	|	j                  | «      }
t        j                   |
j                  «       «      ‰fS c c}w )aŽ  Calculates the control points for a B-spline by global interpolation
    from fit points without any constraints in the same way as AutoCAD and BricsCAD.

    Source: https://stackoverflow.com/a/74863330/6162864

    Args:
        fit_points: points the B-spline has to pass

    Returns:
        2-tuple of control points as list of Vec3 objects and the knot vector
        as list of floats

    c                 ój   •— ‰‰dz      } ‰‰dz      }‰‰dz
  z  | z  }|| z  | | |z   z  | |z  z  ||z  gS )z*Returns the coefficients for equation [1].r   r7   rm   )Úup1Úup2Úfr<   rg   s      €€rP   Úcoefficients1z2cad_fit_point_interpolation.<locals>.coefficients1¬  s`   ø€ ð �A˜‘E‰lˆØ�A˜‘E‰lˆØ��Q‘‰K˜#Ñˆà�‰GØˆB�#˜‘)Ñ  c¡	Ñ*Ø�‰Gð
ð 	
rQ   c                 ó¶   •— t        ‰«      dz
  } ‰| ‰z
  dz
     }‰| ‰z
  dz
     }‰‰dz
  z  d|z
  z  }|d|z
  z  | d|z
  |z
  z  d|z
  z  d|z
  z  |d|z
  z  gS )z,Returns the coefficients for equation [n-1].r   r7   rs   r“   ©rE   )ÚmÚump1Úump2r¾   r<   rg   s       €€rP   Úcoefficients2z2cad_fit_point_interpolation.<locals>.coefficients2¸  s“   ø€ ô �‹J˜‰NˆØ�Q˜‘U˜Q‘YÑˆØ�Q˜‘U˜Q‘YÑˆØ��Q‘‰K˜3 ™:Ñ&ˆà��t‘ÑØˆB�#˜‘*˜tÑ#Ñ$¨¨d©
Ñ3°s¸T±zÑBØ��t‘Ñð
ð 	
rQ   r=   r   rA   r7   rX   T)r?   rƒ   rª   ry   r@   r   )Úreturnúlist[float])rD   r   rE   r*   r   r­   r¸   r   r§   r±   r²   )rH   r¿   rÅ   r\   rf   r³   r—   r²   r¹   r´   rJ   r<   rg   s              @@rP   r'   r'   ›  s&  ù€ ö"

ö
ô ”O J°Ó8Ó9€HÜˆJ‹˜!Ñ€AØ	€AÜ&Ø	ˆA‰ˆq�( 9¸$ô€Eô 	�E  Q¡¨a°!©eÔ4€AÙ'/Ó0¡x !ˆA�N‰N˜1Õ x€DÐ0Øˆe�a‰i€GØ‡K�K�‘=“? WÑ,Ô-Ø‡K�K��G™m›oÑ-Ô.ð ×Ñ�aœ˜a  A›Ô'à×Ñ�bœ$˜q ! Q›-Ô(ä˜d AÓ&€FØ×(Ñ(¨Ó4€NÜ�9‰9�^×(Ñ(Ó*Ó+¨UÐ2Ð2ùò 1s   Á!D1c           	     ób  ‡‡‡‡— dˆˆˆfd„Š|Št        | «      dz
  }t        |‰|«      }t        | «      dz  Št        |‰dz   ‰¬«      Šdgdg‰dz
  z  z   ddgdg‰dz
  z  z   g}t        |d   «      }ˆfd	„|dd
 D «       D ]$  }|j                  |D �	cg c]  }	|	d| ‘Œ	 c}	«       Œ& |j	                  dg‰dz
  z  ddgz   «       |j	                  dg‰dz
  z  dgz   «       t        t        d„ |D «       «      «      dk(  sJ d«       ‚g }
t        | |«      D ]  }|
j                  |«       Œ |
d   |
d
   c|
d
<   |
d<   |
dxx   |‰dz      ‰z  z  cc<   |
dxx   d|‰dz       z
  ‰z  z  cc<   t        ||«      }|j                  |
«      }t        j                  |j                  «       «      |fS c c}	w )a›  Interpolates the control points for a B-spline by a global
    interpolation from fit points and 1st derivatives as constraints.

    Source: Piegl & Tiller: "The NURBS Book" - chapter 9.2.4

    Args:
        fit_points: points the B-spline has to pass
        derivatives: 1st derivatives as constrains, not unit vectors!
            Scaling by chord length is a reasonable choice (Piegl & Tiller).
        degree: degree of spline >= 2
        t_vector: parametrization vector, first value has to be 0 and last
            value has to be 1

    Returns:
        2-tuple of control points as list of Vec3 objects and the knot vector
        as list of floats

    c              3  ó¦   •K  — ‰j                  | «      }|‰z
  }‰‰z   dz   |z
  }‰j                  || d¬«      D ]  }dg|z  |z   dg|z  z   –— Œ y ­w)Nr   ©rf   ry   )Ú	find_spanÚbasis_funcs_derivatives)rK   ÚspanÚfrontÚbackÚbasisr³   r[   rg   s        €€€rP   Únbasisz>global_bspline_interpolation_first_derivatives.<locals>.nbasisõ  sg   øè ø€ Ø�{‰{˜1‹~ˆØ�q‘ˆØ�q‰y˜1‰}˜tÑ#ˆØ×.Ñ.¨t°Q¸!Ð.Ö<ˆEØ�%˜%‘- %Ñ'¨3¨%°$©,Ñ6Ó6ñ =ùs   ƒAAr   r7   rª   rs   ry   r·   r   c              3  ó.   •K  — | ]  } ‰|«      –— Œ y ­wr†   rm   )r{   rK   rÑ   s     €rP   r|   zAglobal_bspline_interpolation_first_derivatives.<locals>.<genexpr>  s   øè ø€ Ð0¡˜A‰f�Q�i¡ùr}   r@   Nc              3  ó2   K  — | ]  }t        |«      –— Œ y ­wr†   rÁ   )r{   Úrows     rP   r|   zAglobal_bspline_interpolation_first_derivatives.<locals>.<genexpr>  s   è ø€ Ð)¡q ”3�s—8¡qùs   ‚zinhomogeneous matrix detectedr•   )rK   rt   )rE   r/   r   r~   r–   ÚsetÚzipr§   r±   r   rD   r²   )rH   ÚderivativesrB   r\   rf   r<   r¦   Úncolsr¾   rÔ   ÚBr²   r´   rJ   r³   r[   rÑ   rg   s                 @@@@rP   r(   r(   Ü  sä  û€ ÷27ð 	€AÜˆJ‹˜!Ñ€AÜ˜˜A˜xÓ(€EÜ�
‹O˜aÑ€EÜ�E  Q¡¨eÔ4€Aà	ˆ��˜ ™Ñ#Ñ#Ø	ˆtˆ˜�u ¨¡	Ñ*Ñ*ð	€Aô ��!‘‹I€EÛ0 ¨!¨B¡Ö0ˆØ	�‰©Ó+© #�#�f�u’+¨Ñ+Õ,ð 1ð ‡H�HˆcˆU�e˜a‘iÑ  D¨$ <Ñ/Ô0Ø‡H�HˆcˆU�e˜a‘iÑ  D 6Ñ)Ô*ÜŒsÑ)¡qÓ)Ó)Ó*¨aÒ/ÐPÐ1PÓPÐ/ð €AÜ�J Ö,ˆØ	�‰��ð -ð �R‘5˜!˜B™%€L€A€b�Eˆ1ˆR‰5ð €aƒDˆE�!�a‘%‰L˜1ÑÑƒDØ€bƒEˆc�E˜A ™E˜(‘OÑ# qÑ(Ñ(ƒEÜ˜a Ó(€FØ×(Ñ(¨Ó+€NÜ�9‰9�^×(Ñ(Ó*Ó+¨UÐ2Ð2ùò' ,s   ÂF,
c                óL  — t        | «      t        |«      k(  sJ ‚t        | «      dkD  sJ ‚d}|dz   }| d   g}d}g }t        t        | «      dz
  «      D ]Ä  }| |   }| |dz      }	||   }
||dz      }d|
|z   j                  z
  }d|	|z
  j                  |
|z   «      z  }d|	|z
  j                  z  }	 t	        j
                  |||«      \  }}|||
z  d	z  z   }|	||z  d	z  z
  }|j                  ||f«       |d	||z
  j                  z  z  }|j                  |«       ŒÆ |j                  | d
   «       dg|z  }|d
   }|dd
 D ]  }||z  }|j                  ||f«       Œ |j                  dgdz  «       t        |«      t        t        |«      |«      k(  sJ ‚||fS # t        $ r Y �ŒPw xY w)aG  Interpolates the control points for a cubic B-spline by local
    interpolation from fit points and tangents as unit vectors for each fit
    point. Use the :func:`estimate_tangents` function to estimate end tangents.

    Source: Piegl & Tiller: "The NURBS Book" - chapter 9.3.4

    Args:
        fit_points: curve definition points - curve has to pass all given fit
            points
        tangents: one tangent vector for each fit point as unit vectors

    Returns:
        2-tuple of control points as list of Vec3 objects and the knot vector
        as list of floats

    r7   rA   r   r   ry   g      0@g      (@g      BÀr”   r@   Nrs   r9   )rE   ru   Úmagnitude_squareÚdotr   Úquadratic_equationrF   r~   Ú	magnituder–   r0   )rH   rC   rB   r;   rJ   r—   ÚparamsÚiÚp0Úp3Út0Út3ÚaÚbÚcÚ
alpha_plusÚalpha_minusÚp1Úp2r<   Úmax_urp   Úknots                          rP   r)   r)     s÷  € ô& ˆz‹?œc (›mÒ+Ð+Ð+Üˆz‹?˜QÒÐÐà€FØ�Q‰J€EØ  ‘m�_€NØ€AØ€FÜ”3�z“? QÑ&Ö'ˆØ˜‰]ˆØ˜˜A™ÑˆØ�a‰[ˆØ�a˜!‘e‰_ˆØ�B˜‘G×-Ñ-Ñ-ˆØ�B˜‘G—=‘=  b¡Ó)Ñ)ˆØ�R˜"‘W×.Ñ.Ñ.ˆð	Ü&,×&?Ñ&?ÀÀ1ÀaÓ&HÑ#ˆJ˜ð �*˜r‘/ CÑ'Ñ'ˆØ�*˜r‘/ CÑ'Ñ'ˆØ×Ñ˜r 2˜hÔ'Ø	ˆS�B˜‘G×&Ñ&Ñ&Ñ&ˆØ�‰�aÕð! (ð" ×Ñ˜* R™.Ô)àˆE�E‰M€EØ�2‰J€EØ�C�R‹[ˆØ�5‰yˆØ�‰�d˜D�\Õ"ð ð 
‡L�L�#�˜‘Ôäˆu‹:Ô-¬c°.Ó.AÀ5ÓIÒIÐIÐIØ˜5Ð Ð øô# ò 	Úð	ús   Â.FÆ	F#Æ"F#c                  ó  — e Zd ZdZdZ	 	 	 d-	 	 	 	 	 	 	 d.d„Zd„ Zed/d„«       Zed0d„«       Z	ed1d„«       Z
ed0d	„«       Zed0d
„«       Zed2d„«       Zed„ «       Zed„ «       Zed3d4d„«       Zed5d6d„«       Zed5d7d„«       Zed8d„«       Zed9d„«       Zed:d„«       Zd:d„Zd;d„Zd;d„Zd<d=d„Zd>d„Zd?d@d„ZdAd„ZdBd„ZdCdDd„ZdCdEd„Z dFd„Z!dFd„Z"dGd „Z#dHd!„Z$dId"„Z%	 dJ	 	 	 	 	 dKd#„Z&dLdMd$„Z'dNd%„Z(d&d'd(d)œ	 	 	 dOd*„Z)dPdQd+„Z*dRd,„Z+y)Sr$   a  B-spline construction tool.

    Internal representation of a `B-spline`_ curve. The default configuration
    of the knot vector is a uniform open `knot`_ vector ("clamped").

    Factory functions:

        - :func:`fit_points_to_cad_cv`
        - :func:`fit_points_to_cubic_bezier`
        - :func:`open_uniform_bspline`
        - :func:`closed_uniform_bspline`
        - :func:`rational_bspline_from_arc`
        - :func:`rational_bspline_from_ellipse`
        - :func:`global_bspline_interpolation`
        - :func:`local_cubic_bspline_interpolation`

    Args:
        control_points: iterable of control points as :class:`Vec3` compatible
            objects
        order: spline order (degree + 1)
        knots: iterable of knot values
        weights: iterable of weight values

    )Ú_control_pointsÚ_basisÚ_clampedNc                ó  — t        j                  |«      | _        t        | j                  «      }t	        |«      }||kD  rt        d|› d|› d|› �«      ‚|€t        ||d¬«      }nKt        |«      }||z   }t        |«      |k7  rt        |› dt        |«      › d�«      ‚|d   d	k7  rt        |«      }t        ||||¬
«      | _
        t        t        |d | «      «      dk(  xr t        t        || d  «      «      dk(  | _        y )Nzgot z control points, need z or more for order of T©rG   z knot values required, got Ú.r   ry   )Úweightsr   )r   Útuplerï   rE   rd   r   r2   rF   rq   r   rð   rÕ   rñ   )ÚselfrJ   r;   r<   rõ   r[   Úrequired_knot_counts          rP   Ú__init__zBSpline.__init__r  s  € ô  $Ÿz™z¨.Ó9ˆÔÜ�D×(Ñ(Ó)ˆÜ�E“
ˆØ�5Š=ÜØ�u�gÐ3°E°7Ð:PÐQVÐPWÐXóð ð ˆ=Ü,¨U°EÀTÔJ‰Eä˜%“LˆEØ"'¨%¡-ÐÜ�5‹zÐ0Ò0Ü Ø*Ð+Ð+FÄsÈ5ÃzÀlÐRSÐTóð ð �Q‰x˜3ŠÜ'¨Ó.�Ü˜E 5¨%¸ÔAˆŒÜœC  f u Ó.Ó/°1Ñ4ÒV¼¼SÀÈÀvÀwÀÓ=PÓ9QÐUVÑ9Vˆ�rQ   c                ó¤   — d| j                   › d| j                  › dt        | j                  «       «      › dt        | j	                  «       «      › d�	S )NzBSpline degree=z, z control points, z knot values, z weights)rB   r[   rE   r<   rõ   ©r÷   s    rP   Ú__str__zBSpline.__str__�  sL   € à˜dŸk™k˜]¨"¨T¯Z©Z¨Lð 9Ü" 4§:¡:£<Ó0Ð1°Ü�4—<‘<“>Ó"Ð# 8ð-ð	
rQ   c                ó   — | j                   S )z4Control points as tuple of :class:`~ezdxf.math.Vec3`)rï   rû   s    rP   rJ   zBSpline.control_points–  s   € ð ×#Ñ#Ð#rQ   c                ó,   — t        | j                  «      S )z7Count of control points, (n + 1 in text book notation).)rE   rï   rû   s    rP   r[   zBSpline.count›  s   € ô �4×'Ñ'Ó(Ð(rQ   c                ó.   — | j                   j                  S )zBiggest `knot`_ value.)rð   Úmax_trû   s    rP   r   zBSpline.max_t   ó   € ð �{‰{× Ñ Ð rQ   c                ó.   — | j                   j                  S )zOrder (k) of B-spline = p + 1)rð   r;   rû   s    rP   r;   zBSpline.order¥  r  rQ   c                ó.   — | j                   j                  S )z"Degree (p) of B-spline = order - 1)rð   rB   rû   s    rP   rB   zBSpline.degreeª  s   € ð �{‰{×!Ñ!Ð!rQ   c                óB   — t        | j                  | j                  «      S r†   )r   rð   rï   rû   s    rP   Ú	evaluatorzBSpline.evaluator¯  s   € ä˜Ÿ™ d×&:Ñ&:Ó;Ð;rQ   c                ó.   — | j                   j                  S )z?Returns ``True`` if curve is a rational B-spline. (has weights))rð   Úis_rationalrû   s    rP   r  zBSpline.is_rational³  s   € ð �{‰{×&Ñ&Ð&rQ   c                ó   — | j                   S )z7Returns ``True`` if curve is a clamped (open) B-spline.)rñ   rû   s    rP   Ú
is_clampedzBSpline.is_clamped¸  s   € ð �}‰}ÐrQ   c                ó   — t        | ||¬«      S )z/Returns :class:`BSpline` defined by fit points.r>   )r   )rI   rB   r?   s      rP   Úfrom_fit_pointszBSpline.from_fit_points½  s   € ô ,¨F°FÀ6ÔJÐJrQ   c                óX   — t        | j                  | j                  |«      «      d¬«      S )zaReturns an ellipse approximation as :class:`BSpline` with `num`
        control points.

        r7   ©rB   )r   Úverticesrß   )ÚellipseÚnums     rP   Úellipse_approximationzBSpline.ellipse_approximationÂ  s*   € ô ,Ø×Ñ˜WŸ^™^¨CÓ0Ó1¸!ô
ð 	
rQ   c                óX   — t        | j                  | j                  |«      «      d¬«      S )z]Returns an arc approximation as :class:`BSpline` with `num`
        control points.

        r7   r  )r   r  Úangles)Úarcr  s     rP   Úarc_approximationzBSpline.arc_approximationÌ  s#   € ô ,¨C¯L©L¸¿¹ÀC»Ó,IÐRSÔTÐTrQ   c                ó   — t        | d¬«      S )zoReturns the ellipse as :class:`BSpline` of 2nd degree with as few
        control points as possible.

        r   ©Úsegments)r    )r  s    rP   Úfrom_ellipsezBSpline.from_ellipseÔ  s   € ô -¨W¸qÔAÐArQ   c                ór   — t        | j                  | j                  | j                  | j                  d¬«      S )zkReturns the arc as :class:`BSpline` of 2nd degree with as few control
        points as possible.

        r   r  )r   ÚcenterÚradiusÚstart_angleÚ	end_angle)r  s    rP   Úfrom_arczBSpline.from_arcÜ  s,   € ô )Ø�J‰J˜Ÿ
™
 C§O¡O°S·]±]ÈQô
ð 	
rQ   c                óp   — t        | j                  | j                  | j                  | j                  ¬«      S )z¾Interface to the `NURBS-Python <https://pypi.org/project/geomdl/>`_
        package.

        Returns a :class:`BSpline` object from a :class:`geomdl.BSpline.Curve`
        object.

        ©rJ   r;   r<   rõ   )r$   Úctrlptsr;   Ú
knotvectorrõ   )Úcurves    rP   Úfrom_nurbs_python_curvezBSpline.from_nurbs_python_curveæ  s/   € ô Ø Ÿ=™=Ø—+‘+Ø×"Ñ"Ø—M‘Mô	
ð 	
rQ   c           	     óÐ   ‡ — ˆ fd„}‰ j                  t        ‰ j                  «      ‰ j                   |«       ‰ j                  rt        ‰ j                  «       «      ¬«      S d¬«      S )zZReturns a new :class:`BSpline` object with reversed control point
        order.

        c               3  ój   •K  — t        t        ‰j                  «       «      «      D ]	  } d| z
  –— Œ y ­w)Nrs   )Úreversedrq   r<   )re   r÷   s    €rP   Úreverse_knotsz&BSpline.reverse.<locals>.reverse_knotsü  s*   øè ø€ Üœo¨d¯j©j«lÓ;Ö<�Ø˜A‘g“ñ =ùs   ƒ03Nr!  )Ú	__class__r(  rJ   r;   r  rõ   )r÷   r)  s   ` rP   ÚreversezBSpline.reverseö  sf   ø€ ô	ð �~‰~Ü# D×$7Ñ$7Ó8Ø—*‘*Ù“/Ø04×0@Ò0@”H˜TŸ\™\›^Ó,ð	 ó 
ð 	
ð GKð	 ó 
ð 	
rQ   c                ó.   — | j                   j                  S )z•Returns a tuple of `knot`_ values as floats, the knot vector
        **always** has order + count values (n + p + 2 in text book notation).

        )rð   r<   rû   s    rP   r<   zBSpline.knots  s   € ð
 �{‰{× Ñ Ð rQ   c                ó.   — | j                   j                  S )zlReturns a tuple of weights values as floats, one for each control
        point or an empty tuple.

        )rð   rõ   rû   s    rP   rõ   zBSpline.weights  s   € ð
 �{‰{×"Ñ"Ð"rQ   c                óV   — | j                   j                  | j                  |«      «      S )ziApproximates curve by vertices as :class:`Vec3` objects, vertices
        count = segments + 1.

        )r  rI   rß   ©r÷   r  s     rP   ÚapproximatezBSpline.approximate  s"   € ð
 �~‰~×$Ñ$ T§[¡[°Ó%:Ó;Ð;rQ   c                ó˜   — | j                  «       }|| j                  dz
     }|| j                     }t        j                  |||dz   «      S )z7Yield evenly spaced parameters for given segment count.r   )r<   r;   r[   r®   Úlinspace)r÷   r  r<   Úlower_boundÚupper_bounds        rP   rß   zBSpline.params  sF   € ð —
‘
“ˆØ˜DŸJ™J¨™NÑ+ˆØ˜DŸJ™JÑ'ˆÜ�{‰{˜;¨°XÀ±\ÓBÐBrQ   c              #  óÎ  ‡‡‡K  — dˆˆˆfd„Š| j                   Št        j                  t        j                  | j	                  «       «      «      }t        j
                  |«      }|d   }‰j                  |«      }|–— |dd D ][  }||z
  |z  }||k  sŒ||z   }	t        j                  |	|«      r|}	‰j                  |	«      }
 ‰||
||	«      E d{  –—†  |	}|
}||k  rŒKŒ] y7 Œ­w)aÙ  Adaptive recursive flattening. The argument `segments` is the
        minimum count of approximation segments between two knots, 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 projected curve point onto the
                segment chord.
            segments: minimum segment count between two knots

        c              3  óæ   •K  — ||z   dz  }‰j                  |«      }	 t        || |«      }|‰k  r|–— y  ‰	| |||«      E d {  –—†   ‰	||||«      E d {  –—†  y # t        $ r d}Y Œ>w xY w7 Œ)7 Œ­w)Ng      à?r   )Úpointr   ÚZeroDivisionError)
ÚsÚeÚstart_tÚend_tÚmid_trÂ   Ú_distÚdistancer  Úsubdivs
          €€€rP   r@  z"BSpline.flattening.<locals>.subdiv1  sŒ   øè ø€ Ø˜u‘_¨Ñ+ˆEØ—‘ Ó&ˆAðÜ.¨q°!°QÓ7�ð �xÒØ“á! ! Q¨°Ó7×7Ð7Ù! ! Q¨¨uÓ5×5Ñ5øô %ò Ø’ðúð
 8øØ5úsE   ƒA1žA «A1ÁA-ÁA1ÁA/ÁA1ÁA*Á'A1Á)A*Á*A1Á/A1r   r   N)r9  r   r:  r   r;  rt   r<  rt   )r  r®   Úuniquer¯   r<   r°   r7  r‚   )r÷   r?  r  r<   Úseg_f64rK   Ústart_pointrš   ÚdeltaÚnext_tÚ	end_pointr  r@  s    `         @@rP   Ú
flatteningzBSpline.flattening$  sÛ   úè ø€ ÷	6ð —N‘Nˆ	Ü—	‘	œ"Ÿ(™( 4§:¡:£<Ó0Ó1ˆÜ—*‘*˜XÓ&ˆØ�!‰HˆØ—o‘o aÓ(ˆØÒØ˜˜“)ˆBØ˜!‘V˜wÑ&ˆEØ�b“&Ø˜U™�Ü—:‘:˜f bÔ)Ø�FØ%ŸO™O¨FÓ3�	Ù! +¨y¸!¸VÓD×DÐDØ�Ø'�ð �b”&ñ ð Eús   …BC%Â<C%ÃC#ÃC%Ã C%c                ó8   — | j                   j                  |«      S )zgReturns point  for parameter `t`.

        Args:
            t: parameter in range [0, max_t]

        )r  r7  ©r÷   rK   s     rP   r7  zBSpline.pointO  s   € ð �~‰~×#Ñ# AÓ&Ð&rQ   c                ó8   — | j                   j                  |«      S )znYields points for parameter vector `t`.

        Args:
            t: parameters in range [0, max_t]

        )r  rI   rI  s     rP   rI   zBSpline.pointsX  s   € ð �~‰~×$Ñ$ QÓ'Ð'rQ   c                ó:   — | j                   j                  ||«      S )a8  Return point and derivatives up to `n` <= degree for parameter `t`.

        e.g. n=1 returns point and 1st derivative.

        Args:
            t: parameter in range [0, max_t]
            n: compute all derivatives up to n <= degree

        Returns:
            n+1 values as :class:`Vec3` objects

        )r  Ú
derivative©r÷   rK   rf   s      rP   rL  zBSpline.derivativea  s   € ð �~‰~×(Ñ(¨¨AÓ.Ð.rQ   c                ó:   — | j                   j                  ||«      S )aQ  Yields points and derivatives up to `n` <= degree for parameter
        vector `t`.

        e.g. n=1 returns point and 1st derivative.

        Args:
            t: parameters in range [0, max_t]
            n: compute all derivatives up to n <= degree

        Returns:
            List of n+1 values as :class:`Vec3` objects

        )r  r×   rM  s      rP   r×   zBSpline.derivativesp  s   € ð �~‰~×)Ñ)¨!¨QÓ/Ð/rQ   c                óD  ‡‡‡‡— | j                   j                  r| j                  ‰«      S t        | j                   j                  «      Št        | j
                  «      Š| j                  Šdˆˆˆˆfd„}‰dk  s‰| j                  k\  rt        d«      ‚| j                   j                  ‰«      }|‰k  rt        d«      ‚t        |‰z
  dz   |dz   «      D �cg c]
  } ||«      ‘Œ c}‰|‰z
  dz   | ‰j                  |dz   ‰«       t        ‰| j                  ‰«      S c c}w )z½Insert an additional knot, without altering the shape of the curve.
        Returns a new :class:`BSpline` object.

        Args:
            t: position of new knot 0 < t < max_t

        c                ó`   •— ‰‰|    z
  ‰| ‰z      ‰|    z
  z  }‰| dz
     d|z
  z  ‰|    |z  z   S ©Nr   rm   )Úindexrå   Úcpointsr<   rg   rK   s     €€€€rP   Ú	new_pointz&BSpline.insert_knot.<locals>.new_point�  sN   ø€ Ø�U˜5‘\Ñ! e¨E°A©IÑ&6¸¸u¹Ñ&EÑFˆAØ˜5 1™9Ñ%¨¨Q©Ñ/°'¸%±.À1Ñ2DÑDÐDrQ   ry   úInvalid position tr   )rR  rd   rÆ   r   )rð   r  Ú_insert_knot_rationalrD   r<   rï   rB   r   r   rË   ru   r¸   r$   r;   )r÷   rK   rT  re   rà   rS  r<   rg   s    `   @@@rP   Úinsert_knotzBSpline.insert_knot€  s	  û€ ð �;‰;×"Ò"Ø×-Ñ-¨aÓ0Ð0ä�T—[‘[×&Ñ&Ó'ˆÜ�t×+Ñ+Ó,ˆØ�K‰Kˆ÷	Eð 	Eð �Š8�q˜DŸJ™J’ÜÐ 4Ó5Ð5à�K‰K×!Ñ! !Ó$ˆØˆqŠ5ÜÐ 4Ó5Ð5ä8=¸aÀ!¹eÀa¹iÈÈQÉÔ8OÓ!PÑ8O°1¡)¨A¥,Ð8OÑ!Pˆ��A‘˜‘	˜AÐØ�‰�Q˜‘U˜AÔÜ�w §
¡
¨EÓ2Ð2ùò "Qs   ÃDc                ód  ‡‡‡	‡
— | j                   j                  st        d«      ‚t        | j                   j                  «      Š	t        | «      Š| j                  Š
dˆˆ	ˆ
ˆfd„}‰dk  s‰| j                  k\  rt        d«      ‚| j                   j                  ‰«      }|‰
k  rt        d«      ‚‰j                  «       }t        |‰
z
  dz   |dz   «      D �cg c]
  } ||«      ‘Œ c}||‰
z
  dz   | t        |«      \  }}‰	j                  |dz   ‰«       t        || j                  ‰	|¬«      S c c}w )z&Knot insertion for rational B-splines.zRequires a rational B-splines.c                ó`   •— ‰‰|    z
  ‰| ‰z      ‰|    z
  z  }‰| dz
     d|z
  z  ‰|    |z  z   S rQ  rm   )rR  rå   Ú	hg_pointsr<   rg   rK   s     €€€€rP   rT  z0BSpline._insert_knot_rational.<locals>.new_point¨  sO   ø€ Ø˜E %™LÑ(¨U°5¸1±9Ñ-=ÀÀeÁÑ-LÑMˆAØ˜U Q™YÑ'¨1¨q©5Ñ1°I¸eÑ4DÀqÑ4HÑHÐHrQ   ry   rU  r   ©r<   rõ   )rR  rd   rÆ   únp.typing.NDArray)rð   r  Ú	TypeErrorrD   r<   Úto_homogeneous_pointsrB   r   r   rË   Útolistru   Úfrom_homogeneous_pointsr¸   r$   r;   )r÷   rK   rT  re   Ú
new_pointsrà   rI   rõ   rZ  r<   rg   s    `      @@@rP   rV  zBSpline._insert_knot_rationalž  s  û€ à�{‰{×&Ò&ÜÐ<Ó=Ð=ä! $§+¡+×"3Ñ"3Ó4ˆä'<¸TÓ'Bˆ	Ø—‘ˆ÷	Ið 	Ið �Š8�q˜DŸJ™J’ÜÐ 4Ó5Ð5à—‘×&Ñ& qÓ)ˆØˆqŠ5ÜÐ 4Ó5Ð5Ø#×*Ñ*Ó,ˆ
Ü;@ÀÀQÁÈÁÈAÐPQÉEÔ;RÓ$SÑ;R°a¡Y¨q¥\Ð;RÑ$Sˆ
�1�q‘5˜1‘9˜qÐ!ä1°*Ó=‰ˆ�Ø�‰�Q˜‘U˜AÔÜ�v˜tŸz™z°ÀÔHÐHùò	 %Ts   ÃD-c                ó:   — | }|D ]  }|j                  |«      }Œ |S )zËInsert multiple knots, without altering the shape of the curve.
        Returns a new :class:`BSpline` object.

        Args:
            u: vector of new knots t and for each t: 0 < t  < max_t

        )rW  )r÷   r—   ÚsplinerK   s       rP   Úknot_refinementzBSpline.knot_refinement¹  s(   € ð ˆÛˆAØ×'Ñ'¨Ó*‰Fð àˆrQ   c                ó    — |j                  | j                  «      }t        || j                  | j	                  «       | j                  «       «      S )zqReturns a new :class:`BSpline` object transformed by a
        :class:`Matrix44` transformation matrix.

        )Útransform_verticesrJ   r$   r;   r<   rõ   )r÷   rÂ   rS  s      rP   Ú	transformzBSpline.transformÆ  s;   € ð
 ×&Ñ& t×':Ñ':Ó;ˆÜ�w §
¡
¨D¯J©J«L¸$¿,¹,».ÓIÐIrQ   c              #  óð  K  — | j                   j                  rt        d«      ‚| j                  st        d«      ‚| j                  dz
  }| j
                  }| j                   j                  }| j                  }dgt        |«      z  }||z   dz   }|}|dz   }t        |d|dz    «      }	||k  �rHt        g|dz   z  }
|}||k  rIt        j                  ||dz      ||   «      r*|dz  }||k  r t        j                  ||dz      ||   «      rŒ*||z
  dz   }||k  rŸ||   ||   z
  }t        ||d«      D ]  }||||z      ||   z
  z  |||z
  dz
  <   Œ ||z
  }t        d|dz   «      D ]Q  }||z
  }||z   }t        ||dz
  d«      D ]$  }|||z
     }|	|   |z  |	|dz
     d|z
  z  z   |	|<   Œ& ||k  sŒJ|	|   |
|<   ŒS |	–— ||k  r.t        ||z
  |dz   «      D ]  }|||z
  |z      |
|<   Œ |}|dz  }|
}	||k  r�ŒGyy­w)	uå  Decompose a non-rational B-spline into multiple BÃ©zier curves.

        This is the preferred method to represent the most common non-rational
        B-splines of 3rd degree by cubic BÃ©zier curves, which are often supported
        by render backends.

        Returns:
            Yields control points of BÃ©zier curves, each BÃ©zier segment
            has degree+1 control points e.g. B-spline of 3rd degree yields
            cubic BÃ©zier curves of 4 control points.

        z!Rational B-splines not supported.zClamped B-Spline required.r   ry   r   r@   rs   N)rð   r  r]  r	  r[   rB   r<   rï   rE   rD   r   r�   r‚   ru   )r÷   rf   rg   r<   rJ   ÚalphasrÂ   rå   ræ   Úbezier_pointsÚnext_bezier_pointsrà   ÚmultÚnumerrŠ   ÚrÚsaver9  re   Úalphas                       rP   Úbezier_decompositionzBSpline.bezier_decompositionÎ  sj  è ø€ ð �;‰;×"Ò"ÜÐ?Ó@Ð@Ø�ŠÜÐ8Ó9Ð9à�J‰J˜‰NˆØ�K‰KˆØ—‘×!Ñ!ˆØ×-Ñ-ˆØ�œ˜U›Ñ#ˆà�‰E�A‰IˆØˆØ�‰EˆÜ˜^¨A°°A±Ð6Ó7ˆà�!‹eÜ") ¨a°!©eÑ!4ÐØˆAØ�a’%œDŸL™L¨¨q°1©u©°u¸Q±xÔ@Ø�Q‘�ð �a’%œDŸL™L¨¨q°1©u©°u¸Q±xÕ@à�q‘5˜1‘9ˆDØ�aŠxØ˜a™ 5¨¡8Ñ+�Ü˜q $¨Ö+�AØ+0°E¸!¸a¹%±LÀ5ÈÁ8Ñ4KÑ+L�F˜1˜t™8 a™<Ò(ð ,à˜‘H�Ü˜q ! a¡%ž�AØ˜q™5�DØ˜q™�AÜ" 1 a¨!¡e¨RÖ0˜Ø & q¨1¡u¡˜Ø+8¸Ñ+;¸eÑ+CÀmØ ™EñGà  5™[ñG*ñ ,*˜ aÒ(ð 1ð
 ˜1“uØ3@ÀÑ3CÐ*¨4Ò0ð )ð  Òà�1ŠuÜ˜q 4™x¨¨Q©Ö/�AØ,:¸1¸q¹5À1¹9Ñ,EÐ& qÒ)ð 0à�Ø�Q‘�Ø 2�ð9 �!Žeùs   ‚DG6Ä
B!G6Æ,AG6Ç4G6c                óª   — |€*t        | j                  | j                  |«      «      «      }nt        | j                  |«      «      }ddlm}  ||«      S )uá  Approximate arbitrary B-splines (degree != 3 and/or rational) by
        multiple segments of cubic BÃ©zier curves. The choice of cubic BÃ©zier
        curves is based on the widely support of this curves by many render
        backends. For cubic non-rational B-splines, which is maybe the most
        common used B-spline, is :meth:`bezier_decomposition` the better choice.

        1. approximation by `level`: an educated guess, the first level of
           approximation segments is based on the count of control points
           and their distribution along the B-spline, every additional level
           is a subdivision of the previous level.

        E.g. a B-Spline of 8 control points has 7 segments at the first level,
        14 at the 2nd level and 28 at the 3rd level, a level >= 3 is recommended.

        2. approximation by a given count of evenly distributed approximation
           segments.

        Args:
            level: subdivision level of approximation segments (ignored if
                argument `segments` is not ``None``)
            segments: absolute count of approximation segments

        Returns:
            Yields control points of cubic BÃ©zier curves as :class:`Bezier4P`
            objects

        r   )rS   )rD   rI   Úapproximation_paramsr0  Úbezier_interpolationrS   )r÷   Úlevelr  rI   rS   s        rP   Úcubic_bezier_approximationz"BSpline.cubic_bezier_approximation
  sK   € ð< ÐÜ˜$Ÿ+™+ d×&?Ñ&?ÀÓ&FÓGÓH‰Fä˜$×*Ñ*¨8Ó4Ó5ˆFÝDá)¨&Ó1Ð1rQ   c                ó  — t        t        | j                  d«      «      }t        |«      dk(  r|S | j                  dk7  r| j                  }|D �cg c]  }||z  ‘Œ	 }}t        |dz
  «      D ]  }t        t        |«      «      }Œ |S c c}w )a}  Returns an educated guess, the first level of approximation
        segments is based on the count of control points and their distribution
        along the B-spline, every additional level is a subdivision of the
        previous level.

        E.g. a B-Spline of 8 control points has 7 segments at the first level,
        14 at the 2nd level and 28 at the 3rd level.

        r=   r   rs   r   )rD   r   rï   rE   r   ru   Úsubdivide_params)r÷   ru  rß   r   rg   Ú_s         rP   rs  zBSpline.approximation_params0  s†   € ô ”o d×&:Ñ&:¸GÓDÓEˆÜˆv‹;˜!ÒØˆMØ�:‰:˜ÒØ—J‘JˆEÙ)/Ó0© A�a˜%“i¨ˆFÐ0Ü�u˜q‘yÖ!ˆAÜÔ*¨6Ó2Ó3‰Fð "àˆùò 1s   ÁBc                ó   — t        | |«      S )a/  Returns a new :class:`BSpline` with a t-times elevated degree.

        Degree elevation increases the degree of a curve without changing the shape of the
        curve. This method implements the algorithm A5.9 of the "The NURBS Book" by
        Piegl & Tiller.

        .. versionadded:: 1.4

        )Údegree_elevationrI  s     rP   r{  zBSpline.degree_elevationD  s   € ô    aÓ(Ð(rQ   ç:Œ0âŽyE>éd   é   ©ÚepsilonÚmax_iterationsÚinitc               ó4   — t        | t        |«      |||¬«      S )aO  Returns the parameter t for a point on the curve that is closest to the input
        point.

        This is an iterative search using Newton's method, so there is no guarantee
        of success, especially for splines with many turns.

        Args:
            point(UVec): point on the curve or near the curve
            epsilon(float): desired precision (distance input point to point on curve)
            max_iterations(int): max iterations for Newton's method
            init(int): number of points to calculate in the initialization phase

        .. versionadded:: 1.4

        r  )Úpoint_inversionr   )r÷   r7  r€  r�  r‚  s        rP   r„  zBSpline.point_inversionP  s!   € ô$ Ø”$�u“+ w¸~ÐTXô
ð 	
rQ   c                ó   — t        | |«      S )zßReturns a B-spline measurement tool.

        All measurements are based on the approximated curve.

        Args:
            segments: count of segments for B-spline approximation.

        .. versionadded:: 1.4

        )ÚMeasurementr/  s     rP   ÚmeasurezBSpline.measuref  s   € ô ˜4 Ó*Ð*rQ   c                ó   — t        | |«      S )z³Splits the B-spline at parameter `t` and returns two new B-splines.

        Raises:
            ValuerError: t out of range 0 < t < max_t

        .. versionadded:: 1.4

        )Úsplit_bsplinerI  s     rP   ÚsplitzBSpline.splits  s   € ô ˜T 1Ó%Ð%rQ   )r9   NN)rJ   úIterable[UVec]r;   rd   r<   úOptional[Iterable[float]]rõ   rŒ  )rÆ   zSequence[Vec3])rÆ   rd   ©rÆ   rt   )rÆ   r   )rA   r=   )rI   r‹  rÆ   r$   )é   )r  r   r  rd   rÆ   r$   )r  r   r  rd   rÆ   r$   )r  r   rÆ   r$   )r  r   rÆ   r$   )rÆ   r$   )rÆ   úSequence[float])rœ   )r  rd   rÆ   úIterable[Vec3])r  rd   rÆ   úIterable[float])r9   )r?  rt   r  rd   rÆ   zIterator[Vec3])rK   rt   rÆ   r   )rK   r‘  rÆ   r�  )r7   )rK   rt   rf   rd   rÆ   ú
list[Vec3])rK   r‘  rf   rd   rÆ   úIterable[list[Vec3]])rK   rt   rÆ   r$   )r—   r‘  rÆ   r$   )rÂ   r   rÆ   r$   )rÆ   r“  )rA   N)ru  rd   r  zOptional[int]rÆ   zIterable[Bezier4P])rA   )ru  rd   rÆ   r�  )rK   rd   rÆ   r$   )r7  r   rÆ   rt   )r}  )r  rd   rÆ   r†  )rK   rt   rÆ   útuple[BSpline, BSpline]),Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__rù   rü   ÚpropertyrJ   r[   r   r;   rB   r  r  r	  Ústaticmethodr  r  r  r  r  r%  r+  r<   rõ   r0  rß   rG  r7  rI   rL  r×   rW  rV  rd  rg  rq  rv  rs  r{  r„  r‡  rŠ  rm   rQ   rP   r$   r$   V  s  „ ñð2 :€Ið
 Ø+/Ø-1ðWà&ðWð ðWð )ð	Wð
 +óWò:
ð ò$ó ð$ð ò)ó ð)ð ò!ó ð!ð ò!ó ð!ð ò"ó ð"ð ò<ó ð<ð ñ'ó ð'ð ñó ðð óKó ðKð ó
ó ð
ð óUó ðUð òBó ðBð ò
ó ð
ð ò
ó ð
ó
ó"!ó#ô<óCô)(óV'ó(ô/ô0ó 3ó<Ió6óJó:3ðz 9=ð$2Øð$2Ø(5ð$2à	ó$2ôLó(
)ð '+¸3ÀQñ
Øð
à	ó
ô,+ô
&rQ   c              #  ó†   K  — t        t        | «      dz
  «      D ]  }| |   –— | |   | |dz      z   dz  –— Œ | d   –— y ­w)Nr   r“   r@   )ru   rE   )rg   rà   s     rP   rx  rx  €  sL   è ø€ Ü”3�q“6˜A‘:ÖˆØ�‰dŠ
Ø�‰t�a˜˜A™‘h‰ #Ñ%Ó%ð ð ˆB‰%ƒKùs   ‚?Ac                óx   — t        j                  | «      }t        t        |«      |d¬«      }t	        | |||¬«      S )ak  Creates an open uniform (periodic) `B-spline`_ curve (`open curve`_).

    This is an unclamped curve, which means the curve passes none of the
    control points.

    Args:
        control_points: iterable of control points as :class:`Vec3` compatible
            objects
        order: spline order (degree + 1)
        weights: iterable of weight values

    Fró   )r;   r<   rõ   )r   rö   r1   rE   r$   )rJ   r;   rõ   rï   r<   s        rP   r"   r"   ‡  s6   € ô" —j‘j Ó0€OÜ¤ OÓ 4°eÀuÔM€EÜ�>¨°eÀWÔMÐMrQ   c                ó¼   — t        j                  | «      }|j                  |d|dz
   «       |�"t        |«      }|j                  |d|dz
   «       t        |||«      S )aJ  Creates a closed uniform (periodic) `B-spline`_ curve (`open curve`_).

    This B-spline does not pass any of the control points.

    Args:
        control_points: iterable of control points as :class:`Vec3` compatible
            objects
        order: spline order (degree + 1)
        weights: iterable of weight values

    Nr   )r   rD   r~   r"   )rJ   r;   rõ   rï   s       rP   r#   r#   �  s`   € ô  —i‘i Ó/€OØ×Ñ˜?¨;¨U°Q©YÐ7Ô8ØÐÜ�w“-ˆØ�‰�w˜{ ¨¡Ð+Ô,Ü °¸Ó@Ð@rQ   c                óú   ‡ ‡— t        ‰ «      Š t        ‰«      Št        j                  |dz  «      }|t        j                  t	        ||«      «      z   }t        |||«      \  }}}	t        ˆ ˆfd„|D «       ||	d¬«      S )aƒ  Returns a rational B-splines for a circular 2D arc.

    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 spline segments, at least one segment for each
            quarter (90 deg), default is 1, for as few as needed.

    éh  c              3  ó.   •K  — | ]  }‰|‰z  z   –— Œ y ­wr†   rm   )r{   rg   r  r  s     €€rP   r|   z,rational_bspline_from_arc.<locals>.<genexpr>Î  s   øè ø€ ÐF±~°!˜ ! f¡*Õ-±~ùr}   rA   ©rJ   rõ   r<   r;   )r   rt   r�   Úradiansr   Únurbs_arc_parametersr$   )
r  r  r  r  r  Ú	start_radÚend_radrJ   rõ   r<   s
   ``        rP   r   r   µ  sx   ù€ ô$ �&‹\€FÜ�6‹]€Fä—‘˜[¨3Ñ.Ó/€IØœ$Ÿ,™,Ô'9¸+ÀyÓ'QÓRÑR€GÜ%9¸)ÀWÈhÓ%WÑ"€N�G˜UÜÜF±~ÓFØØØô	ð rQ   r“   c                ó¶   ‡ ‡— ‰ j                   t        j                  z  }|‰ j                  z   }dˆˆ fd„}t	        |||«      \  Š}}t         |«       ||d¬«      S )u/  Returns a rational B-splines for an elliptic arc.

    Args:
        ellipse: ellipse parameters as :class:`~ezdxf.math.ConstructionEllipse`
            object
        segments: count of spline segments, at least one segment for each
            quarter (Ï€/2), default is 1, for as few as needed.

    c               3  ó¾   •K  — t        ‰j                  «      } ‰j                  }‰j                  }‰D ]&  }| ||j                  z  z   ||j
                  z  z   –— Œ( y ­wr†   )r   r  Ú
major_axisÚ
minor_axisÚxÚy)r  Úx_axisÚy_axisrg   rJ   r  s       €€rP   Útransform_control_pointsz?rational_bspline_from_ellipse.<locals>.transform_control_pointsç  sU   øè ø€ Ü�g—n‘nÓ%ˆØ×#Ñ#ˆØ×#Ñ#ˆÛˆAØ˜6 A§C¡C™<Ñ'¨&°1·3±3©,Ñ6Ó6ñ  ùs   ƒAArA   r¢  )rÆ   r�  )Ústart_paramr�   ÚtauÚ
param_spanr¤  r$   )r  r  r  r  r¯  rõ   r<   rJ   s   `      @rP   r    r    Ø  sf   ù€ ð ×%Ñ%¬¯©Ñ0€KØ˜g×0Ñ0Ñ0€Iö7ô &:Ø�Y ó&Ñ"€N�G˜Uô Ù/Ó1ØØØô	ð rQ   c           	     óð  — |dk  rt        d«      ‚|| z
  }t        t        j                  |t        z  «      |«      }||z  }|dz  }t        j
                  |«      }t        t        j
                  | «      t        j                  | «      «      g}dg}	| }
dt        j
                  |dz  «      z  }t        |«      D ]¶  }|
|z  }
|j                  t        t        j
                  |
«      |z  t        j                  |
«      |z  «      «       |	j                  |«       |
|z  }
|j                  t        t        j
                  |
«      t        j                  |
«      «      «       |	j                  d«       Œ¸ g d¢}dt        t        |«      dz   d«      dz
  dz  dz   z  }|}|dk  r|j                  ||f«       ||z  }|dk  rŒ|j                  dgt        t        |«      d«      t        |«      z
  z  «       ||	|fS )	uU  Returns a rational B-spline parameters for a circular 2D arc with center
    at (0, 0) and a radius of 1.

    Args:
        start_angle: start angle in radians
        end_angle: end angle in radians
        segments: count of segments, at least one segment for each quarter (Ï€/2)

    Returns:
        control_points, weights, knots

    r   z!Invalid argument segments (>= 1).r7   rs   r“   )ry   ry   ry   r9   rA   )rF   rj   r�   ÚceilÚPI_2Úcosr   Úsinru   r–   rE   r~   r0   )r  r  r  Údelta_angleÚ	arc_countÚsegment_angleÚsegment_angle_2Ú
arc_weightrJ   rõ   ÚangleÚdry  r<   ÚstepÚgs                   rP   r¤  r¤  ù  sÌ  € ð �!‚|ÜÐ<Ó=Ð=Ø˜kÑ)€KÜ”D—I‘I˜k¬DÑ0Ó1°8Ó<€Ià )Ñ+€MØ# aÑ'€OÜ—‘˜/Ó*€Jô œ4Ÿ8™8 KÓ0´$·(±(¸;Ó2GÓHÐI€NØˆe€Gà€EØŒd�h‰h�} sÑ*Ó+Ñ+€AÜ�9Öˆà�Ñ ˆØ×Ñœd¤4§8¡8¨E£?°QÑ#6¼¿¹À»È!Ñ8KÓLÔMØ�‰�zÔ"ð 	�Ñ ˆØ×Ñœd¤4§8¡8¨E£?´D·H±H¸U³OÓDÔEØ�‰�sÕð ò €EØ”3”s˜>Ó*¨QÑ.°Ó2°QÑ6¸#Ñ=ÀÑCÑD€DØ€AØ
ˆcŠ'Ø�‰�a˜�VÔØ	ˆT‰	ˆð ˆc‹'ð 
‡L�L�#�Ô.¬s°>Ó/BÀAÓFÌÈUËÑSÑTÔUà˜7 EÐ)Ð)rQ   c                ól   ‡ ‡‡‡— i Št        ‰ «      Š dˆˆˆˆ fd„Š ‰t        |«      t        |«      «      S )aC  B-spline basis_vector function.

    Simple recursive implementation for testing and comparison.

    Args:
        u: curve parameter in range [0, max(knots)]
        index: index of control point
        degree: degree of B-spline
        knots: knots vector

    Returns:
        float: basis_vector value N_i,p(u)

    c                óV  •— 	 ‰| |f   S # t         $ r• |dk(  r‰|    ‰	cxk  r‰| dz      k  rn ndnd}nh‰| |z      ‰|    z
  }|r‰	‰|    z
  |z   ‰| |dz
  «      z  nd}‰| |z   dz      ‰| dz      z
  }|r!‰| |z   dz      ‰	z
  |z   ‰| dz   |dz
  «      z  nd}||z   }|‰| |f<   |cY S w xY w)Nr   r   ry   )ÚKeyError)
rà   rg   ÚretvalÚ	dominatorÚf1Úf2r³   Úcacher<   r—   s
         €€€€rP   r³   zbspline_basis.<locals>.NA  sÿ   ø€ ð	Ø˜!˜Q˜‘=Ð øÜò 	Ø�AŠvØ# A™h¨!Ô:¨e°A¸±E©lÕ:™À‘à! ! a¡%™L¨5°©8Ñ3�	ÙAJ�a˜% ™(‘l iÑ/±!°A°q¸1±u³+Ò=ÐPS�à! ! a¡%¨!¡)Ñ,¨u°Q¸±U©|Ñ;�	ñ !ð ˜1˜q™5 1™9Ñ%¨Ñ)¨YÑ6¹¸1¸q¹5À!ÀaÁ%»ÒHàð ð ˜b™�Ø"ˆE�1�a�&‰MØŠMð!	ús   ƒ
 ŠBB(Â'B()rà   rd   rg   rd   rÆ   rt   )rt   rd   )r—   rR  rB   r<   r³   rÈ  s   `  `@@rP   Úbspline_basisrÉ  /  s4   û€ ð +-€EÜˆa‹€A÷ð ñ* ŒS�‹Zœ˜V›Ó%Ð%rQ   c           	     óÀ   — t        |«      ||z   dz   k(  sJ ‚t        |«      D �cg c]  }t        | |||«      ‘Œ }}t        j                  | |d   «      rd|d<   |S c c}w )a  Create basis_vector vector at parameter u.

    Used with the bspline_basis() for testing and comparison.

    Args:
        u: curve parameter in range [0, max(knots)]
        count: control point count (n + 1)
        degree: degree of B-spline (order = degree + 1)
        knots: knot vector

    Returns:
        list[float]: basis_vector vector, len(basis_vector) == count

    r   r@   rs   )rE   ru   rÉ  r�   r‚   )r—   r[   rB   r<   rR  rÐ   s         rP   Úbspline_basis_vectorrË  Y  sq   € ô" ˆu‹:˜% &™.¨1Ñ,Ò-Ð-Ð-ä<AÀ%¼LóÙ<H°5Œ�a˜ ¨Õ.¸Lð 
ð ô ‡|�|�A�u˜R‘yÔ!Øˆˆb‰	Ø€Lùòs   ¤Ac           	     ó´  — t        |«      }|dk  r| S | j                  }| j                  rd}t        | «      }n!d}t	        j
                  | j                  «      }t	        j
                  | j                  «       «      }t        |«      dz
  }||z   dz   }||z   }|dz  }	t	        j                  t        |«      d|z   z  |f¬«      }
t	        j                  |d|z   z  «      }t	        j                  ||z   dz   |dz   f¬«      }t	        j                  |dz   |f¬«      }t	        j                  ||z   dz   |f¬«      }t	        j                  |dz
  |f¬«      }t	        j                  |dz
  «      }d|d<   d|||f<   t        j                  }t        d|	dz   «      D ]Y  }d |||«      z  }t        ||«      }t        t        d||z
  «      |dz   «      D ]   }| |||«      z   ||||z
  «      z  |||f<   Œ" Œ[ t        |	dz   |«      D ]A  }t        ||«      }t        t        d||z
  «      |dz   «      D ]  }|||z
  ||z
  f   |||f<   Œ ŒC |}|dz   }d	}|}|dz   }d}|d   }|d   |
d<   ||d
|dz    |d
|dz    |d
|dz    ||k  �rà|}||k  rIt        j                   ||   ||dz      «      r*|dz  }||k  r t        j                   ||   ||dz      «      rŒ*||z
  dz   }||z   |z   }||   }|}||z
  }|dkD  r	|dz   dz  } nd} |dkD  r||dz   dz  z
  }!n|}!|dkD  r�||z
  }"t        ||d	«      D ]  }#|"|||#z      |z
  z  ||#|z
  dz
  <   Œ t        d|dz   «      D ]O  }||z
  }$||z   }%t        ||%dz
  d	«      D ](  }#||#|%z
     ||#   z  d||#|%z
     z
  ||#dz
     z  z   ||#<   Œ* ||   ||$<   ŒQ t        | |dz   «      D ]J  }d||<   t        ||«      }t        t        d||z
  «      |dz   «      D ]  }||   |||f   ||   z  z   ||<   Œ ŒL |dkD  rç|dz
  }&|}'||z
  }(|||dz
     z
  |(z  })t        d|«      D ]¾  }*|&}|'}||z
  dz   }+||z
  |*kD  rž||k  r+|||   z
  |||   z
  z  },|,|
|   z  d|,z
  |
|dz
     z  z   |
|<   || k\  rQ||*z
  ||z
  |z   k  r)||||*z
     z
  |(z  }-|-||+   z  d|-z
  ||+dz      z  z   ||+<   n|)||+   z  d|)z
  ||+dz      z  z   ||+<   |dz  }|dz  }|+dz  }+||z
  |*kD  rŒž|&dz  }&|'dz  }'ŒÀ ||k7  r||z
  }|||||z    ||z  }t        | |!dz   «      D ]  }||   |
|<   |dz  }Œ ||k  r&|d
| |d
| |||z
  |z   |dz    |||dz    |}|dz  }|}n|||||z   dz    ||k  r�Œà||z
  dz
  }.|.dz   }/|dz   }0d
}1|
d
|/…d
d…f   }2|dk(  r:|
d
|/…df   }1t#        |2|1«      D ��3cg c]
  \  }}3||3z  ‘Œ }2}}3|1j%                  «       }1t'        |2|0|1|d
|/|0z    ¬«      S c c}3}w )a  Returns a new :class:`BSpline` with a t-times elevated degree.

    Degree elevation increases the degree of a curve without changing the shape of the
    curve. This function implements the algorithm A5.9 of the "The NURBS Book" by
    Piegl & Tiller.

    .. versionadded:: 1.4

    r   r9   rA   r7   )Úshapers   ©r   r   r   r@   Nry   )r;   rõ   r<   )rd   rB   r  r^  r®   r¯   rJ   r<   rE   Úzerosr   Úbinomial_coefficientru   Úminrj   r�   r‚   rÖ   r_  r$   )4rc  rK   rg   ÚdimÚPwÚUrf   rÂ   ÚphÚph2ÚQwÚUhÚbezalfsÚbptsÚebptsÚNextbptsÚalfsÚbinomrà   ÚinvÚmpirŠ   ÚmhÚkindrn  rå   ræ   ÚcindÚuaÚmulÚubÚoldrÚlbzÚrbzrm  re   ro  r9  ÚfirstÚlastÚdenÚbetÚtrÚkjÚalfÚgamÚnhÚ
count_cptsr;   rõ   rS  Úws4                                                       rP   r{  r{  t  s—  € ô 	ˆA‹€AØˆ1‚uØˆØ�‰€Aà×ÒàˆÜ" 6Ó*‰ð ˆÜ�X‰X�f×+Ñ+Ó,ˆô 	�‰�—‘“Ó €Aô 	ˆB‹�!‰€AØ	ˆA‰�‰	€AØ	
ˆQ‰€BØ
�‰'€Cô 
�‰œ˜R› A¨¡EÑ*¨CÐ0Ô	1€Bô 
�‰�!�q˜1‘u‘+Ó	€Bô �h‰h˜a !™e a™i¨¨Q©Ð/Ô0€Gô �8‰8˜1˜q™5 #˜,Ô'€Dô �H‰H˜A ™E A™I sÐ+Ô,€Eô �x‰x˜q 1™u c˜lÔ+€Hô �8‰8�A˜‘E‹?€DØ€GˆD�MØ€GˆB�ˆE�NÜ×'Ñ'€EÜ�1�c˜A‘gÖˆØ‘E˜"˜a“LÑ ˆÜ�!�Q‹iˆÜ”s˜1˜a !™e“} c¨A¡gÖ.ˆAØ¡%¨¨1£+Ñ-±°a¸¸Q¹³Ñ?ˆG�A�q�DŠMñ /ð ô
 �3˜‘7˜BÖˆÜ�!�Q‹iˆÜ”s˜1˜a !™e“} c¨A¡gÖ.ˆAØ# B¨¡F¨A°©E MÑ2ˆG�A�q�DŠMñ /ð  ð 
€BØ�‰6€DØ
€AØ	€AØ	ˆA‰€AØ€DØ	
ˆ1‰€BØˆq‰E€B€q�Eð €B€xˆˆa‰€Lð
 �w˜˜Q™�K€Dˆˆ1ˆq‰5€Mà
ˆa‹%ØˆØ�1Šuœ4Ÿ<™<¨¨!©¨a°°A±©hÔ7Ø�‰FˆAð �1Šuœ4Ÿ<™<¨¨!©¨a°°A±©hÕ7à�!‰e�a‰iˆØ�#‰X˜‰\ˆØˆq‰TˆØˆØ�‰Gˆà�!Š8Ø˜!‘8 ‘/‰CàˆCØˆqŠ5Ø˜˜A™ !‘|Ñ#‰CàˆCØˆqŠ5à˜‘GˆEÜ˜1˜c 2Ö&�Ø$)¨Q¨q°1©u©X¸©]Ñ$;��Q˜‘W˜q‘[Ò!ð 'ä˜1˜a !™e–_�Ø˜1‘u�Ø˜!‘G�Ü˜q ! a¡%¨Ö,�AØ" 1 q¡5™k¨D°©GÑ3°s¸TÀ!ÀaÁ%¹[Ñ7HÈDÐQRÐUVÑQVÉKÑ6WÑW�D˜’Gð -à!% a¡�˜’ð %ô �s˜B ™FÖ#ˆAð ˆE�!‰HÜ�a˜“)ˆCÜœ3˜q ! a¡%›=¨#°©'Ö2�Ø  ™8 g¨a°¨d¡m°d¸1±gÑ&=Ñ=��a’ñ 3ð $ð �!Š8à˜1‘HˆEØˆDØ�r‘'ˆCØ˜˜4 !™8™Ñ$¨Ñ+ˆCÜ˜A˜t–n�à�Ø�Ø˜‘X ‘\�Ø˜!‘e˜b’jà˜4’xØ! B q¡E™z¨b°2°a±5©jÑ9˜Ø # b¨¡e¡¨s°S©y¸B¸qÀ1¹u¹IÑ.EÑ E˜˜1™Ø˜C’xØ˜r™6 T¨B¡Y°Ñ%5Ò5Ø#%¨¨1¨r©6©
¡?°cÑ"9˜CØ(+¨e°B©i©¸3À¹9ÈÈbÐSTÉfÉÑ:UÑ(U˜E "šIà(+¨e°B©i©¸3À¹9ÈÈbÐSTÉfÉÑ:UÑ(U˜E "™IØ˜‘F�AØ˜‘F�AØ˜!‘G�Bð ˜!‘e˜b“jð ˜‘
�Ø˜‘	‘ð) %ð, �Š6ð �T‘	ˆAØ"$ˆBˆt�d˜Q‘hÐØ�A‰IˆDÜ�s˜C !™GÖ$ˆAà˜Q‘xˆBˆt‰HØ�A‰I‰Dð %ð ˆqŠ5ð    �|ˆD��!ˆHð !  Q¡¨¡¨Q°©UÐ3ˆD��Q˜‘UˆOØˆAØ�‰FˆAØ‰Bð (*ˆBˆt�d˜R‘i !‘mÐ$ðw ˆaŒ%ðz 
ˆb‰�1‰€BØ�a‘€JØ�‰F€Eà€GØ��*�˜b˜q˜b�Ñ!€GØ
ˆa‚xà�[�j�[ !�^Ñ$ˆÜ%(¨°'Ô%:Ô;Ñ%:™T˜Q �1�q“5Ð%:ˆÑ;à—.‘.Ó"ˆÜØ�u g°RÐ8L¸*ÀuÑ:LÐ5Môð ùó <s   ÖWc           
     ó–  — t        j                  | j                  «       t         j                  ¬«      }t	        |«      st        j
                  | j                  «      }t        j                  t        | j                  |«      D ��cg c]2  \  }}|j                  |z  |j                  |z  |j                  |z  |f‘Œ4 c}}«      S c c}}w )Nr«   )r®   r¯   rõ   r°   rE   Úonesr[   rÖ   rJ   r«  r¬  Úz)rc  rõ   rp   rô  s       rP   r^  r^  8  s�   € Ü�h‰h�v—~‘~Ó'¬r¯z©zÔ:€GÜˆwŒ<Ü—'‘'˜&Ÿ,™,Ó'ˆä�8‰8Ü47¸×8MÑ8MÈwÔ4WÔXÑ4W©D¨A¨qˆ!�#‰#�‰'�1—3‘3˜‘7˜AŸC™C !™G QÒ	'Ð4WÒXóð ùÛXs   Â7C
c                óž   — g }g }| D ]A  }t        |d   «      }|j                  t        |d d «      |z  «       |j                  |«       ŒC ||fS )NrA   )rt   r–   r   )rZ  rI   rõ   r7  rô  s        rP   r`  r`  B  sX   € ð €FØ€GÛˆÜ�%˜‘(‹OˆØ�‰”d˜5  !˜9“o¨Ñ)Ô*Ø�‰�qÕð ð �7ˆ?ÐrQ   r|  r}  r~  r  c               óP  — | j                   }t        d«      }|dz  }t        j                  d||d¬«      }t	        | j                  |«      «      }	t        ||	«      D ])  \  }
}|j                  |«      }||k  sŒt        |
«      }|}Œ+ d}t        |«      D ]Ž  }| j                  |d¬«      \  }}||z
  }|j                  }||k  r |S t        j                  ||«      r|dz  }|dkD  r |S d}|}||j                  |«      |j                  |«      z  z  }|dk  rd}Œ‡||kD  sŒ�|}Œ� |S )	aF  Returns the parameter t for a point on the curve that is closest to the input
    point.

    This is an iterative search using Newton's method, so there is no guarantee
    of success, especially for splines with many turns.

    Args:
        spline(BSpline): curve
        point(Vec3): point on the curve or near the curve
        epsilon(float): desired precision (distance input point to point on curve)
        max_iterations(int): max iterations for Newton's method
        init(int): number of points to calculate in the initialization phase

    .. versionadded:: 1.4

    Úinfr7   r   T©Úendpointr   rÊ   ry   )r   rt   r®   r2  rD   rI   rÖ   r?  ru   rL  rÞ   r�   r‚   rÜ   )rc  r7  r€  r�  r‚  r   Úprev_distancer—   rK   Ú
chk_pointsr™   rg   r?  Úno_progress_counterÚ	iterationÚdpduÚdiffs                    rP   r„  r„  N  sU  € ð& �L‰L€EÜ˜%“L€MØ�‰	€Aô 	�‰�A�u˜d¨TÔ2€AÜ�f—m‘m AÓ&Ó'€JÜ�Q˜
Ö#‰ˆˆAØ—>‘> !Ó$ˆØ�mÓ#Ü�b“	ˆAØ$‰Mð	 $ð  !ÐÜ˜>Ö*ˆ	à×#Ñ# A¨Ð#Ó+‰ˆˆ4ð �5‰yˆð —>‘>ˆØ�gÒØð" €Hô! �<‰<˜ xÔ0Ø 1Ñ$ÐØ" QÒ&Øð €Hð #$ÐØ ˆð 	
ˆT�X‰X�d‹^˜dŸh™h t›nÑ,Ñ,ˆð ˆsŠ7Ø‰AØ�‹YØ‰Að5 +ð6 €HrQ   c                  óT   — e Zd ZdZd	d„Zed
d„«       Zedd„«       Zdd„Z	dd„Z
dd„Zy)r†  zvB-spline measurement tool.

    All measurements are based on the approximated curve.

    .. versionadded:: 1.4

    c                ó  — t        |t        «      st        dt        |«      › �«      ‚t	        |«      }|dk  rt        d|› �«      ‚|| _        t        j                  d|j                  |dz   d¬«      | _
        t        | j                  j                  | j                  «      «      }t        |«      }|j                  | _        |j                  | _        | j!                  |«      | _        t        j$                  | j"                  «      | _        y )NzBSpline instance expected, got r   zinvalid segment count: ry   Trû  )rž   r$   r]  Útyperd   rF   Ú_spliner®   r2  r   Ú_parametersrD   rI   r   ÚextminÚextmaxÚ_measureÚ
_distancesÚcumsumÚ_offsets)r÷   rc  r  rI   Úbboxs        rP   rù   zMeasurement.__init__–  sÐ   € Ü˜&¤'Ô*ÜÐ=¼dÀ6»l¸^ÐLÓMÐMÜ�x“=ˆØ�aŠ<ÜÐ6°x°jÐAÓBÐBØˆŒÜŸ;™; s¨F¯L©L¸(ÀQ¹,ÐQUÔVˆÔÜ�d—l‘l×)Ñ)¨$×*:Ñ*:Ó;Ó<ˆÜ˜6Ó"ˆØ—k‘kˆŒØ—k‘kˆŒØŸ-™-¨Ó/ˆŒÜŸ	™	 $§/¡/Ó2ˆ�rQ   c                ó¾   — | d   }t        j                  t        | «      t         j                  ¬«      }t	        | «      D ]  \  }}|j                  |«      ||<   |}Œ |S )Nr   r«   )r®   rÏ  rE   r°   Ú	enumerater?  )rI   ÚprevÚ	distancesrR  r7  s        rP   r
  zMeasurement._measure¥  sV   € à�a‰yˆÜ—H‘HœS ›[´·
±
Ô;ˆ	Ü% fÖ-‰LˆE�5Ø#Ÿ}™}¨UÓ3ˆI�eÑØ‰Dð .ð ÐrQ   c                ó2   — t        | j                  d   «      S )z0Returns the approximated length of the B-spline.r@   )rt   r  rû   s    rP   ÚlengthzMeasurement.length®  s   € ô �T—]‘] 2Ñ&Ó'Ð'rQ   c                ó,  — |dk  ry|| j                   j                  k\  r| j                  S | j                  }t	        j
                  ||d¬«      }||   }||dz      }| j                  |dz      ||z
  z  ||z
  z  }t        | j                  |   |z   «      S )zfReturns the distance along the curve from the start point for then given
        parameter t.
        ry   Úright©Úsider   )	r  r   r  r  r®   Úsearchsortedr  rt   r  )r÷   rK   rß   rR  rš   Út2r?  s          rP   r?  zMeasurement.distance³  s›   € ð �Š8ØØ�—‘×"Ñ"Ò"Ø—;‘;ÐØ×!Ñ!ˆÜ—‘ ¨°Ô8ˆØ�E‰]ˆØ�E˜A‘IÑˆØ—?‘? 5¨1¡9Ñ-°°R±Ñ8¸BÀ¹GÑDˆÜ�T—]‘] 5Ñ)¨HÑ4Ó5Ð5rQ   c                ó<  — t        j                  | j                  |d¬«      }|dk  ry| j                  }|t	        |«      k\  r| j
                  j                  S |dz
  }|| j                  |   z
  }||   }||   }t        |||z
  || j                  |   z  z  z   «      S )zcReturns the parameter t for a given distance along the curve from the
        start point.
        r  r  r   ry   r   )	r®   r  r  r  rE   r  r   rt   r  )r÷   r?  rR  rß   r  rý  rš   r  s           rP   Úparam_atzMeasurement.param_atÂ  s    € ô —‘ §¡¨x¸gÔFˆØ�AŠ:ØØ×!Ñ!ˆØ”C˜“KÒØ—<‘<×%Ñ%Ð%Ø�q‰yˆØ  4§=¡=°Ñ#6Ñ6ˆØ�D‰\ˆØ�E‰]ˆÜ�R˜2 ™7 }°t·±ÀuÑ7MÑ'MÑNÑNÓOÐOrQ   c                ó  — |dk  rt        d|› �«      ‚| j                  }||z  }|}| j                  j                  }g }||k  rC| j	                  |«      }t        j                  ||«      s|j                  |«       ||z  }||k  rŒC|S )av  Returns the interpolated B-spline parameters for dividing the curve into
        `count` segments of equal length.

        The method yields only the dividing parameters, the first (0.0) and last parameter
        (max_t) are not included e.g. dividing a B-spline by 3 yields two parameters
        [t1, t2] that divides the B-spline into 3 parts of equal length.

        r   zinvalid count: )rF   r  r  r   r  r�   r‚   r–   )r÷   r[   Útotal_lengthÚ
seg_lengthr?  r   ÚresultrK   s           rP   ÚdividezMeasurement.divideÒ  s”   € ð �1Š9Ü˜¨u¨gÐ6Ó7Ð7Ø"Ÿk™kˆØ! EÑ)ˆ
ØˆØ—‘×"Ñ"ˆØ ˆØ˜Ò%Ø—‘˜hÓ'ˆAÜ—<‘<  qÔ)Ø—‘˜aÔ Ø˜
Ñ"ˆHð	 ˜Ó%ð
 ˆrQ   N)rc  r$   r  rd   rÆ   ÚNone)rI   r’  rÆ   r\  r�  )rK   rt   rÆ   rt   )r?  rt   rÆ   rt   )r[   rd   rÆ   rÇ   )r•  r–  r—  r˜  rù   r›  r
  rš  r  r?  r  r!  rm   rQ   rP   r†  r†  �  sD   „ ñó3ð òó ðð ò(ó ð(ó6óPô rQ   r†  c                ót  — d}||k  rt        d«      ‚|| j                  |z
  kD  rt        d«      ‚| j                  }t        j                  ||«      }| j                  |«      } t        j                  | j                  «       t        j                  ¬«      }t        j                  ||d¬«      }|d| }||d }t        j                  ||f«      }| j                  }	t        |«      |z
  }
|	d|
 }|	|
d }g }g }| j                  «       }t        |«      r
|d|
 }||
d }t        ||||¬«      t        ||||¬«      fS )	zƒSplits a B-spline at a parameter t.

    Raises:
        ValuerError: t out of range 0 < t < max_t

    .. versionadded:: 1.4

    gê-�™—q=zt must be greater than 0zt must be smaller than max_tr«   r  r  Nr[  )rF   r   r;   r®   Úfullrd  r¯   r<   r°   r  ÚconcatenaterJ   rE   rõ   r$   )rc  rK   Útolr;   r—   r<   rÍ   Úknots1Úknots2rI   Úsplit_indexÚpoints1Úpoints2Úweights1Úweights2rõ   s                   rP   r‰  r‰  ê  sJ  € ð €CØˆ3‚wÜÐ3Ó4Ð4Øˆ6�<‰<˜#ÑÒÜÐ7Ó8Ð8Ø�L‰L€Eô 	�‰��qÓ€AØ×#Ñ# AÓ&€Fä�H‰H�V—\‘\“^¬2¯:©:Ô6€Eä�?‰?˜5 !¨'Ô2€Dð �5�Dˆ\€FØ�4�5ˆ\€Fô �^‰^˜Q ˜KÓ(€Fð ×"Ñ"€FÜ�f“+ Ñ%€KØ�\�kÐ"€GØ�[�\Ð"€GØ "€HØ "€HØ�n‰nÓ€GÜ
ˆ7„|Ø˜<˜KÐ(ˆØ˜;˜<Ð(ˆä�˜ f°hÔ?Ü�˜ f°hÔ?ðð rQ   c                ó²   — 	 t        t        j                  |«      «       }|dk  r| S | D �cg c]  }t	        ||¬«      ‘Œ c}S # t        $ r | cY S w xY wc c}w )zyReturns rounded knot-values.

    The `tolerance` defines the minimal difference between two knot values like 1e-9.

    r   )Úndigits)rd   r�   Úlog10rF   Úround)r<   Ú	tolerancer/  re   s       rP   r5   r5     sa   € ðÜ”t—z‘z )Ó,Ó-Ð-ˆð �!‚|ØˆÙ/4Ó5©u¨!ŒE�!˜WÖ%¨uÑ5Ð5øô	 ò ØŠðüò 6s   ‚A ¬AÁAÁAr†   )rH   r‹  rC   úOptional[Iterable[UVec]]rÆ   r$   )rH   r‹  rÆ   r$   )rA   Nr=   )
rH   r‹  rB   rd   rC   r3  r?   ÚstrrÆ   r$   )z5-pointsN)rH   r‹  r?   r4  rC   r3  rÆ   r$   )r[   rd   r;   rd   rÆ   rd   )T)r;   rd   rÆ   rd   )r<   r�  rÆ   rÇ   )F)r[   rd   r;   rd   rÆ   rÇ   )rY   F)rf   rd   rg   rd   rK   r‘  rÆ   rÇ   )rf   rd   rg   rd   rK   r�  rÆ   rÇ   )r¢   zlist | linalg.MatrixrB   rd   rÆ   zlinalg.Solver)rY   )
rH   zSequence[UVec]rB   rd   r\   r�  r]   r4  rÆ   útuple[list[Vec3], list[float]])rH   r’  rN   r   rO   r   rB   rd   r\   r�  r]   r4  rÆ   r5  )rH   r’  rÆ   r5  )
rH   r’  r×   r’  rB   rd   r\   r�  rÆ   r5  )rH   r’  rC   r’  rÆ   r5  )rg   rÇ   rÆ   r‘  )r9   N)rJ   r‹  r;   rd   rõ   rŒ  rÆ   r$   )rÎ  r   r   r   r   )r  r   r  rt   r  rt   r  rt   r  rd   rÆ   r$   )r   )r  r   r  rd   rÆ   r$   )r  rt   r  rt   r  rd   )
r—   rt   rR  rd   rB   rd   r<   r�  rÆ   rt   )
r—   rt   r[   rd   rB   rd   r<   r�  rÆ   rÇ   )rc  r$   rK   rd   rÆ   r$   )rc  r$   rÆ   r\  )rZ  zIterable[Sequence[float]]rÆ   r5  )rc  r$   r7  r   rÆ   rt   )rc  r$   rK   rt   rÆ   r”  )r<   rÇ   r2  rt   rÆ   rÇ   )Jr˜  Ú
__future__r   Útypingr   r   r   r   r   r	   r
   r�   Únumpyr®   rU   r   r   r   r   r   r   r   r   r   r  r   r   Úezdxf.lldxf.constr   r   r   r   r   Ú__all__r   r!   r   r   r0   r3   r4   rq   r1   r2   r*   r+   r,   r-   r.   r/   r§   r%   r&   r'   r(   r)   r$   rx  r"   r#   r   Úpirµ  r    r¤  rÉ  rË  r{  r^  r`  r„  r†  r‰  r5   rm   rQ   rP   Ú<module>r<     sü  ðñõ  #÷÷ ñ ó Û ÷
÷ 
õ 
õ Ý Ý +á÷ó ò €ðJ *.ð*Øð*à&ð*ð ó*óZ,ð2 Ø)-Øð	SØðSàðSð 'ðSð ð	Sð
 óSðp Ø)-ð'9Øð'9àð'9ð 'ð'9ð ó	'9óTô2ó$	ó4ôKô&ð6 GLð&FØ
ð&FØð&FØ&ð&Fàó&FóRó*ó&ó&ó&#óL0ð6 #,ð	$3Øð$3àð$3ð ð$3ð  ð	$3ð
 $ó$3ðZ #,ð33Øð33àð33ð ð33ð ð	33ð
 ð33ð  ð33ð $ó33ðl>3Øð>3à#ó>3ðB>3Øð>3àð>3ð ð>3ð ð	>3ð
 $ó>3ðB6!Øð6!Ø&0ð6!à#ó6!÷rg&ñ g&óTð Ø)-ðNØ"ðNàðNð 'ðNð ó	Nð0 Ø)-ðAØ"ðAàðAð 'ðAð ó	Að2 ØØØØðØðàðð ðð ð	ð
 ðð óð@ ‡w�w��}€ð 34ðØ ðØ,/ðàóôB3*ól'&ðTØðØðØ"%ðØ.=ðàóð6 ò@ó ð@óFð	Ø(ð	à#ó	ð .2À#ÈAñ<Øð<Ø ð<à
ó<÷~Zñ Zóz-ô`6rQ   