o
    oÇh.  ã                   @   sØ   d dl mZ d dlmZ d dlmZmZ d dlmZm	Z	m
Z
mZ d dlmZ d dlmZ d dlmZ d dlZG d	d
„ d
eƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdd„ ZdS )é    )ÚBasic)Úsympify)ÚcosÚsin)ÚeyeÚ	rot_axis1Ú	rot_axis2Ú	rot_axis3)ÚImmutableDenseMatrix)Úcacheit)ÚStrNc                   @   s   e Zd ZdZdd„ ZdS )ÚOrienterz/
    Super-class for all orienter classes.
    c                 C   ó   | j S )zV
        The rotation matrix corresponding to this orienter
        instance.
        )Ú_parent_orient©Úself© r   új/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/vector/orienters.pyÚrotation_matrix   s   zOrienter.rotation_matrixN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r      s    r   c                       sL   e Zd ZdZ‡ fdd„Zdd„ Zedd„ ƒZedd	„ ƒZ	ed
d„ ƒZ
‡  ZS )ÚAxisOrienterz+
    Class to denote an axis orienter.
    c                    s>   t |tjjƒstdƒ‚t|ƒ}tƒ  | ||¡}||_||_	|S )Nzaxis should be a Vector)
Ú
isinstanceÚsympyÚvectorÚVectorÚ	TypeErrorr   ÚsuperÚ__new__Ú_angleÚ_axis)ÚclsÚangleÚaxisÚobj©Ú	__class__r   r   r       s   zAxisOrienter.__new__c                 C   ó   dS )aá  
        Axis rotation is a rotation about an arbitrary axis by
        some angle. The angle is supplied as a SymPy expr scalar, and
        the axis is supplied as a Vector.

        Parameters
        ==========

        angle : Expr
            The angle by which the new system is to be rotated

        axis : Vector
            The axis around which the rotation has to be performed

        Examples
        ========

        >>> from sympy.vector import CoordSys3D
        >>> from sympy import symbols
        >>> q1 = symbols('q1')
        >>> N = CoordSys3D('N')
        >>> from sympy.vector import AxisOrienter
        >>> orienter = AxisOrienter(q1, N.i + 2 * N.j)
        >>> B = N.orient_new('B', (orienter, ))

        Nr   )r   r$   r%   r   r   r   Ú__init__(   s   zAxisOrienter.__init__c                 C   s˜   t j | j|¡ ¡ }| |¡}| j}tdƒ||j  t	|ƒ t
d|d  |d g|d d|d  g|d  |d dggƒt|ƒ  ||j  }|j}|S )zø
        The rotation matrix corresponding to this orienter
        instance.

        Parameters
        ==========

        system : CoordSys3D
            The coordinate system wrt which the rotation matrix
            is to be computed
        é   r   é   é   )r   r   Úexpressr%   Ú	normalizeÚ	to_matrixr$   r   ÚTr   ÚMatrixr   )r   Úsystemr%   ÚthetaÚparent_orientr   r   r   r   F   s   
þþÿüzAxisOrienter.rotation_matrixc                 C   r   ©N)r!   r   r   r   r   r$   _   ó   zAxisOrienter.anglec                 C   r   r6   )r"   r   r   r   r   r%   c   r7   zAxisOrienter.axis)r   r   r   r   r    r*   r   r   Úpropertyr$   r%   Ú__classcell__r   r   r'   r   r      s    

r   c                       sP   e Zd ZdZ‡ fdd„Zedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZ	‡  Z
S )ÚThreeAngleOrienterz3
    Super-class for Body and Space orienters.
    c                    s<  t |tƒr|j}d}|}t|ƒ ¡ }t|ƒdkstdƒ‚dd„ |D ƒ}dd„ |D ƒ}dd„ |D ƒ}d |¡}||vr>td	ƒ‚t|d
 ƒ}t|d ƒ}t|d ƒ}	t	|ƒ}t	|ƒ}t	|ƒ}| j
rot||ƒt||ƒ t|	|ƒ }
nt|	|ƒt||ƒ t||ƒ }
|
j}
tƒ  | |||t|ƒ¡}||_||_||_||_|
|_|S )N)Ú123Ú231Ú312Ú132Ú213Ú321Ú121Ú131Ú212Ú232Ú313Ú323Ú r+   z%rot_order should be a str of length 3c                 S   ó   g | ]}|  d d¡‘qS )ÚXÚ1©Úreplace©Ú.0Úir   r   r   Ú
<listcomp>x   ó    z.ThreeAngleOrienter.__new__.<locals>.<listcomp>c                 S   rH   )ÚYÚ2rK   rM   r   r   r   rP   y   rQ   c                 S   rH   )ÚZÚ3rK   rM   r   r   r   rP   z   rQ   rG   zInvalid rot_type parameterr   r-   r,   )r   r   ÚnameÚstrÚupperÚlenr   ÚjoinÚintr   Ú	_in_orderÚ_rotr1   r   r    Ú_angle1Ú_angle2Ú_angle3Ú
_rot_orderr   )r#   Úangle1Úangle2Úangle3Ú	rot_orderÚapproved_ordersÚoriginal_rot_orderÚa1Úa2Úa3r5   r&   r'   r   r   r    m   sP   

ÿþÿþÿzThreeAngleOrienter.__new__c                 C   r   r6   )r^   r   r   r   r   rb   ˜   r7   zThreeAngleOrienter.angle1c                 C   r   r6   )r_   r   r   r   r   rc   œ   r7   zThreeAngleOrienter.angle2c                 C   r   r6   )r`   r   r   r   r   rd       r7   zThreeAngleOrienter.angle3c                 C   r   r6   )ra   r   r   r   r   re   ¤   r7   zThreeAngleOrienter.rot_order)r   r   r   r   r    r8   rb   rc   rd   re   r9   r   r   r'   r   r:   h   s    +


r:   c                   @   ó$   e Zd ZdZdZdd„ Zdd„ ZdS )ÚBodyOrienterz*
    Class to denote a body-orienter.
    Tc                 C   ó   t  | ||||¡}|S r6   ©r:   r    ©r#   rb   rc   rd   re   r&   r   r   r   r    °   ó   ÿzBodyOrienter.__new__c                 C   r)   )a’  
        Body orientation takes this coordinate system through three
        successive simple rotations.

        Body fixed rotations include both Euler Angles and
        Tait-Bryan Angles, see https://en.wikipedia.org/wiki/Euler_angles.

        Parameters
        ==========

        angle1, angle2, angle3 : Expr
            Three successive angles to rotate the coordinate system by

        rotation_order : string
            String defining the order of axes for rotation

        Examples
        ========

        >>> from sympy.vector import CoordSys3D, BodyOrienter
        >>> from sympy import symbols
        >>> q1, q2, q3 = symbols('q1 q2 q3')
        >>> N = CoordSys3D('N')

        A 'Body' fixed rotation is described by three angles and
        three body-fixed rotation axes. To orient a coordinate system D
        with respect to N, each sequential rotation is always about
        the orthogonal unit vectors fixed to D. For example, a '123'
        rotation will specify rotations about N.i, then D.j, then
        D.k. (Initially, D.i is same as N.i)
        Therefore,

        >>> body_orienter = BodyOrienter(q1, q2, q3, '123')
        >>> D = N.orient_new('D', (body_orienter, ))

        is same as

        >>> from sympy.vector import AxisOrienter
        >>> axis_orienter1 = AxisOrienter(q1, N.i)
        >>> D = N.orient_new('D', (axis_orienter1, ))
        >>> axis_orienter2 = AxisOrienter(q2, D.j)
        >>> D = D.orient_new('D', (axis_orienter2, ))
        >>> axis_orienter3 = AxisOrienter(q3, D.k)
        >>> D = D.orient_new('D', (axis_orienter3, ))

        Acceptable rotation orders are of length 3, expressed in XYZ or
        123, and cannot have a rotation about about an axis twice in a row.

        >>> body_orienter1 = BodyOrienter(q1, q2, q3, '123')
        >>> body_orienter2 = BodyOrienter(q1, q2, 0, 'ZXZ')
        >>> body_orienter3 = BodyOrienter(0, 0, 0, 'XYX')

        Nr   ©r   rb   rc   rd   re   r   r   r   r*   µ   s   7zBodyOrienter.__init__N©r   r   r   r   r\   r    r*   r   r   r   r   rl   ©   ó
    rl   c                   @   rk   )ÚSpaceOrienterz+
    Class to denote a space-orienter.
    Fc                 C   rm   r6   rn   ro   r   r   r   r    ö   rp   zSpaceOrienter.__new__c                 C   r)   )a¢  
        Space rotation is similar to Body rotation, but the rotations
        are applied in the opposite order.

        Parameters
        ==========

        angle1, angle2, angle3 : Expr
            Three successive angles to rotate the coordinate system by

        rotation_order : string
            String defining the order of axes for rotation

        See Also
        ========

        BodyOrienter : Orienter to orient systems wrt Euler angles.

        Examples
        ========

        >>> from sympy.vector import CoordSys3D, SpaceOrienter
        >>> from sympy import symbols
        >>> q1, q2, q3 = symbols('q1 q2 q3')
        >>> N = CoordSys3D('N')

        To orient a coordinate system D with respect to N, each
        sequential rotation is always about N's orthogonal unit vectors.
        For example, a '123' rotation will specify rotations about
        N.i, then N.j, then N.k.
        Therefore,

        >>> space_orienter = SpaceOrienter(q1, q2, q3, '312')
        >>> D = N.orient_new('D', (space_orienter, ))

        is same as

        >>> from sympy.vector import AxisOrienter
        >>> axis_orienter1 = AxisOrienter(q1, N.i)
        >>> B = N.orient_new('B', (axis_orienter1, ))
        >>> axis_orienter2 = AxisOrienter(q2, N.j)
        >>> C = B.orient_new('C', (axis_orienter2, ))
        >>> axis_orienter3 = AxisOrienter(q3, N.k)
        >>> D = C.orient_new('C', (axis_orienter3, ))

        Nr   rq   r   r   r   r*   û   s   0zSpaceOrienter.__init__Nrr   r   r   r   r   rt   ï   rs   rt   c                       sX   e Zd ZdZ‡ fdd„Zdd„ Zedd„ ƒZedd	„ ƒZed
d„ ƒZ	edd„ ƒZ
‡  ZS )ÚQuaternionOrienterz0
    Class to denote a quaternion-orienter.
    c                    s0  t |ƒ}t |ƒ}t |ƒ}t |ƒ}t|d |d  |d  |d  d|| ||   d|| ||   gd|| ||   |d |d  |d  |d  d|| ||   gd|| ||   d|| ||   |d |d  |d  |d  ggƒ}|j}tƒ  | ||||¡}||_||_||_||_||_	|S )Nr,   )
r   r2   r1   r   r    Ú_q0Ú_q1Ú_q2Ú_q3r   )r#   Úq0Úq1Úq2Úq3r5   r&   r'   r   r   r    3  sF   ÿýÿÿýÿÿþøzQuaternionOrienter.__new__c                 C   r)   )a¨  
        Quaternion orientation orients the new CoordSys3D with
        Quaternions, defined as a finite rotation about lambda, a unit
        vector, by some amount theta.

        This orientation is described by four parameters:

        q0 = cos(theta/2)

        q1 = lambda_x sin(theta/2)

        q2 = lambda_y sin(theta/2)

        q3 = lambda_z sin(theta/2)

        Quaternion does not take in a rotation order.

        Parameters
        ==========

        q0, q1, q2, q3 : Expr
            The quaternions to rotate the coordinate system by

        Examples
        ========

        >>> from sympy.vector import CoordSys3D
        >>> from sympy import symbols
        >>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
        >>> N = CoordSys3D('N')
        >>> from sympy.vector import QuaternionOrienter
        >>> q_orienter = QuaternionOrienter(q0, q1, q2, q3)
        >>> B = N.orient_new('B', (q_orienter, ))

        Nr   rq   r   r   r   r*   O  s   %zQuaternionOrienter.__init__c                 C   r   r6   )rv   r   r   r   r   rz   v  r7   zQuaternionOrienter.q0c                 C   r   r6   )rw   r   r   r   r   r{   z  r7   zQuaternionOrienter.q1c                 C   r   r6   )rx   r   r   r   r   r|   ~  r7   zQuaternionOrienter.q2c                 C   r   r6   )ry   r   r   r   r   r}   ‚  r7   zQuaternionOrienter.q3)r   r   r   r   r    r*   r8   rz   r{   r|   r}   r9   r   r   r'   r   ru   .  s    '


ru   c                 C   sF   | dkrt t|ƒjƒS | dkrt t|ƒjƒS | dkr!t t|ƒjƒS dS )z)DCM for simple axis 1, 2 or 3 rotations. r-   r,   r+   N)r2   r   r1   r   r	   )r%   r$   r   r   r   r]   ‡  s   ÿr]   )Úsympy.core.basicr   Úsympy.core.sympifyr   Ú(sympy.functions.elementary.trigonometricr   r   Úsympy.matrices.denser   r   r   r	   Úsympy.matrices.immutabler
   r2   Úsympy.core.cacher   Úsympy.core.symbolr   Úsympy.vectorr   r   r   r:   rl   rt   ru   r]   r   r   r   r   Ú<module>   s    PAF?Y