
    'jn                        d dl mZ d dl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gZddZ edee
          Z G d dee                   ZdS )    )annotations)IteratorSequenceOptionalGenericTypeVarN   )Vec3Vec2)Matrix44Bezier3PtfloatreturnNonec                B    d| cxk    rdk    sn t          d          d S )N              ?zt not in range [0 to 1])
ValueError)r   s    N/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/math/_bezier3p.pycheck_if_in_valid_ranger      s/    !????s????2333 ?    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&dZd!dZd!dZd'dZd(dZdS ))r   uN  Implements an optimized quadratic `Bézier curve`_ for exact 3 control
    points.

    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Three control points required.r   )r   r
   zinvalid point type: c              3  "   K   | ]	}|z
  V  
d S )N ).0poffsets     r   	<genexpr>z$Bezier3P.__init__.<locals>.<genexpr>8   s'      3R3R1AJ3R3R3R3R3R3Rr   )lenr   	__class____name__	TypeErrorr   tupler   )selfr   
point_typer&   s      @r   __init__zBezier3P.__init__-   s    y>>Q=>>>q\+
"&666H:3FHHIII aL .33R3R3R3R	3R3R3R.R.Rr   r   c                <    | j         \  }}}| j        }|||z   ||z   fS )zBControl points as tuple of :class:`Vec3` or :class:`Vec2` objects.r   )r-   _p1p2r&   s        r   control_pointszBezier3P.control_points:   s.     (	2rrF{BK//r   r   r   r   c                J    t          |           |                     |          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   _get_curve_tangentr-   r   s     r   tangentzBezier3P.tangentB   s&     	 """&&q)))r   c                J    t          |           |                     |          S )u   Returns point for location `t` at the Bèzier-curve.

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

        )r   _get_curve_pointr7   s     r   pointzBezier3P.pointM   s&     	 """$$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   r4   ranger:   )r-   r<   delta_tcpsegments        r   approximatezBezier3P.approximateW   s       a<<X&&&x eQ)) 	; 	;G'''(9::::::er      c                v    d}d}|                      |          D ]}|||                    |          z  }|}|S )u_   Returns estimated length of Bèzier-curve as approximation by line
        `segments`.
        r   N)rE   distance)r-   r<   length
prev_pointr;   s        r   approximated_lengthzBezier3P.approximated_lengthh   sU     "&
%%h// 	 	E%*--e444JJr      rH   c              #    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 )aB  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 quadratic (C2)
                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   r   r@   Tg      ?N)r4   mathiscloser:   lerprH   popappend)r-   rH   r<   stackdtt0rC   start_pointt1	end_pointmid_t	mid_point	chk_pointds                 r   
flatteningzBezier3P.flatteningt   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                b    | j         \  }}}d|z
  }d|z  |z  }||z  }||z  ||z  z   | j        z   S )Nr          @r   )r-   r   r1   r2   r3   
_1_minus_tbcs           r   r:   zBezier3P._get_curve_point   sK     (	2r1W
!Gj EAvQ--r   c                H    | j         \  }}}dd|z  z
  }d|z  }||z  ||z  z   S )Nr_   g      @)r   )r-   r   r1   r2   r3   ra   rb   s          r   r6   zBezier3P._get_curve_tangent   s:     (	2r#'M!GAvQr   Bezier3P[T]c                ^    t          t          t          | j                                      S )u>   Returns a new Bèzier-curve with reversed control point order.)r   listreversedr4   )r-   s    r   reversezBezier3P.reverse   s#    Xd&9::;;<<<r   mr   Bezier3P[Vec3]c                    t          j        | j                  }t          t	          |                    |                              S )zGeneral transformation interface, returns a new :class:`Bezier3P`
        curve and it is always a 3D curve.

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

        )r
   generater4   r   r,   transform_vertices)r-   ri   r   s      r   	transformzBezier3P.transform   s:     M$"566	a229==>>???r   N)r   r   )r   r   )r   r   r   r   )r<   r=   r   r>   )rF   )r<   r=   r   r   )rL   )rH   r   r<   r=   r   r>   )r   rd   )ri   r   r   rj   )r*   
__module____qualname____doc__	__slots__r/   propertyr4   r8   r;   rE   rK   r]   r:   r6   rh   rn   r#   r   r   r   r      s"       
 
 /IS S S S 0 0 0 X0	* 	* 	* 	*( ( ( (   "
 
 
 
 
0* 0* 0* 0* 0*d	. 	. 	. 	.   = = = =	@ 	@ 	@ 	@ 	@ 	@r   )r   r   r   r   )
__future__r   typingr   r   r   r   r   rN   _vectorr
   r   	_matrix44r   __all__r   r   r   r#   r   r   <module>ry      s   # " " " " "                              ,4 4 4 4
 GCtj@ j@ j@ j@ j@wqz j@ j@ j@ j@ j@r   