
    'j-                        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	j        dz  Zded<   	 d&d'dZd Zd!ZeZ	 d&d(d#Z dS ))    )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                      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dS ))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_offset	defpointsSequence[T]c                   t          |          dk    rt          d          |d         j        }|j        dvrt	          d|j                   |d         | _        t          fd|D                       | _        d S )N   zFour control points required.r   )r   r   zinvalid point type: c              3  "   K   | ]	}|z
  V  
d S N ).0poffsets     N/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/math/_bezier4p.py	<genexpr>z$Bezier4P.__init__.<locals>.<genexpr>=   s'      3R3R1AJ3R3R3R3R3R3R    )len
ValueError	__class____name__	TypeErrorr   tupler   )selfr   
point_typer#   s      @r$   __init__zBezier4P.__init__2   s    y>>Q<===q\+
"&666H:3FHHIII aL .33R3R3R3R	3R3R3R.R.Rr&   returnc                F    | 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?   s6     -BBrF{BKf<<r&   tfloatr   c                h    d|cxk    rdk    sn t          d          |                     |          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-   r7   s     r$   tangentzBezier4P.tangentG   s>     Q#6777&&q)))r&   c                h    d|cxk    rdk    sn t          d          |                     |          S )u   Returns point for location `t` at the Bèzier-curve.

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

        r   r:   r;   )r(   _get_curve_pointr=   s     r$   pointzBezier4P.pointS   s>     Q#6777$$Q'''r&   segmentsintIterator[T]c              #     K   |dk     rt          |          d|z  }| j        }|d         V  t          d|          D ]}|                     ||z            V  |d         V  dS )u   Approximate `Bézier curve`_ by vertices, yields `segments` + 1
        vertices as ``(x, y[, z])`` tuples.

        Args:
            segments: count of segments for approximation

        r
   r:   r      N)r(   r6   ranger@   )r-   rB   delta_tcpsegments        r$   approximatezBezier4P.approximate^   s       a<<X&&&. eQ)) 	; 	;G'''(9::::::er&   r   distancec              #    K   g }d|z  }d}| j         }|d         }|V  |dk     r||z   }t          j        |d          r|d         }	d}n|                     |          }		 ||z   dz  }
|                     |
          }|                    |	          }|                    |          }||k     r#|	V  |}|	}|r|                                \  }}	nn|                    ||	f           |
}|}	|dk     dS dS )a>  Adaptive recursive flattening. The argument `segments` is the
        minimum count of approximation segments, if the distance from the center
        of the approximation segment to the curve is bigger than `distance` the
        segment will be subdivided.

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

        r:           r   rF   Tg      ?N)r6   mathiscloser@   lerprL   popappend)r-   rL   rB   stackdtt0rI   start_pointt1	end_pointmid_t	mid_point	chk_pointds                 r$   
flatteningzBezier4P.flatteningo   s@      (*(N A 3hhbB|B$$ 6qE	 11"55	* "R3#44U;;	*//	::	&&y11x<<#OOOB"+K (-		IILL"i111B )I#* 3hhhhhhr&   c                    | j         \  }}}}||z  }d|z
  }d|z  |z  |z  }d|z  |z  }	||z  }
||z  ||	z  z   ||
z  z   | j        z   S )Nr:         @r   )r-   r7   _r3   r4   r5   t2
_1_minus_tbcr]   s              r$   r@   zBezier4P._get_curve_point   st     ,2r2U1W
*z)A-*r!FAv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`   r:         @       @)r   )
r-   r7   ra   r3   r4   r5   rb   rd   re   r]   s
             r$   r<   zBezier4P._get_curve_tangent   sr     ,2r2U3q=38+,!GsS1W}%"HAvQa''r&      c                v    d}d}|                      |          D ]}|||                    |          z  }|}|S )u_   Returns estimated length of Bèzier-curve as approximation by line
        `segments`.
        rN   N)rK   rL   )r-   rB   length
prev_pointrA   s        r$   approximated_lengthzBezier4P.approximated_length   sU     
%%h// 	 	E%*--e444JJr&   Bezier4P[T]c                ^    t          t          t          | j                                      S )u>   Returns a new Bèzier-curve with reversed control point order.)r   listreversedr6   )r-   s    r$   reversezBezier4P.reverse   s#    Xd&9::;;<<<r&   mr   Bezier4P[Vec3]c                    t          j        | j                  }t          t	          |                    |                              S )zGeneral transformation interface, returns a new :class:`Bezier4p`
        curve as a 3D curve.

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

        )r   generater6   r   r,   transform_vertices)r-   rs   r   s      r$   	transformzBezier4P.transform   s:     M$"566	a229==>>???r&   N)r   r   )r0   r   )r7   r8   r0   r   )rB   rC   r0   rD   )r   )rL   r8   rB   rC   r0   rD   )ri   )rB   rC   r0   r8   )r0   rn   )rs   r   r0   rt   )r*   
__module____qualname____doc__	__slots__r/   propertyr6   r>   rA   rK   r^   r@   r<   rm   rr   rx   r    r&   r$   r   r   !   s"         /IS S S S = = = X=
* 
* 
* 
*	( 	( 	( 	(   "0* 0* 0* 0* 0*d7 7 7 7
( 
( 
( 
(
 
 
 
 
= = = =	@ 	@ 	@ 	@ 	@ 	@r&   r   r   r   r   h  centerr   radiusr8   start_angle	end_anglerB   rC   r0   Iterator[Bezier4P[Vec3]]c              #    	K   t          |           	t                    t          ||          }t          |          dk     rdS |}t	          j        |          t          j        z  }t	          j        ||z             }||k    r|t          j        z  }||k    t          |||          D ]"}	fd|D             }t          |          V  #dS )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.

    &.>Nc                     g | ]
}|z  z   S r    r    )r!   r"   center_r   s     r$   
<listcomp>z)cubic_bezier_from_arc.<locals>.<listcomp>   s"    DDDWF
+DDDr&   )	r   r8   r   absrO   radianstaur   r   )
r   r   r   r   rB   
angle_spansr6   r   r   s
    `       @r$   r   r      s      & LLG6]]F*;	BBJ
:A,q//DH,KQ^,,I
	
!
!TX	 	
!
! 6k9hWW " "DDDDD^DDD	y!!!!!!" "r&   rh   PI_2ellipse'ConstructionEllipse'c              #  .   K    j         }t          |          dk     rdS  j        t          j        z  }||z   }||k    r|t          j        z  }||k    d fd}t          |||          D ])}t          t           ||                              V  *dS )	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   NpointsIterable[Vec3]r0   Iterator[Vec3]c              3     K   t          j                  }j        }j        }| D ]}|||j        z  z   ||j        z  z   V  d S r   )r   r   
major_axis
minor_axisxy)r   r   x_axisy_axisr"   r   s        r$   rx   z,cubic_bezier_from_ellipse.<locals>.transform  sd      gn%%)) 	7 	7A6AC<'&13,66666	7 	7r&   )r   r   r0   r   )
param_spanr   start_paramrO   r   r   r   r,   )r   rB   r   r   r   rx   r   s   `      r$   r   r      s        *J
: ,tx7K"Z/I
	
!
!TX	 	
!
!7 7 7 7 7 7 1iRR 4 4	uYYy11223333334 4r&   gUUUUUU?gI`Q?'Iterator[tuple[Vec3, Vec3, Vec3, Vec3]]c              #    K   |dk     rt          d          || z
  }|dk    r3t          t          j        |t          j        z  dz            |          }nt          d          ||z  }t
          t          j        |dz            z  }| }t          j        |          }t          |          D ]U}	|}
||z  }t          j        |          }|
|
j
         |z  |
j        |z  fz   }||j
        |z  |j         |z  fz   }|
|||fV  VdS )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   rh   z3Delta angle from start- to end angle has to be > 0.rg   N)r(   maxrO   ceilpiTANGENT_FACTORtanr   
from_anglerG   r   r   )r   r   rB   delta_angle	arc_countsegment_angletangent_lengthanglerY   ra   rW   control_point_1control_point_2s                r$   r   r   )  sI      !||<==="[0KQ	+"7#"=>>II		NOOO&2M*TXmc6I-J-JJNEoe,,I9 G GOE**	%]N^+MN*)
 
 $K.([L>)'
 
 ?OYFFFFFG Gr&   )r~   r
   r   r   r
   )r   r   r   r8   r   r8   r   r8   rB   rC   r0   r   )r
   )r   r   rB   rC   r0   r   )r   r8   r   r8   rB   rC   r0   r   )!
__future__r   typingr   r   r   r   r   r	   rO   _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   # " " " " " "                                * * * * * * 7666666   GCtr@ r@ r@ r@ r@wqz r@ r@ r@l !" !" !" !" !"H gm     564 4 4 4 4H # -  ( ;<'G 'G 'G 'G 'G 'G 'Gr&   