
    'jYC                    *   d dl mZ d dl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mZmZ erd dlmZ d Zd Zdd	ej        d
z  dfd dZdd	ej        dz  ej        dz  dfd!dZ G d d          Z G d d          Z G d d          ZdS )"    )annotations)TYPE_CHECKINGIterableOptionalN)Vec3Vec2UVecMatrix44perlinBezier4Pglobal_bspline_interpolationBSplineopen_uniform_bsplineclosed_uniform_bsplineEulerSpiral)
BaseLayoutc                :    | dz  t          j                     | z  z
  S N       @)random)	max_values    M/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/render/curves.pyrndr      s    s?V]__y888    c                V    t          j        |j        |j                  }| dz  || z  z
  S r   )r   snoise2xy)r   walkerrs      r   
rnd_perlinr!      s*    vx**As?Q]**r   d   g      ?      stepsintmax_step_sizefloatmax_headingretargetreturnIterable[Vec2]c              #  B  K   || z  fd}t          dd          } |            }t          |           D ]g}||z  dk    r| |            z   }||z
  j        }|t          ||          z   }	|t	          j                    z  }
|t          j        |	|
          z   }|V  hdS )u]  Returns a random 2D path as iterable of :class:`~ezdxf.math.Vec2`
    objects.

    Args:
        steps: count of vertices to generate
        max_step_size: max step size
        max_heading: limit heading angle change per step to ± max_heading/2 in
            radians
        retarget: specifies steps before changing global walking target

    c                 Z    t          t                     t                     f          S N)r   r   max_s   r   next_global_targetz*random_2d_path.<locals>.next_global_target5   s"    SYYD		*+++r   r   N)r   rangeangler!   r   
from_angle)r%   r'   r)   r*   r2   r   targetir4   headinglengthr1   s              @r   random_2d_pathr:   "   s      " 5 D, , , , , !QZZF!!F5\\  x<100222F&'*[&9990$/'6::: r   r   g       @	max_pitchIterable[Vec3]c              #    K   || z  fd}t                      } |            }t          |           D ]}||z  dk    r| |            z   }||z
  j        }	|t          j                    z  }
|	t	          ||          z   }t          j        ||
          }t	          ||          }|t          j        |                              |          z  }|V  dS )u  Returns a random 3D path as iterable of :class:`~ezdxf.math.Vec3`
    objects.

    Args:
        steps: count of vertices to generate
        max_step_size: max step size
        max_heading: limit heading angle change per step to ± max_heading/2,
            rotation about the z-axis in radians
        max_pitch: limit pitch angle change per step to ± max_pitch/2, rotation
            about the x-axis in radians
        retarget: specifies steps before changing global walking target

    c                 v    t          t                     t                     t                     f          S r/   )r   r   r0   s   r   r2   z*random_3d_path.<locals>.next_global_targetZ   s*    SYYD		3t995666r   r   N)	r   r3   r4   r   r!   r5   r
   x_rotate	transform)r%   r'   r)   r;   r*   r2   r   r6   r7   r4   r9   heading_angle	next_steppitch_angler1   s                 @r   random_3d_pathrD   D   s     ( 5 D7 7 7 7 7 VVF!!F5\\ 	 	x<100222F&'0
; ? ??OM6::	 F33(#K00::9EEE	 	r   c                  `    e Zd ZdZ G d d          ZddZdd
Z	 	 dddZddZ	 	 d d!dZ	dS )"Beziera>  Render a bezier curve as 2D/3D :class:`~ezdxf.entities.Polyline`.

    The :class:`Bezier` class is implemented with multiple segments, each
    segment is an optimized 4 point bezier curve, the 4 control points of the
    curve are: the start point (1) and the end point (4), point (2) is start
    point + start vector and point (3) is end point + end vector. Each segment
    has its own approximation count.

    .. seealso::

        The new :mod:`ezdxf.path` package provides many advanced construction tools
        based on the :class:`~ezdxf.path.Path` class.

    c                      e Zd ZddZddZdS )Bezier.Segmentstartr	   endstart_tangentend_tangentsegmentsr&   c                    t          |          | _        t          |          | _        t          |          | _        t          |          | _        || _        d S r/   )r   rI   rJ   rK   rL   rM   )selfrI   rJ   rK   rL   rM   s         r   __init__zBezier.Segment.__init__|   sP     eDJCyyDH!%" "D  $K00D$DMMMr   r+   r<   c                    | j         | j         | j        z   | j        | j        z   | j        g}t	          |          }|                    | j                  S r/   )rI   rK   rJ   rL   r   approximaterM   )rO   control_pointsbeziers      r   rR   zBezier.Segment.approximate   sR    

T//4++	N n--F%%dm444r   N)
rI   r	   rJ   r	   rK   r	   rL   r	   rM   r&   )r+   r<   )__name__
__module____qualname__rP   rR    r   r   SegmentrH   {   s<        	% 	% 	% 	% 	5 	5 	5 	5 	5 	5r   rY   r+   Nonec                    g | _         d S r/   )points)rO   s    r   rP   zBezier.__init__   s      	r   pointr	   tangentc                \    | j                             t          |          d|df           dS )zSet start point and start tangent.

        Args:
            point: start point
            tangent: start tangent as vector, example: (5, 0, 0) means a
                     horizontal tangent with a length of 5 drawing units
        N)r\   appendr   )rO   r]   r^   s      r   rI   zBezier.start   s/     	DKKw=>>>>>r   Nr$   tangent1tangent2Optional[UVec]rM   r&   c                    t          |          }|| }nt          |          }| j                            t          |          ||t          |          f           dS )a  Append a control point with two control tangents.

        Args:
            point: control point
            tangent1: first tangent as vector "left" of the control point
            tangent2: second tangent as vector "right" of the control point,
                if omitted `tangent2` = `-tangent1`
            segments: count of line segments for the polyline approximation,
                count of line segments from the previous control point to the
                appended control point.

        N)r   r\   r`   r&   )rO   r]   ra   rb   rM   s        r   r`   zBezier.append   sZ    & >> yHHH~~HDKK8S]]KLLLLLr   Iterable[Segment]c              #  H  K   t          | j                  dk    rzt          | j        d d         | j        dd                    D ]M\  }}|d         }|d         }|d         }|d         }|d         }t                              |||||          V  Nd S t          d          )N   r   r#      zTwo or more points needed!)lenr\   ziprF   rY   
ValueError)rO   
from_pointto_pointstart_pointrK   	end_pointrL   counts           r   _build_bezier_segmentszBezier._build_bezier_segments   s      t{a(+DK,<dk!""o(N(N  $
H(m *1$QK	&qk nnM;       9:::r   Flayoutr   force3dboolc                   g }|                                  D ])}|                    |                                           *|st          d |D                       r|                    ||           dS |                    ||           dS )a  Render Bezier curve as 2D/3D :class:`~ezdxf.entities.Polyline`.

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            force3d: force 3D polyline rendering
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        c              3  &   K   | ]}|d          V  dS )r#   NrX   ).0ps     r   	<genexpr>z Bezier.render.<locals>.<genexpr>   s&      //1!A$//////r   
dxfattribsN)rr   extendrR   anyadd_polyline3dadd_polyline2d)rO   rs   rt   r|   r\   segments         r   renderzBezier.render   s      2244 	1 	1GMM'--//0000 	Ac/////// 	A!!&Z!@@@@@!!&Z!@@@@@r   )r+   rZ   )r]   r	   r^   r	   r+   rZ   )Nr$   )r]   r	   ra   r	   rb   rc   rM   r&   )r+   re   )FN)rs   r   rt   ru   r+   rZ   )
rU   rV   rW   __doc__rY   rP   rI   r`   rr   r   rX   r   r   rF   rF   k   s         5 5 5 5 5 5 5 56   ? ? ? ? $(M M M M M4; ; ; ;" 	A A A A A A Ar   rF   c                      e Zd ZdZ	 dd dZd!d"dZ	 	 	 d#d$dZeZ	 d%d&dZ	 d%d&dZ		 d%d&dZ
	 	 d%d'dZ	 	 d%d'dZ	 	 d%d'dZdS )(Splinea-  This class can be used to render B-splines into DXF R12 files as
    approximated :class:`~ezdxf.entities.Polyline` entities.
    The advantage of this class over the :class:`R12Spline` class is,
    that this is a real 3D curve, which means that the B-spline vertices do
    have to be located in a flat plane, and no :ref:`UCS` class is needed to
    place the curve in 3D space.

    .. seealso::

        The newer :class:`~ezdxf.math.BSpline` class provides the
        advanced vertex interpolation method :meth:`~ezdxf.math.BSpline.flattening`.

    Nr"   r\   Optional[Iterable[UVec]]rM   r&   c                h    |g }t          j        |          | _        t          |          | _        dS )z
        Args:
            points: spline definition points
            segments: count of line segments for approximation, vertex count is
                `segments` + 1

        N)r   listr\   r&   rM   )rO   r\   rM   s      r   rP   zSpline.__init__   s0     >F"&)F"3"3Hr      r+   rZ   c                D    t          | j                  dz
  |z  | _        dS )ad  Calculate overall segment count, where segments is the sub-segment
        count, `segments` = 4, means 4 line segments between two definition
        points e.g. 4 definition points and 4 segments = 12 overall segments,
        useful for fit point rendering.

        Args:
            segments: sub-segments count between two definition points

        rg   N)rj   r\   rM   )rO   rM   s     r   	subdividezSpline.subdivide  s#     T[))A-9r   ri   chordrs   r   degreemethodstrr|   Optional[dict]c                   t          | j        ||          }t          |                    | j                            }t          d |D                       r|                    ||           dS |                    ||           dS )a  Render a B-spline as 2D/3D :class:`~ezdxf.entities.Polyline`, where
        the definition points are fit points.

           - 2D spline vertices uses: :meth:`~ezdxf.layouts.BaseLayout.add_polyline2d`
           - 3D spline vertices uses: :meth:`~ezdxf.layouts.BaseLayout.add_polyline3d`

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            degree: degree of B-spline (order = `degree` + 1)
            method: "uniform", "distance"/"chord", "centripetal"/"sqrt_chord" or
                "arc" calculation method for parameter t
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        )r   r   c              3  ,   K   | ]}|j         d k    V  dS )g        N)z)rx   vertexs     r   rz   z.Spline.render_as_fit_points.<locals>.<genexpr>(  s(      666vx3666666r   r{   N)r   r\   r   rR   rM   r~   r   r   )rO   rs   r   r   r|   splineverticess          r   render_as_fit_pointszSpline.render_as_fit_points  s    * .Kv
 
 
 **4=99::66X66666 	C!!(z!BBBBB!!(z!BBBBBr   c                    t          | j        |dz             }|                    t          |                    | j                            |           dS )aX  Render an open uniform B-spline as 3D :class:`~ezdxf.entities.Polyline`.
        Definition points are control points.

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            degree: degree of B-spline (order = `degree` + 1)
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        rg   orderr{   Nr   r\   r   r   rR   rM   rO   rs   r   r|   r   s        r   render_open_bsplinezSpline.render_open_bspline/  s`     FQJ777##DM2233
 	 	
 	
 	
 	
 	
r   c                    t          | j        |dz             }|                    t          |                    | j                            |           dS )aR  Render a uniform B-spline as 3D :class:`~ezdxf.entities.Polyline`.
        Definition points are control points.

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            degree: degree of B-spline (order = `degree` + 1)
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        rg   r   r{   N)r   r\   r   r   rR   rM   r   s        r   render_uniform_bsplinezSpline.render_uniform_bspline@  s`     &dk!DDD##DM2233
 	 	
 	
 	
 	
 	
r   c                    t          | j        |dz             }|                    t          |                    | j                            |           dS )aY  Render a closed uniform B-spline as 3D :class:`~ezdxf.entities.Polyline`.
        Definition points are control points.

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            degree: degree of B-spline (order = `degree` + 1)
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        rg   r   r{   Nr   r\   r   r   rR   rM   r   s        r   render_closed_bsplinezSpline.render_closed_bsplineQ  s`     (6A:FFF##DM2233
 	 	
 	
 	
 	
 	
r   weightsIterable[float]c                    t          | j        |dz   |          }|                    t          |                    | j                            |           dS )a  Render a rational open uniform BSpline as 3D :class:`~ezdxf.entities.Polyline`.
        Definition points are control points.

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            weights: list of weights, requires a weight value (float) for each
                definition point.
            degree: degree of B-spline (order = `degree` + 1)
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        rg   r   r   r{   Nr   rO   rs   r   r   r|   r   s         r   render_open_rbsplinezSpline.render_open_rbsplineb  sb    $ FQJHHH##DM2233
 	 	
 	
 	
 	
 	
r   c                    t          | j        |dz   |          }|                    t          |                    | j                            |           dS )a  Render a rational uniform B-spline as 3D :class:`~ezdxf.entities.Polyline`.
        Definition points are control points.

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            weights: list of weights, requires a weight value (float) for each
                definition point.
            degree: degree of B-spline (order = `degree` + 1)
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        rg   r   r{   Nr   r   s         r   render_uniform_rbsplinezSpline.render_uniform_rbspliney  k    $ (Kvz7
 
 
 	##DM2233
 	 	
 	
 	
 	
 	
r   c                    t          | j        |dz   |          }|                    t          |                    | j                            |           dS )a  Render a rational B-spline as 3D :class:`~ezdxf.entities.Polyline`.
        Definition points are control points.

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            weights: list of weights, requires a weight value (float) for each
                definition point.
            degree: degree of B-spline (order = `degree` + 1)
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        rg   r   r{   Nr   r   s         r   render_closed_rbsplinezSpline.render_closed_rbspline  r   r   )Nr"   )r\   r   rM   r&   )r   )rM   r&   r+   rZ   )ri   r   N)
rs   r   r   r&   r   r   r|   r   r+   rZ   )ri   N)rs   r   r   r&   r+   rZ   )rs   r   r   r   r   r&   r+   rZ   )rU   rV   rW   r   rP   r   r   r   r   r   r   r   r   r   rX   r   r   r   r      sG         HK& & & & &
: 
: 
: 
: 
: %)C C C C C< "F ?C
 
 
 
 
$ ?C
 
 
 
 
$ ?C
 
 
 
 
* 
 
 
 
 
6 
 
 
 
 
: 
 
 
 
 
 
 
r   r   c                  B    e Zd ZdZdddZ	 	 	 	 dddZ	 	 	 	 	 dddZdS )r   zRender an `euler spiral <https://en.wikipedia.org/wiki/Euler_spiral>`_
    as a 3D :class:`~ezdxf.entities.Polyline` or a
    :class:`~ezdxf.entities.Spline` entity.

    This is a parametric curve, which always starts at the origin (0, 0).

    rg   	curvaturer(   c                H    t          t          |                    | _        dS )zC
        Args:
            curvature: Radius of curvature

        N)_EulerSpiralr(   spiral)rO   r   s     r   rP   zEulerSpiral.__init__  s     #5#3#344r   r"   Nrs   r   r9   rM   r&   matrixOptional[Matrix44]c                    | j                             ||          }||                    |          }|                    t	          |          |          S )a
  Render curve as :class:`~ezdxf.entities.Polyline`.

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            length: length measured along the spiral curve from its initial position
            segments: count of line segments to use, vertex count is `segments` + 1
            matrix: transformation matrix as :class:`~ezdxf.math.Matrix44`
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        Returns:
            :class:`~ezdxf.entities.Polyline`

        Nr{   )r   rR   transform_verticesr   r   )rO   rs   r9   rM   r   r|   r\   s          r   render_polylinezEulerSpiral.render_polyline  sS    * ((::..v66F$$T&\\j$IIIr   
   ri   
fit_pointsr   c                    | j                             |||          }|j        }||                    |          }|                    ||j        |                                |          S )a  
        Render curve as :class:`~ezdxf.entities.Spline`.

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            length: length measured along the spiral curve from its initial position
            fit_points: count of spline fit points to use
            degree: degree of B-spline
            matrix: transformation matrix as :class:`~ezdxf.math.Matrix44`
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Spline`

        Returns:
            :class:`~ezdxf.entities.Spline`

        )r   N)rS   r   knotsr|   )r   bsplinerS   r   add_open_spliner   r   )	rO   rs   r9   r   r   r   r|   r   r\   s	            r   render_splinezEulerSpiral.render_spline  st    0 $$VZ$GG&..v66F%%!=,,..!	 & 
 
 	
r   )rg   )r   r(   )rg   r"   NN)rs   r   r9   r(   rM   r&   r   r   )rg   r   ri   NN)
rs   r   r9   r(   r   r&   r   r&   r   r   )rU   rV   rW   r   rP   r   r   rX   r   r   r   r     s         5 5 5 5 5 %)J J J J J: %)!
 !
 !
 !
 !
 !
 !
r   r   )
r%   r&   r'   r(   r)   r(   r*   r&   r+   r,   )r%   r&   r'   r(   r)   r(   r;   r(   r*   r&   r+   r<   )
__future__r   typingr   r   r   r   math
ezdxf.mathr   r   r	   r
   r   r   r   r   r   r   r   r   ezdxf.layoutsr   r   r!   pir:   rD   rF   r   rX   r   r   <module>r      s   # " " " " " 4 4 4 4 4 4 4 4 4 4                             )((((((9 9 9+ + + 1	    F 3w}$ $ $ $ $NwA wA wA wA wA wA wA wAtD
 D
 D
 D
 D
 D
 D
 D
NL
 L
 L
 L
 L
 L
 L
 L
 L
 L
r   