
    'j9I                       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	Z
d dlmZmZ ddlmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ erd dlmZ d dlmZ g dZd ej        dz  ej        ej        dz  gZ G d d          Z ddZ!ddZ"dS )    )annotations)TYPE_CHECKINGIterableSequenceIteratorOptionalN)Vec2UVec   )BoundingBox2d)enclosing_angles)ConstructionCircle)ConstructionRayConstructionLine)UCS)Arc)
BaseLayout)ConstructionArcarc_chord_lengtharc_segment_count      ?g      ?c                     e Zd ZdZ	 	 	 	 	 dPdQdZedRd            ZedRd            ZedSd            ZedTd            Z	edUd            Z
dVdZedWd            ZdXd!ZdYd#ZdXd$ZdZd&Zd[d)Zd\d+Zd]d-ZedWd.            ZedWd/            Zed^d3            Ze	 d_d`d5            Ze	 	 dadbd7            Ze	 d_dcd9            Z	 ddded@Z	 dfdgdFZ	 dfdhdIZ	 dfdidKZ	 dfdjdMZ dkdOZ!d:S )lr   aP  Construction tool for 2D arcs.

    :class:`ConstructionArc` represents a 2D arc in the xy-plane, use an
    :class:`UCS` to place a DXF :class:`~ezdxf.entities.Arc` entity in 3D space,
    see method :meth:`add_to_layout`.

    Implements the 2D transformation tools: :meth:`translate`,
    :meth:`scale_uniform` and :meth:`rotate_z`

    Args:
        center: center point as :class:`Vec2` compatible object
        radius: radius
        start_angle: start angle in degrees
        end_angle: end angle in degrees
        is_counter_clockwise: swaps start- and end angle if ``False``

    r   r         ?             v@Tcenterr
   radiusfloatstart_angle	end_angleis_counter_clockwiseOptional[bool]c                |    t          |          | _        || _        |r|| _        || _        d S || _        || _        d S N)r	   r   r   r    r!   )selfr   r   r    r!   r"   s         H/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/math/arc.py__init__zConstructionArc.__init__+   sF     6ll 	)*D&DNNN(D(DNNN    returnr	   c                P    | j         t          j        | j        | j                  z   S )z$start point of arc as :class:`Vec2`.)r   r	   from_deg_angler    r   r&   s    r'   start_pointzConstructionArc.start_point=   s#     {T01A4;OOOOr)   c                P    | j         t          j        | j        | j                  z   S )z"end point of arc as :class:`Vec2`.)r   r	   r,   r!   r   r-   s    r'   	end_pointzConstructionArc.end_pointB   s"     {T0MMMMr)   boolc                "    | j         | j        k    S )z<Returns ``True`` if the arc passes the x-axis (== 0 degree).r    r!   r-   s    r'   is_passing_zerozConstructionArc.is_passing_zeroG   s     $.00r)   r   c                6    t          | j        | j                  S r%   )r   r   r   r-   s    r'   circlezConstructionArc.circleL   s    !$+t{;;;r)   r   c                    t          | j        | j        f          }|                    |                                            |S )z.bounding box of arc as :class:`BoundingBox2d`.)r   r.   r0   extendmain_axis_points)r&   bboxs     r'   bounding_boxzConstructionArc.bounding_boxP   s>     d.?@@D))++,,,r)   numintIterable[float]c              #     K   |dk     rt          d          | j        dz  }| j        dz  }||k    r|dz  }t          j        |||d          D ]	}|dz  V  
dS )zReturns `num` angles from start- to end angle in degrees in
        counter-clockwise order.

        All angles are normalized in the range from [0, 360).

           znum >= 2h  T)r<   endpointN)
ValueErrorr    r!   nplinspace)r&   r<   startstopangles        r'   angleszConstructionArc.anglesW   s       77Z((('#-ns*5==CKD[#EEE 	 	E#+	 	r)   c                D    | j         }|| j        k     r|dz  }|| j        z
  S )z3Returns angle span of arc from start- to end param.r   )r!   r    )r&   ends     r'   
angle_spanzConstructionArc.angle_spang   s0     ^!!!5LCT%%%r)   aIterable[Vec2]c              #  d   K   | j         }| j        }|D ]}|t          j        ||          z   V  dS )zYields vertices on arc for angles in iterable `a` in WCS as location
        vectors.

        Args:
            a: angles in the range from 0 to 360 in degrees, arc goes
                counter clockwise around the z-axis, WCS x-axis = 0 deg.

        N)r   r   r	   r,   )r&   rM   r   r   rH   s        r'   verticeszConstructionArc.verticeso   sP        	> 	>E4.uf=======	> 	>r)   sagittac              #  j  K   t          | j                  }|dk    r| j        }| j        }t	          j        ||          rdS |dz  }|dz  }||k    r|dz  }t	          j        ||z
            }t          |||          }|                     t          j
        |||dz                       E d{V  dS dS )zApproximate the arc by vertices in WCS, argument `sagitta` is the
        max. distance from the center of an arc segment to the center of its
        chord.

        r   NrA   r   )absr   r    r!   mathiscloseradiansr   rP   rD   rE   )r&   rQ   r   rF   rG   rL   counts          r'   
flatteningzConstructionArc.flattening~   s       DK((A::+E.D|E4(( SLECKDu}} $TE\ : :J%fj'BBE}}R[eai%H%HIIIIIIIIIII :r)   c              #     K   |D ]N}t          j        |          }t          t          j        |           t          j        |          f          V  OdS )zYields tangents on arc for angles in iterable `a` in WCS as
        direction vectors.

        Args:
            a: angles in the range from 0 to 360 in degrees, arc goes
                counter-clockwise around the z-axis, WCS x-axis = 0 deg.

        N)rT   rV   r	   sincos)r&   rM   rH   rs       r'   tangentszConstructionArc.tangents   s^        	4 	4E|E**A!dhqkk2333333	4 	4r)   Iterator[Vec2]c              #     K   | j         }| j        }t          j        | j                  }t          j        | j                  }t          D ]-}t          |||          r|t          j	        ||          z   V  .d S r%   )
r   r   rT   rV   r    r!   QUARTER_ANGLESr   r	   
from_angle)r&   r   r   rF   rK   rH   s         r'   r9   z ConstructionArc.main_axis_points   s      {|D$455\$.11# 	> 	>Euc22 >tuf======	> 	>r)   dxdyc                B    | xj         t          ||          z  c_         | S )zMove arc about `dx` in x-axis and about `dy` in y-axis, returns
        `self` (floating interface).

        Args:
            dx: translation in x-axis
            dy: translation in y-axis

        )r   r	   )r&   rb   rc   s      r'   	translatezConstructionArc.translate   s!     	tB||#r)   sc                @    | xj         t          |          z  c_         | S )zkScale arc inplace uniform about `s` in x- and y-axis, returns
        `self` (floating interface).
        )r   r   )r&   rf   s     r'   scale_uniformzConstructionArc.scale_uniform   s     	uQxxr)   rH   c                F    | xj         |z  c_         | xj        |z  c_        | S )zRotate arc inplace about z-axis, returns `self`
        (floating interface).

        Args:
            angle: rotation angle in degrees

        r3   )r&   rH   s     r'   rotate_zzConstructionArc.rotate_z   s-     	E!%r)   c                4    t          j        | j                  S )z#Returns the start angle in radians.)rT   rV   r    r-   s    r'   start_angle_radzConstructionArc.start_angle_rad   s     |D,---r)   c                4    t          j        | j                  S )z!Returns the end angle in radians.)rT   rV   r!   r-   s    r'   end_angle_radzConstructionArc.end_angle_rad   s     |DN+++r)   r.   r0   tuple[Vec2, Vec2]c                p    t          |           } t          |          }| |k    rt          d          | |fS )Nz1Start- and end point have to be different points.)r	   rC   )r.   r0   s     r'   validate_start_and_end_pointz,ConstructionArc.validate_start_and_end_point   sA     ;''OO	)##PQQQI%%r)   ccwc                   |                      ||          \  }}t          j        |          }|dk    rt          d          |du r||}}|dz  }|                    |          }|dz  }	|	t          j        |          z  }
|	t          j        |          z  }|                    |d          }||z
  }|                                	                    |          }||z   }t          ||
||z
  j        ||z
  j        d          S )	a  Create arc from two points and enclosing angle. Additional
        precondition: arc goes by default in counter-clockwise orientation from
        `start_point` to `end_point`, can be changed by `ccw` = ``False``.

        Args:
            start_point: start point as :class:`Vec2` compatible object
            end_point: end point as :class:`Vec2` compatible object
            angle: enclosing angle in degrees
            ccw: counter-clockwise direction if ``True``

        r   zAngle can not be 0.F       @r   factorTr   r   r    r!   r"   )rq   rT   rV   rC   distancerZ   tanlerp
orthogonal	normalizer   	angle_deg)clsr.   r0   rH   rr   _start_point
_end_pointalpha2rx   	distance2r   height	mid_pointdistance_vectorheight_vectorr   s                   r'   from_2p_anglezConstructionArc.from_2p_angle   s)   & $'#C#C$
 $
 j U##A::2333%<<'1<*L$--l;;#c>	!DHV$4$44!DHV$4$44$//,s/CC	 *\ 9-88::DDVLL =0%.9!F*5!%
 
 
 	
r)   center_is_leftc                   |                      ||          \  }}t          |          }|dk    rt          d          |du r||}}|                    |d          }|                    |          }	|	dz  }
t          j        |dz  |
dz  z
            }|||z
                      |                              |          z   }t          ||||z
  j
        ||z
  j
        d	
          S )aX  Create arc from two points and arc radius.
        Additional precondition: arc goes by default in counter-clockwise
        orientation from `start_point` to `end_point` can be changed
        by `ccw` = ``False``.

        The parameter `center_is_left` defines if the center of the arc is
        left or right of the line from `start_point` to `end_point`.
        Parameter `ccw` = ``False`` swaps start- and end point, which also
        inverts the meaning of ``center_is_left``.

        Args:
            start_point: start point as :class:`Vec2` compatible object
            end_point: end point as :class:`Vec2` compatible object
            radius: arc radius
            ccw: counter-clockwise direction if ``True``
            center_is_left: center point of arc is left of line from start- to
                end point if ``True``

        r   zRadius has to be > 0.Fr   ru   rt   r@   )rr   Trw   )rq   r   rC   rz   rx   rT   sqrtr{   r|   r   r}   )r~   r.   r0   r   rr   r   r   r   r   rx   r   r   r   s                r'   from_2p_radiuszConstructionArc.from_2p_radius	  s   8 $'#C#C$
 $
 j vQ;;4555%<<'1<*L$//,s/CC	$--l;;#c>		&!)il":;; J$=#I#I $J $
 $

)F

 %.9!F*5!%
 
 
 	
r)   	def_pointc                .   |                      ||          \  }}t          |          }||k    s||k    rt          d          t          j        |||          }t          |j                  }t          ||j        ||z
  j        ||z
  j        |          S )a  Create arc from three points.
        Additional precondition: arc goes in counter-clockwise
        orientation from `start_point` to `end_point`.

        Args:
            start_point: start point as :class:`Vec2` compatible object
            end_point: end point as :class:`Vec2` compatible object
            def_point: additional definition point as :class:`Vec2` compatible
                object
            ccw: counter-clockwise direction if ``True``

        z5def_point has to be different to start- and end pointrw   )	rq   r	   rC   r   from_3pr   r   r   r}   )r~   r.   r0   r   rr   r6   r   s          r'   r   zConstructionArc.from_3p>  s    ( "%!A!A"
 "
Y OO	##yI'='=TUUU#+KINNfm$$=$v-8 6)4!$
 
 
 	
r)   Nlayoutr   ucsOptional[UCS]r   c                    |                     | j        | j        | j        | j        |          }||n|                    |j                  S )a9  Add arc as DXF :class:`~ezdxf.entities.Arc` entity to a layout.

        Supports 3D arcs by using an :ref:`UCS`. An :class:`ConstructionArc` is
        always defined in the xy-plane, but by using an arbitrary UCS, the arc
        can be placed in 3D space, automatically OCS transformation included.

        Args:
            layout: destination layout as :class:`~ezdxf.layouts.BaseLayout`
                object
            ucs: place arc in 3D space by :class:`~ezdxf.math.UCS` object
            dxfattribs: additional DXF attributes for the ARC entity

        )r   r   r    r!   
dxfattribs)add_arcr   r   r    r!   	transformmatrix)r&   r   r   r   arcs        r'   add_to_layoutzConstructionArc.add_to_layoutc  sR      nn;;(n!  
 
 ksss}}SZ'@'@@r)   绽|=rayr   abs_tolSequence[Vec2]c                     t          |t                    sJ  fd j                            ||          D             S )a  Returns intersection points of arc and `ray` as sequence of
        :class:`Vec2` objects.

        Args:
            ray: intersection ray
            abs_tol: absolute tolerance for tests (e.g. test for tangents)

        Returns:
            tuple of :class:`Vec2` objects

            =========== ==================================
            tuple size  Description
            =========== ==================================
            0           no intersection
            1           line intersects or touches the arc at one point
            2           line intersects the arc at two points
            =========== ==================================

        c                >    g | ]}                     |          |S  _is_point_in_arc_range.0pointr&   s     r'   
<listcomp>z1ConstructionArc.intersect_ray.<locals>.<listcomp>  =     
 
 
**511

 
 
r)   )
isinstancer   r6   intersect_ray)r&   r   r   s   `  r'   r   zConstructionArc.intersect_ray|  sX    , #/////
 
 
 
223@@
 
 
 	
r)   liner   c                     t          |t                    sJ  fd j                            ||          D             S )a  Returns intersection points of arc and `line` as sequence of
        :class:`Vec2` objects.

        Args:
            line: intersection line
            abs_tol: absolute tolerance for tests (e.g. test for tangents)

        Returns:
            tuple of :class:`Vec2` objects

            =========== ==================================
            tuple size  Description
            =========== ==================================
            0           no intersection
            1           line intersects or touches the arc at one point
            2           line intersects the arc at two points
            =========== ==================================

        c                >    g | ]}                     |          |S r   r   r   s     r'   r   z2ConstructionArc.intersect_line.<locals>.<listcomp>  r   r)   )r   r   r6   intersect_line)r&   r   r   s   `  r'   r   zConstructionArc.intersect_line  sY    , $ 011111
 
 
 
33D'BB
 
 
 	
r)   r6   c                     t          |t                    sJ  fd j                            ||          D             S )a  Returns intersection points of arc and `circle` as sequence of
        :class:`Vec2` objects.

        Args:
            circle: intersection circle
            abs_tol: absolute tolerance for tests

        Returns:
            tuple of :class:`Vec2` objects

            =========== ==================================
            tuple size  Description
            =========== ==================================
            0           no intersection
            1           circle intersects or touches the arc at one point
            2           circle intersects the arc at two points
            =========== ==================================

        c                >    g | ]}                     |          |S r   r   r   s     r'   r   z4ConstructionArc.intersect_circle.<locals>.<listcomp>  r   r)   )r   r   r6   intersect_circle)r&   r6   r   s   `  r'   r   z ConstructionArc.intersect_circle  sY    , &"455555
 
 
 
55fgFF
 
 
 	
r)   otherc                     t          t                    sJ  fd j                            j        |          D             S )a  Returns intersection points of two arcs as sequence of
        :class:`Vec2` objects.

        Args:
            other: other intersection arc
            abs_tol: absolute tolerance for tests

        Returns:
            tuple of :class:`Vec2` objects

            =========== ==================================
            tuple size  Description
            =========== ==================================
            0           no intersection
            1           other arc intersects or touches the arc at one point
            2           other arc intersects the arc at two points
            =========== ==================================

        c                h    g | ].}                     |                               |          ,|/S r   r   )r   r   r   r&   s     r'   r   z1ConstructionArc.intersect_arc.<locals>.<listcomp>  sU     
 
 
**511
 ,,U33	

 
 
r)   )r   r   r6   r   )r&   r   r   s   `` r'   intersect_arczConstructionArc.intersect_arc  s`    , %11111
 
 
 
 
55elGLL
 
 
 	
r)   r   c                    | j         dz  }| j        dz  }|| j        z
  j        dz  }||k    r||k    p||k    S ||cxk    o|k    nc S )Nr   )r    r!   r   r}   )r&   r   rF   rK   rH   s        r'   r   z&ConstructionArc._is_point_in_arc_range  so     '%/^e++6>3;;E>1Uc\1$$$$$$$$$r)   )r   r   r   r   T)
r   r
   r   r   r    r   r!   r   r"   r#   )r*   r	   )r*   r1   )r*   r   )r*   r   )r<   r=   r*   r>   )r*   r   )rM   r>   r*   rN   )rQ   r   r*   rN   )r*   r^   )rb   r   rc   r   r*   r   )rf   r   r*   r   )rH   r   r*   r   )r.   r
   r0   r
   r*   ro   )T)
r.   r
   r0   r
   rH   r   rr   r1   r*   r   )TT)r.   r
   r0   r
   r   r   rr   r1   r   r1   r*   r   )
r.   r
   r0   r
   r   r
   rr   r1   r*   r   )NN)r   r   r   r   r*   r   )r   )r   r   r   r   r*   r   )r   r   r   r   r*   r   )r6   r   r   r   r*   r   )r   r   r   r   r*   r   )r   r	   r*   r1   )"__name__
__module____qualname____doc__r(   propertyr.   r0   r4   r6   r;   rI   rL   rP   rX   r]   r9   re   rh   rj   rl   rn   staticmethodrq   classmethodr   r   r   r   r   r   r   r   r   r   r)   r'   r   r      sJ        (   /3) ) ) ) )$ P P P XP N N N XN 1 1 1 X1 < < < X<    X     & & & X&> > > >J J J J(4 4 4 4> > > >
 
 
 
   
 
 
 
 . . . X. , , , X, & & & \&  +
 +
 +
 +
 [+
Z  #2
 2
 2
 2
 [2
h  "
 "
 "
 "
 ["
J IMA A A A A4 6;
 
 
 
 
< 8=
 
 
 
 
< <A
 
 
 
 
< 8=
 
 
 
 
<% % % % % %r)   r   r   r   rQ   r*   c                l    	 dt          j        d| z  |z  ||z  z
            z  S # t          $ r Y dS w xY w)zReturns the chord length for an arc defined by `radius` and
    the `sagitta`_.

    Args:
        radius: arc radius
        sagitta: distance from the center of the arc to the center of its base

    rt   r   )rT   r   rC   )r   rQ   s     r'   r   r     sQ    TYsV|g5'8IIJJJJ   sss   "% 
33rH   r=   c                    	 t          | |          }t          j        |dz  | z            dz  }t          j        ||z            S # t          t
          f$ r Y dS w xY w)a.  Returns the count of required segments for the approximation
    of an arc for a given maximum `sagitta`_.

    Args:
        radius: arc radius
        angle: angle span of the arc in radians
        sagitta: max. distance from the center of an arc segment to the
            center of its chord

    rt   r   )r   rT   asinceilrC   ZeroDivisionError)r   rH   rQ   chord_lengthalphas        r'   r   r     sp    .vw??y!3f!<==Cy''')*   qqs   AA AA)r   r   rQ   r   r*   r   )r   r   rH   r   rQ   r   r*   r=   )#
__future__r   typingr   r   r   r   r   rT   numpyrD   
ezdxf.mathr	   r
   r:   r   construct2dr   r6   r   r   r   r   r   r   ezdxf.entitiesr   ezdxf.layoutsr   __all__pir`   r   r   r   r   r)   r'   <module>r      s   # " " " " " H H H H H H H H H H H H H H      ! ! ! ! ! ! ! !       ) ) ) ) ) ) & & & & & & 3 3 3 3 3 3 3 3       )""""""((((((
F
F
FTWs]DGTWs];a% a% a% a% a% a% a% a%H        r)   