
    g.                         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
e          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Zd ZdS )    )Basic)sympify)cossin)eye	rot_axis1	rot_axis2	rot_axis3)ImmutableDenseMatrix)cacheit)StrNc                       e Zd ZdZd ZdS )Orienterz/
    Super-class for all orienter classes.
    c                     | j         S )zV
        The rotation matrix corresponding to this orienter
        instance.
        )_parent_orientselfs    R/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/vector/orienters.pyrotation_matrixzOrienter.rotation_matrix   s    
 ""    N)__name__
__module____qualname____doc__r    r   r   r   r      s-         # # # # #r   r   c                   j     e Zd ZdZ fdZd Zed             Zed             Z	ed             Z
 xZS )AxisOrienterz+
    Class to denote an axis orienter.
    c                     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__s       r   r%   zAxisOrienter.__new__   s`    $ 344 	75666ggooc5$//
	
r   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*   s      r   __init__zAxisOrienter.__init__(   s	    8 	r   c                    t           j                            | j        |                                          }|                    |          }| j        }t          d          ||j        z  z
  t          |          z  t          d|d          |d         g|d         d|d          g|d          |d         dgg          t          |          z  z   ||j        z  z   }|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_orients        r   r   zAxisOrienter.rotation_matrixF   s     |##DIv66@@BB~~f%%
a&&4$&=0CJJ>!d1gXtAw!7"&q'1tAwh!7#'7(DGQ!7!9 : :<?JJGG 	'
 &r   c                     | j         S N)r&   r   s    r   r)   zAxisOrienter.angle_   s
    {r   c                     | j         S r<   )r'   r   s    r   r*   zAxisOrienter.axisc   s
    zr   )r   r   r   r   r%   r.   r   r   propertyr)   r*   __classcell__r,   s   @r   r   r      s         	 	 	 	 	  <   W0   X   X    r   r   c                   z     e Zd ZdZ fdZed             Zed             Zed             Zed             Z	 xZ
S )ThreeAngleOrienterz3
    Super-class for Body and Space orienters.
    c           	         t          |t                    r|j        }d}|}t          |                                          }t          |          dk    st          d          d |D             }d |D             }d |D             }d                    |          }||vrt          d          t          |d	                   }t          |d
                   }t          |d                   }	t          |          }t          |          }t          |          }| j
        r3t          ||          t          ||          z  t          |	|          z  }
n2t          |	|          t          ||          z  t          ||          z  }
|
j        }
t                                          | |||t          |                    }||_        ||_        ||_        ||_        |
|_        |S )N)123231312132213321121131212232313323 r0   z%rot_order should be a str of length 3c                 :    g | ]}|                     d d          S )X1replace.0is     r   
<listcomp>z.ThreeAngleOrienter.__new__.<locals>.<listcomp>x   &    <<<QQYYsC((<<<r   c                 :    g | ]}|                     d d          S )Y2rT   rV   s     r   rY   z.ThreeAngleOrienter.__new__.<locals>.<listcomp>y   rZ   r   c                 :    g | ]}|                     d d          S )Z3rT   rV   s     r   rY   z.ThreeAngleOrienter.__new__.<locals>.<listcomp>z   rZ   r   rP   zInvalid rot_type parameterr   r2   r1   )r   r   namestrupperlenr#   joinintr   	_in_order_rotr6   r$   r%   _angle1_angle2_angle3
_rot_orderr   )r(   angle1angle2angle3	rot_orderapproved_ordersoriginal_rot_ordera1a2a3r:   r+   r,   s               r   r%   zThreeAngleOrienter.__new__m   s   i%% 	'!I- '	NN((**	I!##CDDD<<)<<<	<<)<<<	<<)<<<	GGI&&	O++8999111= 	/!"f--!"f--.!"f--.MM ""f--!"f--.!"f--.M &ggooY9 9+*
r   c                     | j         S r<   )ri   r   s    r   rm   zThreeAngleOrienter.angle1   
    |r   c                     | j         S r<   )rj   r   s    r   rn   zThreeAngleOrienter.angle2   rw   r   c                     | j         S r<   )rk   r   s    r   ro   zThreeAngleOrienter.angle3   rw   r   c                     | j         S r<   )rl   r   s    r   rp   zThreeAngleOrienter.rot_order   s
    r   )r   r   r   r   r%   r>   rm   rn   ro   rp   r?   r@   s   @r   rB   rB   h   s         ) ) ) ) )V   X   X   X   X    r   rB   c                   "    e Zd ZdZdZd Zd ZdS )BodyOrienterz*
    Class to denote a body-orienter.
    Tc                 B    t                               | ||||          }|S r<   rB   r%   r(   rm   rn   ro   rp   r+   s         r   r%   zBodyOrienter.__new__   '     ((fff)24 4
r   c                     dS )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   rm   rn   ro   rp   s        r   r.   zBodyOrienter.__init__   s
    n 	r   Nr   r   r   r   rg   r%   r.   r   r   r   r|   r|      sC          I  
7 7 7 7 7r   r|   c                   "    e Zd ZdZdZd Zd ZdS )SpaceOrienterz+
    Class to denote a space-orienter.
    Fc                 B    t                               | ||||          }|S r<   r~   r   s         r   r%   zSpaceOrienter.__new__   r   r   c                     dS )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   r   s        r   r.   zSpaceOrienter.__init__   s
    ` 	r   Nr   r   r   r   r   r      sC          I  
0 0 0 0 0r   r   c                        e Zd ZdZ fdZd Zed             Zed             Zed             Z	ed             Z
 xZS )QuaternionOrienterz0
    Class to denote a quaternion-orienter.
    c           	      b   t          |          }t          |          }t          |          }t          |          }t          |dz  |dz  z   |dz  z
  |dz  z
  d||z  ||z  z
  z  d||z  ||z  z   z  gd||z  ||z  z   z  |dz  |dz  z
  |dz  z   |dz  z
  d||z  ||z  z
  z  gd||z  ||z  z
  z  d||z  ||z  z   z  |dz  |dz  z
  |dz  z
  |dz  z   gg          }|j        }t                                          | ||||          }||_        ||_        ||_        ||_        ||_	        |S )Nr1   )
r   r7   r6   r$   r%   _q0_q1_q2_q3r   )r(   q0q1q2q3r:   r+   r,   s          r   r%   zQuaternionOrienter.__new__3  s   R[[R[[R[[R[["'B!G"3bAg"="$'#*"#rBwb'8"9"#rBwb'8"9"; #$rBwb'8"9"$'B!G"3"$'#*,.!G#4"#rBwb'8"9"; #$rBwb'8"9"#rBwb'8"9"$'B!G"3"$'#*,.!G#4"5!6 7 7 &ggooc2r2r22*
r   c                     dS )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   r   s        r   r.   zQuaternionOrienter.__init__O  s
    J 	r   c                     | j         S r<   )r   r   s    r   r   zQuaternionOrienter.q0v  	    xr   c                     | j         S r<   )r   r   s    r   r   zQuaternionOrienter.q1z  r   r   c                     | j         S r<   )r   r   s    r   r   zQuaternionOrienter.q2~  r   r   c                     | j         S r<   )r   r   s    r   r   zQuaternionOrienter.q3  r   r   )r   r   r   r   r%   r.   r>   r   r   r   r   r?   r@   s   @r   r   r   .  s             8% % %N   X   X   X   X    r   r   c                     | 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. r2   r1   r0   N)r7   r   r6   r	   r
   )r*   r)   s     r   rh   rh     so    qyyi&&()))	i&&()))	i&&())) 
r   )sympy.core.basicr   sympy.core.sympifyr   (sympy.functions.elementary.trigonometricr   r   sympy.matrices.denser   r   r	   r
   sympy.matrices.immutabler   r7   sympy.core.cacher   sympy.core.symbolr   sympy.vectorr    r   r   rB   r|   r   r   rh   r   r   r   <module>r      s   " " " " " " & & & & & & ? ? ? ? ? ? ? ? G G G G G G G G G G G G C C C C C C $ $ $ $ $ $ ! ! ! ! ! !    
# 
# 
# 
# 
#u 
# 
# 
#M M M M M8 M M M`> > > > > > > >BC C C C C% C C CL< < < < <& < < <~V V V V V V V Vr* * * * *r   