Ë
    £èhyl  ã                  ó@  — d dl mZ d dlmZmZmZmZ d dl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 g d¢Ze	j*                  dz  Zd*d+d	„Z	 d,	 	 	 	 	 d-d„Z	 d.	 	 	 d/d„Zd0d„Zd1d„Zd2d„Zd3d„Z	 	 d4	 	 	 	 	 	 	 	 	 d5d„Z	 	 	 d6	 	 	 	 	 	 	 d7d„ZdZ  G d„ de«      Z! G d„ d«      Z"d
e dœ	 	 	 	 	 d8d„Z#d
d
e dœ	 	 	 	 	 	 	 d9d„Z$d
e dœ	 	 	 	 	 	 	 d:d„Z%	 	 	 	 	 	 	 	 	 	 d;d„Z& G d„ d«      Z'd<d „Z(d=d!„Z)d>d"„Z*d?d#„Z+efd@d$„Z,d1d%„Z-e d&œ	 	 	 	 	 dAd'„Z.e d&œ	 	 	 	 	 dBd(„Z/dCd)„Z0y)Dé    )Úannotations)ÚSequenceÚIterableÚOptionalÚIterator)ÚIntEnumN)ÚVec3ÚVec2ÚMatrix44ÚX_AXISÚY_AXISÚZ_AXISÚUVec)Úis_planar_faceÚsubdivide_faceÚsubdivide_ngonsÚPlaneÚPlaneLocationStateÚnormal_vector_3pÚsafe_normal_vectorÚdistance_point_line_3dÚintersection_line_line_3dÚintersection_ray_polygon_3dÚintersection_line_polygon_3dÚbasic_transformationÚbest_fit_normalÚBarycentricCoordinatesÚlinear_vertex_spacingÚhas_matrix_3d_stretchingÚspherical_envelopeÚinscribe_circle_tangent_lengthÚbending_angleÚsplit_polygon_by_planeÚ is_face_normal_pointing_outwardsÚis_vertex_order_ccw_3dç       @ç•Ö&è.>c                ó8  — t        | «      dk  ryt        | «      dk(  ryd}t        t        | «      dz
  «      D ]N  }| ||dz    \  }}}	 ||z
  j                  ||z
  «      j                  «       }|€|}Œ:|j                  ||¬«      rŒN y |�yy# t        $ r Y Œ`w xY w)zµReturns ``True`` if sequence of vectors is a planar face.

    Args:
         face: sequence of :class:`~ezdxf.math.Vec3` objects
         abs_tol: tolerance for normals check

    é   FTNé   ©Úabs_tol)ÚlenÚrangeÚcrossÚ	normalizeÚZeroDivisionErrorÚisclose)Úfacer,   Úfirst_normalÚindexÚaÚbÚcÚnormals           ú6lib/python3.12/site-packages/ezdxf/math/construct3d.pyr   r   /   s»   € ô ˆ4ƒy�1‚}ØÜ
ˆ4ƒy�A‚~ØØ€LÜ”s˜4“y 1‘}Ö%ˆØ�u˜u q™yÐ)‰ˆˆ1ˆað	Ø˜!‘e—]‘] 1 q¡5Ó)×3Ñ3Ó5ˆFð ÐØ!‰LØ×%Ñ% f°gÐ%Õ>Ùð &ð ÐØØøô !ò 	Ùð	ús   Á%BÂ	BÂBTc              #  óp  K  — t        | «      dk  rt        d«      ‚t        | «      }t        j                  | «      |z  }t	        |«      D �cg c]  }| |   j                  | |dz   |z     «      ‘Œ! }}t        | «      D ]0  \  }}|r|||   |||dz
     f–— Œ||dz
     ||f–— |||   |f–— Œ2 yc c}w ­w)z¿Subdivides faces by subdividing edges and adding a center vertex.

    Args:
        face: a sequence of :class:`Vec3`
        quads: create quad faces if ``True`` else create triangles

    r)   z3 or more vertices required.é   N)r-   Ú
ValueErrorr	   Úsumr.   ÚlerpÚ	enumerate)r3   ÚquadsÚlen_faceÚmid_posÚiÚsubdiv_locationr5   Úvertexs           r:   r   r   K   s×   è ø€ ô ˆ4ƒy�1‚}ÜÐ7Ó8Ð8ä˜“I€HÜ�h‰h�t‹n˜xÑ'€Gä8=¸h¼ó#Ù8G°1ˆˆQ‰�‰�T˜1˜q™5 HÑ,Ñ-Õ.¸ð ð #ô # 4ž‰ˆˆvÙØ˜/¨%Ñ0°'¸?È5ÐSTÉ9Ñ;UÐUÓUà! %¨!¡)Ñ,¨f°gÐ=Ò=Ø˜/¨%Ñ0°'Ð9Ó9ñ )ùò	#ùs   ‚A
B6Á$B1Á0AB6c              #  óè   K  — | D ]i  }t        |«      |k  rt        j                  |«      –— Œ)t        j                  |«      t        |«      z  }t	        |«      D ]  \  }}||dz
     ||f–— Œ Œk y­w)zËSubdivides faces into triangles by adding a center vertex.

    Args:
        faces: iterable of faces as sequence of :class:`Vec3`
        max_vertex_count: subdivide only ngons with more vertices

    r<   N)r-   r	   Útupler>   r@   )ÚfacesÚmax_vertex_countr3   rC   r5   rF   s         r:   r   r   f   sk   è ø€ ó ˆÜˆt‹9Ð(Ò(Ü—*‘*˜TÓ"Ó"ä—h‘h˜t“n¤s¨4£yÑ0ˆGÜ!*¨4¦‘��vØ˜5 1™9‘o v¨wÐ6Ó6ñ "1ñ ùs   ‚A0A2c                óL   — || z
  j                  || z
  «      j                  «       S )zlReturns normal vector for 3 points, which is the normalized cross
    product for: :code:`a->b x a->c`.
    )r/   r0   )r6   r7   r8   s      r:   r   r   z   s$   € ð �‰E�=‰=˜˜Q™Ó×)Ñ)Ó+Ð+ó    c                óÀ   — t        | «      dk  rt        d«      ‚| ^}}}}	 ||z
  j                  ||z
  «      j                  «       S # t        $ r t        | «      cY S w xY w)zjSafe function to detect the normal vector for a face or polygon defined
    by 3 or more `vertices`.

    r)   ú3 or more vertices required)r-   r=   r/   r0   r1   r   )Úverticesr6   r7   r8   Ú_s        r:   r   r   �   sh   € ô
 ˆ8ƒ}�qÒÜÐ6Ó7Ð7Ø€K€A€qˆ!ˆað)Ø�A‘�}‰}˜Q ™UÓ#×-Ñ-Ó/Ð/øÜò )Ü˜xÓ(Ò(ð)ús   ¡$A ÁAÁAc                ó¨  — t        j                  | «      }t        |«      dk  rt        d«      ‚|d   }|j	                  |d   «      s|j                  |«       |j                  \  }}}d}d}d}|dd D ]B  }	|	j                  \  }
}}|||z   ||z
  z  z  }|||
z   ||z
  z  z  }|||z   ||
z
  z  z  }|
}|}|}ŒD t        |||«      j                  «       S )zÕReturns the "best fit" normal for a plane defined by three or more
    vertices. This function tolerates imperfect plane vertices. Safe function
    to detect the extrusion vector of flat arbitrary polygons.

    r)   rN   r   éÿÿÿÿç        r<   N)r	   Úlistr-   r=   r2   ÚappendÚxyzr0   )rO   Ú	_verticesÚfirstÚprev_xÚprev_yÚprev_zÚnxÚnyÚnzÚvÚxÚyÚzs                r:   r   r   �   sý   € ô —	‘	˜(Ó#€IÜ
ˆ9ƒ~˜ÒÜÐ6Ó7Ð7Ø�a‰L€EØ�=‰=˜ 2™Ô'Ø×Ñ˜ÔØ"ŸY™YÑ€FˆF�FØ	€BØ	€BØ	€BØ�q�r‹]ˆØ—%‘%‰ˆˆ1ˆaØ
ˆv˜‰z˜f q™jÑ)Ñ)ˆØ
ˆv˜‰z˜f q™jÑ)Ñ)ˆØ
ˆv˜‰z˜f q™jÑ)Ñ)ˆØˆØˆØ‰ð ô ��B˜Ó×%Ñ%Ó'Ð'rL   c                óÔ   — |j                  |«      rt        d«      ‚| |z
  }||z
  j                  |«      }|j                  |j                  z
  }|dk  ryt	        j
                  |«      S )z¶Returns the normal distance from a `point` to a 3D line.

    Args:
        point: point to test
        start: start point of the 3D line
        end: end point of the 3D line

    zNot a line.rS   )r2   r1   ÚprojectÚmagnitude_squareÚmathÚsqrt)ÚpointÚstartÚendÚv1Úv2Údiffs         r:   r   r   «   sh   € ð ‡}�}�SÔÜ Ó.Ð.Ø	�‰€Bà
�‰+×	Ñ	˜rÓ	"€Bà×Ñ ×!4Ñ!4Ñ4€DØˆs‚{ð ä�y‰y˜‹ÐrL   c                ó¸   — ddl m}m}  || ||«      }t        |«      dk7  ry|d   }|r|S  || «      j	                  |«      r ||«      j	                  |«      r|S y)a´  
    Returns the intersection point of two 3D lines, returns ``None`` if lines
    do not intersect.

    Args:
        line1: first line as tuple of two points as :class:`Vec3` objects
        line2: second line as tuple of two points as :class:`Vec3` objects
        virtual: ``True`` returns any intersection point, ``False`` returns only
            real intersection points
        abs_tol: absolute tolerance for comparisons

    r   )Úintersection_ray_ray_3dÚBoundingBoxr<   N)Ú
ezdxf.mathro   rp   r-   Úinside)Úline1Úline2Úvirtualr,   ro   rp   Úresrh   s           r:   r   r   Ã   sb   € ÷$ @á
! %¨°Ó
8€CÜ
ˆ3ƒx�1‚}Øà�‰F€EÙØˆÙ�5Ó× Ñ  Ô'©K¸Ó,>×,EÑ,EÀeÔ,LØˆØrL   c                ó$  — t        |«      \  }}}t        j                  |||«      }|r|t        j                  |«      z  }t        | «      }|j                  s8|t        j
                  |j                  |j                  |j                  «      z  }|S )a  Returns a combined transformation matrix for translation, scaling and
    rotation about the z-axis.

    Args:
        move: translation vector
        scale: x-, y- and z-axis scaling as float triplet, e.g. (2, 2, 1)
        z_rotation: rotation angle about the z-axis in radians

    )	r	   r   ÚscaleÚz_rotateÚis_nullÚ	translater`   ra   rb   )Úmoverx   Ú
z_rotationÚsxÚsyÚszÚmr{   s           r:   r   r   ã   sy   € ô �e“�J€BˆˆBÜ�‰�r˜2˜rÓ"€AÙØ	ŒX×Ñ˜zÓ*Ñ*ˆÜ�T“
€IØ×ÒØ	ŒX×Ñ 	§¡¨Y¯[©[¸)¿+¹+ÓFÑFˆØ€HrL   c                  ó   — e Zd ZdZdZdZdZy)r   r   r<   r*   r)   N)Ú__name__Ú
__module__Ú__qualname__ÚCOPLANARÚFRONTÚBACKÚSPANNING© rL   r:   r   r   þ   s   „ Ø€HØ€EØ€DØ�HrL   r   c                  óè   — e Zd ZdZdZdd„Zedd„«       Zedd„«       Zedd„«       Z	e
dd„«       Ze
dd„«       Zdd	„ZeZd
„ Zdd„Zdd„Zdd„Zddd„Zdd d„Zdedœ	 	 	 	 	 d!d„Zd"d„Zef	 	 	 d#d„Zy)$r   z�Construction tool for 3D planes.

    Represents a plane in 3D space as a normal vector and the perpendicular
    distance from the origin.
    ©Ú_normalÚ_distance_from_originc                óJ   — |j                   du sJ d«       ‚|| _        || _        y )NFzinvalid plane normal)rz   r�   rŽ   )Úselfr9   Údistances      r:   Ú__init__zPlane.__init__  s)   € Ø�~‰~ Ñ&Ð>Ð(>Ó>Ð&ØˆŒà%-ˆÕ"rL   c                ó   — | j                   S )zNormal vector of the plane.)r�   ©r�   s    r:   r9   zPlane.normal  s   € ð �|‰|ÐrL   c                ó   — | j                   S )z@The (perpendicular) distance of the plane from origin (0, 0, 0).)rŽ   r”   s    r:   Údistance_from_originzPlane.distance_from_origin  s   € ð ×)Ñ)Ð)rL   c                ó4   — | j                   | j                  z  S )zReturns the location vector.rŒ   r”   s    r:   ÚvectorzPlane.vector  s   € ð �|‰|˜d×8Ñ8Ñ8Ð8rL   c                ó´   — 	 ||z
  j                  ||z
  «      j                  «       }t	        ||j                  |«      «      S # t        $ r t        d«      ‚w xY w)z+Returns a new plane from 3 points in space.z"undefined plane: colinear vertices)r/   r0   r1   r=   r   Údot)Úclsr6   r7   r8   Úns        r:   Úfrom_3pzPlane.from_3p#  s]   € ð	CØ�Q‘—‘˜a !™eÓ$×.Ñ.Ó0ˆAô �Q˜Ÿ™˜a›Ó!Ð!øô !ò 	CÜÐAÓBÐBð	Cús   ‚%A ÁAc                ó’   — t        |«      }	 t        |j                  «       |j                  «      S # t        $ r t        d«      ‚w xY w)z3Returns a new plane from the given location vector.zinvalid NULL vector)r	   r   r0   Ú	magnituder1   r=   )r›   r˜   r_   s      r:   Úfrom_vectorzPlane.from_vector,  sD   € ô �‹Lˆð	4Ü˜Ÿ™›¨¯©Ó4Ð4øÜ ò 	4ÜÐ2Ó3Ð3ð	4ús	   �#1 ±Ac                óN   — | j                  | j                  | j                  «      S )zReturns a copy of the plane.)Ú	__class__r�   rŽ   r”   s    r:   Ú__copy__zPlane.__copy__5  s   € à�~‰~˜dŸl™l¨D×,FÑ,FÓGÐGrL   c                óN   — dt        | j                  «      › d| j                  › d�S )NzPlane(z, Ú))Úreprr�   rŽ   r”   s    r:   Ú__repr__zPlane.__repr__;  s(   € Øœ˜TŸ\™\Ó*Ð+¨2¨d×.HÑ.HÐ-IÈÐKÐKrL   c                ó`   — t        |t        «      st        S | j                  |j                  k(  S ©N)Ú
isinstancer   ÚNotImplementedr˜   )r�   Úothers     r:   Ú__eq__zPlane.__eq__>  s%   € Ü˜%¤Ô'Ü!Ð!Ø�{‰{˜eŸl™lÑ*Ð*rL   c                óR   — | j                   j                  |«      | j                  z
  S )a  Returns signed distance of vertex `v` to plane, if distance is > 0,
        `v` is in 'front' of plane, in direction of the normal vector, if
        distance is < 0, `v` is at the 'back' of the plane, in the opposite
        direction of the normal vector.

        )r�   rš   rŽ   ©r�   r_   s     r:   Úsigned_distance_tozPlane.signed_distance_toC  s$   € ð �|‰|×Ñ Ó" T×%?Ñ%?Ñ?Ð?rL   c                óJ   — t        j                  | j                  |«      «      S )z<Returns absolute (unsigned) distance of vertex `v` to plane.)rf   Úfabsr°   r¯   s     r:   Údistance_tozPlane.distance_toL  s   € ä�y‰y˜×0Ñ0°Ó3Ó4Ð4rL   c                ó*   — | j                  |«      |k  S )zdReturns ``True`` if vertex `v` is coplanar, distance from plane to
        vertex `v` is 0.
        )r³   )r�   r_   r,   s      r:   Úis_coplanar_vertexzPlane.is_coplanar_vertexP  s   € ð ×Ñ Ó" WÑ,Ð,rL   c                ó„   — | j                   j                  } ||j                   |¬«      xs  ||j                    |¬«      S )ziReturns ``True`` if plane `p` is coplanar, normal vectors in same or
        opposite direction.
        r+   )r�   r2   )r�   Úpr,   Ú
n_is_closes       r:   Úis_coplanar_planezPlane.is_coplanar_planeV  s=   € ð —\‘\×)Ñ)ˆ
Ù˜!Ÿ)™)¨WÔ5ò 
¹Ø�Y‰YˆJ ô:
ð 	
rL   T©Úcoplanarr,   c               óD  — | j                  ||«      }| j                  ||«      }||u ry|s%|t        j                  u s|t        j                  u ry| j                  }| j                  |j                  |«      z
  |j                  ||z
  «      z  }|j                  ||«      S )a  Returns the intersection point of the 3D line from `start` to `end`
        and this plane or ``None`` if there is no intersection. If the argument
        `coplanar` is ``False`` the start- or end point of the line are ignored
        as intersection points.

        N)Úvertex_location_stater   r†   r9   r–   rš   r?   )	r�   ri   rj   r»   r,   Ústate0Ústate1rœ   Úweights	            r:   Úintersect_linezPlane.intersect_line_  s›   € ð ×+Ñ+¨E°7Ó;ˆØ×+Ñ+¨C°Ó9ˆØ�VÑØÙØÔ(×1Ñ1Ñ1ØÔ+×4Ñ4Ñ4àØ�K‰KˆØ×+Ñ+¨a¯e©e°E«lÑ:¸a¿e¹eÀCÈ%ÁKÓ>PÑPˆØ�z‰z˜#˜vÓ&Ð&rL   c                óª   — | j                   }	 | j                  |j                  |«      z
  |j                  |«      z  }|||z  z   S # t        $ r Y yw xY w)zãReturns the intersection point of the infinite 3D ray defined by
        `origin` and the `direction` vector and this plane or ``None`` if there
        is no intersection. A coplanar ray does not intersect the plane!

        N)r9   r–   rš   r1   )r�   ÚoriginÚ	directionrœ   rÀ   s        r:   Úintersect_rayzPlane.intersect_rayu  s^   € ð �K‰Kˆð	Ø×/Ñ/°!·%±%¸³-Ñ?À1Ç5Á5ÈÓCSÑSˆFð ˜ VÑ+Ñ,Ð,øô !ò 	Ùð	ús   Ž0A Á	AÁAc                óÈ   — | j                   j                  |«      | j                  z
  }|| k  rt        j                  S ||kD  rt        j
                  S t        j                  S )zjReturns the :class:`PlaneLocationState` of the given `vertex` in
        relative to this plane.

        )r�   rš   rŽ   r   rˆ   r‡   r†   )r�   rF   r,   r‘   s       r:   r½   zPlane.vertex_location_state‚  sY   € ð —<‘<×#Ñ# FÓ+¨d×.HÑ.HÑHˆØ�w�hÒÜ%×*Ñ*Ð*Ø˜ÒÜ%×+Ñ+Ð+ä%×.Ñ.Ð.rL   N)r9   r	   r‘   Úfloat)Úreturnr	   ©rÈ   rÇ   )r6   r	   r7   r	   r8   r	   rÈ   ú'Plane')r˜   r   rÈ   rÊ   )rÈ   rÊ   )r¬   ÚobjectrÈ   Úbool)r_   r	   rÈ   rÇ   ©r'   )r_   r	   rÈ   rÌ   )r·   rÊ   rÈ   rÌ   )ri   r	   rj   r	   rÈ   úOptional[Vec3])rÃ   r	   rÄ   r	   rÈ   rÎ   )rF   r	   rÈ   r   )rƒ   r„   r…   Ú__doc__Ú	__slots__r’   Úpropertyr9   r–   r˜   Úclassmethodr�   r    r£   Úcopyr§   r­   r°   r³   rµ   r¹   ÚPLANE_EPSILONrÁ   rÅ   r½   rŠ   rL   r:   r   r     sç   „ ñð 5€Ió.ð òó ðð ò*ó ð*ð ò9ó ð9ð ò"ó ð"ð ò4ó ð4óHð €DòLó+ó
@ó5ô-ô
ð 37Àñ'Øð'Ø $ð'à	ó'ó,-ð %2ð/Øð/à	ô/rL   r   rº   c               ó"  — t         j                  }g }g }g }t        | «      }|j                  }	|j                  }
|D ]*  }|j                  ||«      }||z  }|j                  |«       Œ, |t         j                  k(  r*|�r|t        |«      }|
j                  |«      dkD  r|}�nY|}�nU|t         j                  k(  r|}�n>|t         j                  k(  r|}�n'|t         j                  k(  �rt        |«      }t        |«      D ]Ú  }|dz   |z  }||   }||   }||   }||   }|t         j                  k7  r|j                  |«       |t         j                  k7  r|j                  |«       ||z  t         j                  k(  sŒ~|	|
j                  |«      z
  |
j                  ||z
  «      z  }|j                  ||«      }|j                  |«       |j                  |«       ŒÜ t        |«      dk  rg }t        |«      dk  rg }t        |«      t        |«      fS )a7  Split a convex `polygon` by the given `plane`.

    Returns a tuple of front- and back vertices (front, back).
    Returns also coplanar polygons if the
    argument `coplanar` is ``True``, the coplanar vertices goes into either
    front or back depending on their orientation with respect to this plane.

    r   r<   r)   )r   r†   rT   r–   r9   r½   rU   r   rš   r‡   rˆ   r‰   r-   r.   r?   rH   )ÚpolygonÚplaner»   r,   Úpolygon_typeÚvertex_typesÚfront_verticesÚback_verticesrO   Úwr9   rF   Úvertex_typeÚpolygon_normalÚlen_verticesr5   Ú
next_indexÚnext_vertex_typeÚnext_vertexÚinterpolation_weightÚplane_intersection_points                        r:   r#   r#   ’  s  € ô &×.Ñ.€LØ-/€LØ!#€NØ "€MÜ�G‹}€HØ×"Ñ"€AØ�\‰\€Fó ˆØ×1Ñ1°&¸'ÓBˆØ˜Ñ#ˆØ×Ñ˜KÕ(ð ð Ô)×2Ñ2Ò2ÚÜ,¨XÓ6ˆNØ�z‰z˜.Ó)¨AÒ-Ø!)’à (’Ø	Ô+×1Ñ1Ò	1Ø!ŠØ	Ô+×0Ñ0Ò	0Ø ŠØ	Ô+×4Ñ4Ó	4Ü˜8“}ˆÜ˜<Ö(ˆEØ !™) |Ñ3ˆJØ& uÑ-ˆKØ+¨JÑ7ÐØ˜e‘_ˆFØ" :Ñ.ˆKØÔ0×5Ñ5Ò5Ø×%Ñ% fÔ-ØÔ0×6Ñ6Ò6Ø×$Ñ$ VÔ,ØÐ.Ñ.Ô3E×3NÑ3NÓNØ()¨F¯J©J°vÓ,>Ñ(>À&Ç*Á*Ø &Ñ(óCñ (Ð$ð ,2¯;©;ØÐ!5ó,Ð(ð ×%Ñ%Ð&>Ô?Ø×$Ñ$Ð%=Õ>ð% )ô& ˆ~Ó Ò"ØˆNÜˆ}Ó Ò!ØˆMÜ�Ó ¤%¨Ó"6Ð6Ð6rL   )r»   Úboundaryr,   c               ó
  — t        |«      }t        |«      dk  rt        d«      ‚	 t        |«      }t        ||j                  |d   «      «      }|j                  | |||¬«      }	|	€yt        |	||||«      S # t        $ r Y yw xY w)a  Returns the intersection point of the 3D line form `start` to `end` and
    the given `polygon`.

    Args:
        start: start point of 3D line as :class:`Vec3`
        end: end point of 3D line as :class:`Vec3`
        polygon: 3D polygon as iterable of :class:`Vec3`
        coplanar: if ``True`` a coplanar start- or end point as intersection
            point is valid
        boundary: if ``True`` an intersection point at the polygon boundary line
            is valid
        abs_tol: absolute tolerance for comparisons

    r)   rN   Nr   rº   )	rT   r-   r=   r   r1   r   rš   rÁ   Ú(_is_intersection_point_inside_3d_polygon)
ri   rj   rÖ   r»   rå   r,   rO   r9   r×   Úips
             r:   r   r   Ø  sœ   € ô. �G‹}€HÜ
ˆ8ƒ}�qÒÜÐ6Ó7Ð7ðÜ# HÓ-ˆô �&˜&Ÿ*™* X¨a¡[Ó1Ó2€EØ	×	Ñ	˜e S°8ÀWÐ	Ó	M€BØ	€zØÜ3Ø
ˆH�f˜h¨óð øô ò Ùðús   ¦A6 Á6	BÂB©rå   r,   c               ó  — t        |«      }t        |«      dk  rt        d«      ‚	 t        |«      }t        ||j                  |d   «      «      }|j                  | |«      }|€yt        |||||«      S # t        $ r Y yw xY w)aã  Returns the intersection point of the infinite 3D ray defined by `origin`
    and the `direction` vector and the given `polygon`.

    Args:
        origin: origin point of the 3D ray as :class:`Vec3`
        direction: direction vector of the 3D ray as :class:`Vec3`
        polygon: 3D polygon as iterable of :class:`Vec3`
        boundary: if ``True`` intersection points at the polygon boundary line
            are valid
        abs_tol: absolute tolerance for comparisons

    r)   rN   Nr   )	rT   r-   r=   r   r1   r   rš   rÅ   rç   )	rÃ   rÄ   rÖ   rå   r,   rO   r9   r×   rè   s	            r:   r   r   ÿ  s•   € ô* �G‹}€HÜ
ˆ8ƒ}�qÒÜÐ6Ó7Ð7ðÜ# HÓ-ˆô �&˜&Ÿ*™* X¨a¡[Ó1Ó2€EØ	×	Ñ	˜V YÓ	/€BØ	€zØÜ3Ø
ˆH�f˜h¨óð øô ò Ùðús   ¦A3 Á3	A?Á>A?c                óÎ   — ddl m}m}  ||«      }t        j                  |j                  |«      «      } |t        |j                  | «      «      ||¬«      }	|	dkD  s|r|	dk(  r| S y )Nr   )Úis_point_in_polygon_2dÚOCSr+   )rq   rì   rí   r
   rT   Úpoints_from_wcsÚfrom_wcs)
rè   rO   r9   rå   r,   rì   rí   ÚocsÚocs_verticesÚstates
             r:   rç   rç   $  sa   € ÷ 7á
ˆf‹+€CÜ—9‘9˜S×0Ñ0°Ó:Ó;€LÙ"ÜˆS�\‰\˜"ÓÓ °gô€Eð ˆq‚y‘X %¨1¢*Øˆ	ØrL   c                  ó(   — e Zd ZdZdd„Zdd„Zdd„Zy)	r   ah  Barycentric coordinate calculation.

    The arguments `a`, `b` and `c` are the cartesian coordinates of an arbitrary
    triangle in 3D space. The barycentric coordinates (b1, b2, b3) define the
    linear combination of `a`, `b` and `c` to represent the point `p`::

        p = a * b1 + b * b2 + c * b3

    This implementation returns the barycentric coordinates of the normal
    projection of `p` onto the plane defined by (a, b, c).

    These barycentric coordinates have some useful properties:

    - if all barycentric coordinates (b1, b2, b3) are in the range [0, 1], then
      the point `p` is inside the triangle (a, b, c)
    - if one of the coordinates is negative, the point `p` is outside the
      triangle
    - the sum of b1, b2 and b3 is always 1
    - the center of "mass" has the barycentric coordinates (1/3, 1/3, 1/3) =
      (a + b + c)/3

    c                ó  — t        |«      | _        t        |«      | _        t        |«      | _        | j                  | j                  z
  | _        | j                  | j                  z
  | _        | j                  | j                  z
  | _        | j                  j                  | j
                  «      }|j                  «       | _	        |j                  | j                  «      | _        t        | j                  «      dk  rt        d«      ‚y )Nr'   zinvalid triangle)r	   r6   r7   r8   Ú_e1Ú_e2Ú_e3r/   r0   Ú_nrš   Ú_denomÚabsr=   )r�   r6   r7   r8   Úe1xe2s        r:   r’   zBarycentricCoordinates.__init__M  s¶   € Ü�a“ˆŒÜ�a“ˆŒÜ�a“ˆŒØ—6‘6˜DŸF™F‘?ˆŒØ—6‘6˜DŸF™F‘?ˆŒØ—6‘6˜DŸF™F‘?ˆŒØ—‘—‘˜tŸx™xÓ(ˆØ—/‘/Ó#ˆŒØ—i‘i §¡Ó(ˆŒÜˆt�{‰{Ó˜dÒ"ÜÐ/Ó0Ð0ð #rL   c                óÊ  — t        |«      }| j                  }| j                  }|| j                  z
  }|| j                  z
  }|| j
                  z
  }| j                  j                  |«      j                  |«      |z  }| j                  j                  |«      j                  |«      |z  }| j                  j                  |«      j                  |«      |z  }	t        |||	«      S r©   )r	   rø   rù   r6   r7   r8   rõ   r/   rš   rö   r÷   )
r�   r·   rœ   ÚdenomÚd1Úd2Úd3Úb1Úb2Úb3s
             r:   Úfrom_cartesianz%BarycentricCoordinates.from_cartesianZ  s¹   € Ü�‹GˆØ�G‰GˆØ—‘ˆØ�—‘‰ZˆØ�—‘‰ZˆØ�—‘‰ZˆØ�X‰X�^‰^˜BÓ×#Ñ# AÓ&¨Ñ.ˆØ�X‰X�^‰^˜BÓ×#Ñ# AÓ&¨Ñ.ˆØ�X‰X�^‰^˜BÓ×#Ñ# AÓ&¨Ñ.ˆÜ�B˜˜BÓÐrL   c                ó’   — t        |«      j                  \  }}}| j                  |z  | j                  |z  z   | j                  |z  z   S r©   )r	   rV   r6   r7   r8   )r�   r7   r  r  r  s        r:   Úto_cartesianz#BarycentricCoordinates.to_cartesianf  s=   € Ü˜!“W—[‘[‰
ˆˆB�Ø�v‰v˜‰{˜TŸV™V b™[Ñ(¨4¯6©6°B©;Ñ6Ð6rL   N)r6   r   r7   r   r8   r   )r·   r   rÈ   r	   )r7   r   rÈ   r	   )rƒ   r„   r…   rÏ   r’   r  r  rŠ   rL   r:   r   r   3  s   „ ñó21ó
 ô7rL   r   c                ó  — |dk  r| |gS || z
  }|j                   r| g|z  S | g}|j                  |j                  |dz
  z  «      }t        d|dz
  «      D ]  }| |z  } |j	                  | «       Œ |j	                  |«       |S )z=Returns `count` evenly spaced vertices from `start` to `end`.r*   r<   )rz   r0   rŸ   r.   rU   )ri   rj   Úcountr‘   rO   ÚsteprP   s          r:   r   r   k  s”   € à�‚zØ�sˆ|ÐØ�U‰{€HØ×ÒØˆw˜‰Ðàˆw€HØ×Ñ˜h×0Ñ0°E¸A±IÑ>Ó?€DÜ�1�e˜a‘iÖ ˆØ�‰ˆØ�‰˜Õð !ð ‡O�O�CÔØ€OrL   c                ó  — | j                  t        «      j                  }| j                  t        «      }| j                  t        «      }t        j                  ||j                  «       xs! t        j                  ||j                  «       S )a4  Returns ``True`` if matrix `m` performs a non-uniform xyz-scaling.
    Uniform scaling is not stretching in this context.

    Does not check if the target system is a cartesian coordinate system, use the
    :class:`~ezdxf.math.Matrix44` property :attr:`~ezdxf.math.Matrix44.is_cartesian`
    for that.
    )Útransform_directionr   re   r   r   rf   r2   )r�   Ú
ux_mag_sqrÚuyÚuzs       r:   r   r   |  sx   € ð ×&Ñ&¤vÓ.×?Ñ?€JØ	
×	Ñ	œvÓ	&€BØ	
×	Ñ	œvÓ	&€BÜ�|‰|˜J¨×(;Ñ(;Ó<Ð<ò ÄDÇLÁLØ�B×'Ñ'óEð Að rL   c                óv   ‡— t        j                  | «      t        | «      z  Št        ˆfd„| D «       «      }‰|fS )zëCalculate the spherical envelope for the given points.  Returns the
    centroid (a.k.a. geometric center) and the radius of the enclosing sphere.

    .. note::

        The result does not represent the minimal bounding sphere!

    c              3  ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wr©   )r‘   )Ú.0r·   Úcentroids     €r:   Ú	<genexpr>z%spherical_envelope.<locals>.<genexpr>–  s   øè ø€ Ð6©v¨!�×"Ñ" 1×%©vùs   ƒ)r	   r>   r-   Úmax)ÚpointsÚradiusr  s     @r:   r    r    Œ  s7   ø€ ô �x‰x˜Ó¤# f£+Ñ-€HÜÓ6©vÓ6Ó6€FØ�VÐÐrL   c                óÆ   — | j                  |«      }t        |dz  z
  }t        j                  t	        |«      t        «      ryt	        t        j
                  |«      |z  «      S )a  Returns the tangent length of an inscribe-circle of the given `radius`.
    The direction `dir1` and `dir2` define two intersection tangents,
    The tangent length is the distance from the intersection point of the
    tangents to the touching point on the inscribe-circle.

    r&   rS   )Úangle_betweenÚPI2rf   r2   rú   Útan)Údir1Údir2r  ÚalphaÚbetas        r:   r!   r!   š  sO   € ð ×Ñ˜tÓ$€EÜ�%˜#‘+Ñ€DÜ‡|�|”C˜“IœsÔ#ØÜŒt�x‰x˜‹~ Ñ&Ó'Ð'rL   c                óÄ   — | j                  |«      }| j                  |«      }|j                  |«      s|j                  r|S |j                  | «      r| S t	        d«      ‚)zÏReturns the bending angle from `dir1` to `dir2` in radians.

    The normal vector is required to detect the bending orientation,
    an angle > 0 bends to the "left" an angle < 0 bends to the "right".

    zinvalid normal vector)r  r/   r2   rz   r=   )r  r  r9   ÚangleÚnns        r:   r"   r"   ¨  sZ   € ð ×Ñ˜tÓ$€EØ	�‰�DÓ	€BØ	‡z�z�&Ô˜RŸZšZØˆØ	�‰�V�GÔ	ØˆvˆÜ
Ð,Ó
-Ð-rL   c                ó`   — ddl m}  || «      }t        j                  t	        |«      «      dz  S )z6Returns a vertex from the "inside" of  the given face.r   )Úmapbox_earcut_3dg      @)Úezdxf.math.triangulationr#  r	   r>   Únext)rO   r#  Úits      r:   Úany_vertex_inside_facer'  ¸  s)   € õ :á	˜(Ó	#€BÜ�8‰8”D˜“HÓ Ñ#Ð#rL   r+   c               óV  ‡‡‡	— dˆˆfd„Š	t        |«      }t        |«      }t        ||j                  |«      «      Šˆ	fd„| D «       }t	        «       }|D ]J  }t        |||d‰¬«      }|€Œ‰j                  |«      ‰kD  sŒ+|j                  |j                  d«      «       ŒL t        |«      S )z±Returns the count of intersections of the normal-vector of the given
    `face` with the `faces` in front of this `face`.

    A counter-clockwise vertex order is assumed!

    c                óL   •— t        | «      dk  ryt        ˆˆfd„| D «       «      S )Nr)   Fc              3  óF   •K  — | ]  }‰j                  |«      ‰kD  –— Œ y ­wr©   )r°   )r  r_   r,   Údetector_planes     €€r:   r  zZfront_faces_intersect_face_normal.<locals>.is_face_in_front_of_detector.<locals>.<genexpr>Ñ  s"   øè ø€ ÐTÉ8Àa�>×4Ñ4°QÓ7¸'ÕAÉ8ùs   ƒ!)r-   Úany)rO   r,   r+  s    €€r:   Úis_face_in_front_of_detectorzGfront_faces_intersect_face_normal.<locals>.is_face_in_front_of_detectorÎ  s#   ø€ Üˆx‹=˜1ÒØÜÔTÉ8ÓTÓTÐTrL   c              3  ó4   •K  — | ]  } ‰|«      sŒ|–— Œ y ­wr©   rŠ   )r  Úfr-  s     €r:   r  z4front_faces_intersect_face_normal.<locals>.<genexpr>Ù  s   øè ø€ ÐG™e˜Ñ'CÀAÕ'F”1™eùs   ƒ‘Tré   é   )rO   úSequence[Vec3]rÈ   rÌ   )
r   r'  r   rš   Úsetr   r°   ÚaddÚroundr-   )
rI   r3   r,   Úface_normalrÃ   Úfront_facesÚintersection_pointsrè   r+  r-  s
     `     @@r:   Ú!front_faces_intersect_face_normalr8  Á  s­   ú€ öUô % TÓ*€KÜ# DÓ)€FÜ˜;¨¯©¸Ó(?Ó@€Nó H™eÓG€Kô
 &)£UÐÛˆÜ(Ø�K °¸gô
ˆð ˆ:ØØ×,Ñ,¨RÓ0°7Ó:ð  ×#Ñ# B§H¡H¨Q£KÕ0ð ô Ð"Ó#Ð#rL   c               ó*   — t        | ||¬«      dz  dk(  S )aP  Returns ``True`` if the face-normal for the given `face` of a
    closed surface is pointing outwards. A counter-clockwise vertex order is
    assumed, for faces with clockwise vertex order the result is inverted,
    therefore ``False`` is pointing outwards.

    This function does not check if the `faces` are a closed surface.

    r+   r*   r   )r8  )rI   r3   r,   s      r:   r$   r$   ì  s   € ô -¨U°DÀ'ÔJÈQÑNÐRSÑSÐSrL   c                ó,  ‡ ‡— t        ‰ «      dk  rt        d«      ‚dˆˆ fd„}t        |j                  «      t        |j                  «      t        |j
                  «      f}|j                  t        |«      «      Š |«       dkD  }|‰   }|r|dkD  S |dk  S )a  Returns ``True`` when the given 3D vertices have a counter-clockwise order around
    the given normal vector.

    Works for convex and concave shapes. Does not check or care if all vertices are
    located in a flat plane or if the normal vector is really perpendicular to the
    shape, but the result may be incorrect in that cases.

    Args:
        vertices (list): corner vertices of a flat shape (polygon)
        normal (Vec3): normal vector of the shape

    Raises:
        ValueError: input has less than 3 vertices

    r)   rN   c                 ó\  •— t        j                  ‰«      } ‰dk(  r| d d …df   | d d …df   }}n*‰dk(  r| d d …df   | d d …df   }}n| d d …df   | d d …df   }}t        j                  |t        j                  |d«      «      t        j                  |t        j                  |d«      «      z
  S )Nr   r<   r*   rR   )ÚnpÚarrayrš   Úroll)rÖ   r`   ra   ÚdomrO   s      €€r:   Úsigned_areaz+is_vertex_order_ccw_3d.<locals>.signed_area  sŸ   ø€ ä—(‘(˜8Ó$ˆØ�!Š8Øš1˜a˜4‘= 'ª!¨Q¨$¡-ˆq‰AØ�AŠXØš1˜a˜4‘= 'ª!¨Q¨$¡-ˆq‰Aàš1˜a˜4‘= 'ª!¨Q¨$¡-ˆqˆAä�v‰v�aœŸ™  B›Ó(¬2¯6©6°!´R·W±W¸QÀ³^Ó+DÑDÐDrL   r   rÉ   )r-   r=   rú   r`   ra   rb   r5   r  )rO   r9   r@  Úabs_axisÚccwÚdom_axisr?  s   `     @r:   r%   r%   ý  s…   ù€ ô  ˆ8ƒ}�qÒÜÐ6Ó7Ð7ö
Eô �6—8‘8‹}œc &§(¡(›m¬S°·±«]Ð:€HØ
�.‰.œ˜X›Ó
'€Cá
‹-˜!Ñ
€CØ�c‰{€HÙˆ8�a‰<Ð0 H¨q¡LÐ0rL   rÍ   )r3   r1  rÈ   rÌ   )T)r3   r1  rA   rÌ   rÈ   úIterator[Sequence[Vec3]])é   )rI   zIterable[Sequence[Vec3]]rÈ   rD  )r6   r	   r7   r	   r8   r	   rÈ   r	   )rO   r1  rÈ   r	   )rO   zIterable[UVec]rÈ   r	   )rh   r	   ri   r	   rj   r	   rÈ   rÇ   )Tg»½×Ùß|Û=)
rs   r1  rt   r1  ru   rÌ   r,   rÇ   rÈ   rÎ   ))r   r   r   )r<   r<   r<   r   )r|   r   rx   r   r}   rÇ   rÈ   r   )rÖ   úIterable[Vec3]r×   r   rÈ   z%tuple[Sequence[Vec3], Sequence[Vec3]])ri   r	   rj   r	   rÖ   rF  rÈ   rÎ   )rÃ   r	   rÄ   r	   rÖ   rF  rÈ   rÎ   )
rè   r	   rO   ú
list[Vec3]r9   r	   rå   rÌ   r,   rÇ   )ri   r	   rj   r	   r  ÚintrÈ   rG  )r�   r   rÈ   rÌ   )r  zSequence[UVec]rÈ   ztuple[Vec3, float])r  r	   r  r	   r  rÇ   rÈ   rÇ   )r  r	   r  r	   rÈ   rÇ   )rI   úSequence[Sequence[Vec3]]r3   r1  rÈ   rH  )rI   rI  r3   r1  rÈ   rÌ   )rO   rG  r9   r	   rÈ   rÌ   )1Ú
__future__r   Útypingr   r   r   r   Úenumr   rf   Únumpyr<  rq   r	   r
   r   r   r   r   r   Ú__all__Úpir  r   r   r   r   r   r   r   r   r   rÔ   r   r   r#   r   r   rç   r   r   r   r    r!   r"   r'  r8  r$   r%   rŠ   rL   r:   Ú<module>rP     se  ðõ #ß 9Ó 9Ý Û Û ÷÷ ñ ò€ð0 ‡g�g��m€ôð: )-ð:Ø
ð:Ø!%ð:àó:ð: ð7Ø#ð7ð ó7ó(,ó)ó(ó8ð6 Øð	Øðàðð ðð ð	ð
 óðB ØØðØ
ðàðð ðð ó	ð0 €ô˜ô ÷J/ñ J/ðb ØñC7ØðC7àðC7ð +óC7ðV ØØñ$Øð$à	ð$ð ð$ð ó$ðX Øñ"Øð"àð"ð ð"ð ó"ðJØðØ"ðØ,0ðØ<@ðØKPó÷57ñ 57ópó"ó ó(ð 28ô .ó $ð ñ	($Ø#ð($à
ð($ð
 	ó($ð^ ñ	TØ#ðTà
ðTð
 
óTô"'1rL   