
    \h                         S SK JrJrJrJrJrJrJrJr	J
r
  S SKJr  S SKJr  S SKJrJr  S SKJr  S SKJr  SS/r " S	 S\5      r " S
 S5      rS rg)    )	diffexpandsincossympifyeyezerosImmutableMatrix
MatrixBase)Symbol)trigsimp)Vector_check_vector)	translate)warnCoordinateSymReferenceFramec                   T   ^  \ rS rSrSrU 4S jrS r\S 5       rS r	S r
S rS	rU =r$ )
r      a>  
A coordinate symbol/base scalar associated wrt a Reference Frame.

Ideally, users should not instantiate this class. Instances of
this class must only be accessed through the corresponding frame
as 'frame[index]'.

CoordinateSyms having the same frame and index parameters are equal
(even though they may be instantiated separately).

Parameters
==========

name : string
    The display name of the CoordinateSym

frame : ReferenceFrame
    The reference frame this base scalar belongs to

index : 0, 1 or 2
    The index of the dimension denoted by this coordinate variable

Examples
========

>>> from sympy.physics.vector import ReferenceFrame, CoordinateSym
>>> A = ReferenceFrame('A')
>>> A[1]
A_y
>>> type(A[0])
<class 'sympy.physics.vector.frame.CoordinateSym'>
>>> a_y = CoordinateSym('a_y', A, 1)
>>> a_y == A[1]
True

c                    > 0 n[         TU ]  X@5        [         TU ]  " X40 UD6n[        U5        U[	        SS5      ;  a  [        S5      eX#4Ul        U$ )Nr      zInvalid index specified)super	_sanitize__xnew___check_framerange
ValueError_id)clsnameframeindexassumptionsobj	__class__s         R/var/www/auris/envauris/lib/python3.13/site-packages/sympy/physics/vector/frame.py__new__CoordinateSym.__new__3   s[     ++gs8K8Ua#677.
    c                 :    U R                   /U R                  Q70 4$ N)r    r   selfs    r&   __getnewargs_ex__CoordinateSym.__getnewargs_ex__?   s    		%DHH%r))r)   c                      U R                   S   $ )Nr   )r   r,   s    r&   r!   CoordinateSym.frameB   s    xx{r)   c                 d    [        U[        5      (       a  UR                  U R                  :X  a  gg)NTF)
isinstancer   r   r-   others     r&   __eq__CoordinateSym.__eq__F   s'     e]++yyDHH$r)   c                     X:X  + $ r+    r4   s     r&   __ne__CoordinateSym.__ne__N   s      r)   c                 v    U R                   S   R                  5       U R                   S   4R                  5       $ )Nr      )r   __hash__r,   s    r&   r>   CoordinateSym.__hash__Q   s/    $$&4==??r)   r9   )__name__
__module____qualname____firstlineno____doc__r'   r.   propertyr!   r6   r:   r>   __static_attributes____classcell__)r%   s   @r&   r   r      s=    #J
*  !@ @r)   c                      \ rS rSrSrSrS+S jrS rS rS r	\	r
S	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rS rS,S jr  S-S jrS rS r\S 5       r\S 5       r \S 5       r!\S 5       r"\S  5       r#\S! 5       r$\S" 5       r%\S# 5       r&\S$ 5       r'\S% 5       r(\S& 5       r)\S' 5       r*\S( 5       r+S) r,S*r-g).r   U   a  A reference frame in classical mechanics.

ReferenceFrame is a class used to represent a reference frame in classical
mechanics. It has a standard basis of three unit vectors in the frame's
x, y, and z directions.

It also can have a rotation relative to a parent frame; this rotation is
defined by a direction cosine matrix relating this frame's basis vectors to
the parent frame's basis vectors.  It can also have an angular velocity
vector, defined in another frame.

r   Nc                    [        U[        5      (       d  [        S5      eUGbE  [        U[        [        45      (       d  [        S5      e[        U5      S:w  a  [        S5      eU H#  n[        U[        5      (       a  M  [        S5      e   US-   US   -   S	-   US-   US
   -   S	-   US-   US   -   S	-   /U l        UR                  5       S-   US   -   UR                  5       S-   US
   -   UR                  5       S-   US   -   /U l	        SUR                  5       < SUS   < S3SUR                  5       < SUS
   < S3SUR                  5       < SUS   < S3/U l
        X l        OUS-   US-   US-   /U l        UR                  5       S-   UR                  5       S-   UR                  5       S-   /U l	        SUR                  5       -  SUR                  5       -  SUR                  5       -  /U l
        / SQU l        Ubo  [        U[        [        45      (       d  [        S5      e[        U5      S:w  a  [        S5      eU H#  n[        U[        5      (       a  M  [        S5      e   X0l
        Xl        0 U l        0 U l        0 U l        0 U l        0 U l        U R                  U R                   U R"                  /U l        SU l        [)        [+        / SQ5      U 4/5      U l        [)        [+        / SQ5      U 4/5      U l        [)        [+        / SQ5      U 4/5      U l        Ubj  [        U[        [        45      (       d  [        S5      e[        U5      S:w  a  [        S5      eU H#  n[        U[        5      (       a  M  [        S 5      e   OUS-   US-   US-   /n[3        US   U S5      [3        US
   U S
5      [3        US   U S5      4U l        [6        =R8                  S
-  sl        [6        R8                  U l        g)!ar  ReferenceFrame initialization method.

A ReferenceFrame has a set of orthonormal basis vectors, along with
orientations relative to other ReferenceFrames and angular velocities
relative to other ReferenceFrames.

Parameters
==========

indices : tuple of str
    Enables the reference frame's basis unit vectors to be accessed by
    Python's square bracket indexing notation using the provided three
    indice strings and alters the printing of the unit vectors to
    reflect this choice.
latexs : tuple of str
    Alters the LaTeX printing of the reference frame's basis unit
    vectors to the provided three valid LaTeX strings.

Examples
========

>>> from sympy.physics.vector import ReferenceFrame, vlatex
>>> N = ReferenceFrame('N')
>>> N.x
N.x
>>> O = ReferenceFrame('O', indices=('1', '2', '3'))
>>> O.x
O['1']
>>> O['1']
O['1']
>>> P = ReferenceFrame('P', latexs=('A1', 'A2', 'A3'))
>>> vlatex(P.x)
'A1'

``symbols()`` can be used to create multiple Reference Frames in one
step, for example:

>>> from sympy.physics.vector import ReferenceFrame
>>> from sympy import symbols
>>> A, B, C = symbols('A B C', cls=ReferenceFrame)
>>> D, E = symbols('D E', cls=ReferenceFrame, indices=('1', '2', '3'))
>>> A[0]
A_x
>>> D.x
D['1']
>>> E.y
E['2']
>>> type(A) == type(D)
True

Unit dyads for the ReferenceFrame can be accessed through the attributes ``xx``, ``xy``, etc. For example:

>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> N.yz
(N.y|N.z)
>>> N.zx
(N.z|N.x)
>>> P = ReferenceFrame('P', indices=['1', '2', '3'])
>>> P.xx
(P['1']|P['1'])
>>> P.zy
(P['3']|P['2'])

Unit dyadic is also accessible via the ``u`` attribute:

>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> N.u
(N.x|N.x) + (N.y|N.y) + (N.z|N.z)
>>> P = ReferenceFrame('P', indices=['1', '2', '3'])
>>> P.u
(P['1']|P['1']) + (P['2']|P['2']) + (P['3']|P['3'])

zNeed to supply a valid nameNzSupply the indices as a listr   zSupply 3 indiceszIndices must be stringsz['r   z']r=      _z\mathbf{\hat{z}_{z}}z.xz.yz.z_x_y_zz\mathbf{\hat{%s}_x}z\mathbf{\hat{%s}_y}z\mathbf{\hat{%s}_z})xyzzLatex entries must be stringsr=   r   r   r   r=   r   r   r   r=   z)Supply the variable names as a list/tuplezSupply 3 variable nameszVariable names must be strings)r3   str	TypeErrortuplelistlenr   str_vecslowerpretty_vecs
latex_vecsindicesr    	_var_dict	_dcm_dict
_dcm_cache_ang_vel_dict_ang_acc_dict_dlist_curr   MatrixrM   rN   rO   r   varlistr   _countr"   )r-   r    r_   latexs	variablesis         r&   __init__ReferenceFrame.__init__d   s   Z $$$9:: gt}55 >??7|q  !344!!S))#$=>>  #UlWQZ7%?"UlWQZ7%?"UlWQZ7%?BDM "&!3gaj!@!%!3gaj!@!%!3gaj!@ CD >BZZ\=DQZ!I=AZZ\=DQZ!I=AZZ\=DQZ!I	KDO #L #TkTD[D4KIDM $

t 3 $

t 3 $

t 3 5D !7 E 6 E 6 EHDO +DLfudm44 >??6{a !344!!S))#$CDD  %O	
 ~~t'9'94;M;MN	6),d3456),d3456),d345 i%77 KLL9~" !:;;!!S))#$DEE  dTk4$;?I%ilD!<%ilD!<%ilD!<> 	"#**
r)   c                 <   [        U[        5      (       d   US:  a  U R                  U   $ [        S5      eU R                  S   U:X  a  U R
                  $ U R                  S   U:X  a  U R                  $ U R                  S   U:X  a  U R                  $ [        S5      e)z
Returns basis vector for the provided index, if the index is a string.

If the index is a number, returns the coordinate variable correspon-
-ding to that index.
r   zInvalid index providedr   r=   rK   zNot a defined index)r3   rV   rh   r   r_   rP   rQ   rR   )r-   inds     r&   __getitem__ReferenceFrame.__getitem__   s     #s##Qw||C(( !9::<<?c!66M<<?c!66M<<?c!66M233r)   c                 Z    [        U R                  U R                  U R                  /5      $ r+   )iterrP   rQ   rR   r,   s    r&   __iter__ReferenceFrame.__iter__  s     TVVTVVTVV,--r)   c                     U R                   $ )zReturns the name of the frame. )r    r,   s    r&   __str__ReferenceFrame.__str__  s    yyr)   c                 <   SSSS.nX#R                  5       ;  a  [        S5      eU //n/ /nXE:w  am  UR                  5       nU HP  nUS   R                  U   R                  5       nU H'  nX;  d  M
  Xh/-   n	X;  d  M  UR	                  U	5        M)     MR     XE:w  a  Mm  U H  n	U	S   U:w  d  M  UR                  U	5        M!     UR                  [        S9  [        U5      S:w  a  US   $ S	n
[        U
R                  X2   U R                  UR                  5      5      e)
a  Returns an inclusive list of reference frames that connect this
reference frame to the provided reference frame.

Parameters
==========
other : ReferenceFrame
    The other reference frame to look for a connecting relationship to.
num : integer
    ``0``, ``1``, and ``2`` will look for orientation, angular
    velocity, and angular acceleration relationships between the two
    frames, respectively.

Returns
=======
list
    Inclusive list of reference frames that connect this reference
    frame to the other reference frame.

Examples
========

>>> from sympy.physics.vector import ReferenceFrame
>>> A = ReferenceFrame('A')
>>> B = ReferenceFrame('B')
>>> C = ReferenceFrame('C')
>>> D = ReferenceFrame('D')
>>> B.orient_axis(A, A.x, 1.0)
>>> C.orient_axis(B, B.x, 1.0)
>>> D.orient_axis(C, C.x, 1.0)
>>> D._dict_list(A, 0)
[D, C, B, A]

Raises
======

ValueError
    When no path is found between the two reference frames or ``num``
    is an incorrect value.

orientationzangular velocityzangular acceleration)r   r=   rK   z$Valid values for num are 0, 1, or 2.)keyr   z.No connecting {} path found between {} and {}.)
keysr   copyre   appendremovesortrZ   formatr    )r-   r5   numconnect_typepossible_connecting_pathsoldlist
frame_listframes_adjacent_to_lastadjacent_frameconnecting_pathmsgs              r&   
_dict_listReferenceFrame._dict_list  s1   T )-13 ''))CDD&*VH!$'2/446G7
*4R.*?*?*D*I*I*K'&=N%7*47G*G*K5<<_M	 '> 8 (2  'Or"e+)00A  ' 	"&&3&/()Q.,Q//>L$5tyy%**MNNr)   c                 8   SSK Jn  UR                  U 5      nUR                  UR                  5      nXCR
                  -  n[        [        US   5      SS9n[        [        US   5      SS9n[        [        US   5      SS9n[        [        XgU/5      U4/5      $ )z4Angular velocity from time differentiating the DCM. r   dynamicsymbols   T)	recursiverK   r   )
sympy.physics.vector.functionsr   dcmr   _tTr   r   r   rg   )	r-   
otherframer   dcm2diffdiffed	angvelmatw1w2w3s	            r&   _w_diff_dcmReferenceFrame._w_diff_dcme  s    A>>$'~001ZZ'	fYq\*d;fYq\*d;fYq\*d;|,j9:;;r)   c                    [        U5        U[        R                  4U R                  ;   a  U R                  U[        R                  4   $ U R	                  U5      [        UR                  5      -  n0 n[        U 5       HJ  u  pE[        R                  (       a  [        X$   SS9X0R                  U   '   M7  X$   X0R                  U   '   ML     X0R                  U[        R                  4'   U$ )a  
Returns a dictionary which expresses the coordinate variables
of this frame in terms of the variables of otherframe.

If Vector.simp is True, returns a simplified version of the mapped
values. Else, returns them without simplification.

Simplification of the expressions may take time.

Parameters
==========

otherframe : ReferenceFrame
    The other frame to map the variables to

Examples
========

>>> from sympy.physics.vector import ReferenceFrame, dynamicsymbols
>>> A = ReferenceFrame('A')
>>> q = dynamicsymbols('q')
>>> B = A.orientnew('B', 'Axis', [q, A.z])
>>> A.variable_map(B)
{A_x: B_x*cos(q(t)) - B_y*sin(q(t)), A_y: B_x*sin(q(t)) + B_y*cos(q(t)), A_z: B_z}

fu)method)	r   r   simpr`   r   rg   rh   	enumerater   )r-   r   vars_matrixmappingrl   rP   s         r&   variable_mapReferenceFrame.variable_mapp  s    8 	Z $6>>:v{{";<<((:.
8J8J1KKKG!$;;/7?C0EGLLO, 0;~GLLO, ( 9@NNJ45Nr)   c                     [        U5        XR                  ;   a  U R                  U   $ U R                  U5      R                  U5      $ )a	  Returns the angular acceleration Vector of the ReferenceFrame.

Effectively returns the Vector:

``N_alpha_B``

which represent the angular acceleration of B in N, where B is self,
and N is otherframe.

Parameters
==========

otherframe : ReferenceFrame
    The ReferenceFrame which the angular acceleration is returned in.

Examples
========

>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_acc(N, V)
>>> A.ang_acc_in(N)
10*N.x

)r   rd   
ang_vel_indt)r-   r   s     r&   
ang_acc_inReferenceFrame.ang_acc_in  sC    : 	Z +++%%j11??:.11*==r)   c                     [        U5        U R                  US5      n[        S5      n[        [	        U5      S-
  5       H  nX2U   R
                  X$S-         -  nM     U$ )a  Returns the angular velocity Vector of the ReferenceFrame.

Effectively returns the Vector:

^N omega ^B

which represent the angular velocity of B in N, where B is self, and
N is otherframe.

Parameters
==========

otherframe : ReferenceFrame
    The ReferenceFrame which the angular velocity is returned in.

Examples
========

>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_vel(N, V)
>>> A.ang_vel_in(N)
10*N.x

r=   r   )r   r   r   r   rZ   rc   )r-   r   flistoutvecrl   s        r&   r   ReferenceFrame.ang_vel_in  s^    : 	Z 
A.s5zA~&AAh,,Uq5\::F 'r)   c                 N   [        U5        XR                  ;   a  U R                  U   $ U R                  US5      n[        S5      n[	        [        U5      S-
  5       H  nX2U   R                  X$S-         -  nM     X0R                  U'   UR                  UR                  U '   U$ )a  Returns the direction cosine matrix of this reference frame
relative to the provided reference frame.

The returned matrix can be used to express the orthogonal unit vectors
of this frame in terms of the orthogonal unit vectors of
``otherframe``.

Parameters
==========

otherframe : ReferenceFrame
    The reference frame which the direction cosine matrix of this frame
    is formed relative to.

Examples
========

The following example rotates the reference frame A relative to N by a
simple rotation and then calculates the direction cosine matrix of N
relative to A.

>>> from sympy import symbols, sin, cos
>>> from sympy.physics.vector import ReferenceFrame
>>> q1 = symbols('q1')
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> A.orient_axis(N, q1, N.x)
>>> N.dcm(A)
Matrix([
[1,       0,        0],
[0, cos(q1), -sin(q1)],
[0, sin(q1),  cos(q1)]])

The second row of the above direction cosine matrix represents the
``N.y`` unit vector in N expressed in A. Like so:

>>> Ny = 0*A.x + cos(q1)*A.y - sin(q1)*A.z

Thus, expressing ``N.y`` in A should return the same result:

>>> N.y.express(A)
cos(q1)*A.y - sin(q1)*A.z

Notes
=====

It is important to know what form of the direction cosine matrix is
returned. If ``B.dcm(A)`` is called, it means the "direction cosine
matrix of B rotated relative to A". This is the matrix
:math:`{}^B\mathbf{C}^A` shown in the following relationship:

.. math::

   \begin{bmatrix}
     \hat{\mathbf{b}}_1 \\
     \hat{\mathbf{b}}_2 \\
     \hat{\mathbf{b}}_3
   \end{bmatrix}
   =
   {}^B\mathbf{C}^A
   \begin{bmatrix}
     \hat{\mathbf{a}}_1 \\
     \hat{\mathbf{a}}_2 \\
     \hat{\mathbf{a}}_3
   \end{bmatrix}.

:math:`{}^B\mathbf{C}^A` is the matrix that expresses the B unit
vectors in terms of the A unit vectors.

r   r   r=   )r   rb   r   r   r   rZ   ra   r   )r-   r   r   outdcmrl   s        r&   r   ReferenceFrame.dcm  s    P 	Z (??:..
A.Qs5zA~&AAh001u>>F ' '-
#&,hh
d#r)   c                 b   U R                   R                  5       n/ n/ nX;   al  U H  nX`R                  ;   a  XF/-  nXV/-  nM     U H  nUR                  U 	 M     U H  nUR                   U 	 M     0 =U l        U R                  S'   0 U l         O/ n[	        U5      nSn	U(       a  U	(       a  UR                  S5      n
X;  aY  UR                  U
5        U
R                  R                  5       nU H(  nX:X  a  [        S5        Sn	  OUR                  U5        M*     U(       a	  U	(       a  M  U R                  R                  XR                  05        UR                  R                  X05        U R                   R                  XR                  05        UR                   R                  X05        g )Nr   TzxLoops are defined among the orientation of frames. This is likely not desired and may cause errors in your calculations.F)
rb   r~   ra   re   rY   popr   r   updater   )r-   parentparent_orientframesdcm_dict_deldcm_cache_delr!   visitedqueuecontnode	neighborsneighbors                r&   _dcmReferenceFrame._dcm8  s    %%'NN* G+L(   &OOD) &&$$T* ' /10DNT[[^ DO GLEDDyy|&NN4( $ 3 3 5I$-#-  "F G $)D!X. %. DD 	v78 5689  $!67r)   c                 B   SSK Jn  [        U5        [        U[        5      (       d  [        U[        5      (       a  X2p2[        U5      n[        U5      nUR                  U5      S:X  d  [        S5      eUR                  U5      R                  5       nUR                  S   S   n[        S5      XwR                  -  -
  [        U5      -  [        SUS   * US   /US   SUS   * /US   * US   S//5      [!        U5      -  -   XwR                  -  -   nU R#                  X5        UR%                  UR&                  5      n	XR                  U5      R                  5       -  n
U R(                  R+                  X05        UR(                  R+                  X
* 05        0 U l        g)a  Sets the orientation of this reference frame with respect to a
parent reference frame by rotating through an angle about an axis fixed
in the parent reference frame.

Parameters
==========

parent : ReferenceFrame
    Reference frame that this reference frame will be rotated relative
    to.
axis : Vector
    Vector fixed in the parent frame about about which this frame is
    rotated. It need not be a unit vector and the rotation follows the
    right hand rule.
angle : sympifiable
    Angle in radians by which it the frame is to be rotated.

Warns
======

UserWarning
    If the orientation creates a kinematic loop.

Examples
========

Setup variables for the examples:

>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q1 = symbols('q1')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
>>> B.orient_axis(N, N.x, q1)

The ``orient_axis()`` method generates a direction cosine matrix and
its transpose which defines the orientation of B relative to N and vice
versa. Once orient is called, ``dcm()`` outputs the appropriate
direction cosine matrix:

>>> B.dcm(N)
Matrix([
[1,       0,      0],
[0,  cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])
>>> N.dcm(B)
Matrix([
[1,       0,        0],
[0, cos(q1), -sin(q1)],
[0, sin(q1),  cos(q1)]])

The following two lines show that the sense of the rotation can be
defined by negating the vector direction or the angle. Both lines
produce the same result.

>>> B.orient_axis(N, -N.x, q1)
>>> B.orient_axis(N, N.x, -q1)

r   r   zAxis cannot be time-varying.r   rK   r=   N)r   r   r   r3   r   r   r   r   r   express	normalizeargsr   r   r   rg   r   r   r   r   rc   r   r`   )r-   r   axisangler   theta	unit_axisunit_colparent_orient_axisthetadwvecs              r&   orient_axisReferenceFrame.orient_axism  s   z 	BV$''Juf,E,E%T"wwv!#;<<LL(224	>>!$Q'Vh++s5z9Q!hqk2a[!hqk\2qk\8A;24 5 J "JJ.	/ 	 			&-n//0ll6*4466!!6.1##T5M2r)   c                     [        U5        [        U[        5      (       d  [        S5      eU R	                  XR
                  5        g)a'  Sets the orientation of this reference frame relative to another (parent) reference frame
using a direction cosine matrix that describes the rotation from the parent to the child.

Parameters
==========

parent : ReferenceFrame
    Reference frame that this reference frame will be rotated relative
    to.
dcm : Matrix, shape(3, 3)
    Direction cosine matrix that specifies the relative rotation
    between the two reference frames.

Warns
======

UserWarning
    If the orientation creates a kinematic loop.

Examples
========

Setup variables for the examples:

>>> from sympy import symbols, Matrix, sin, cos
>>> from sympy.physics.vector import ReferenceFrame
>>> q1 = symbols('q1')
>>> A = ReferenceFrame('A')
>>> B = ReferenceFrame('B')
>>> N = ReferenceFrame('N')

A simple rotation of ``A`` relative to ``N`` about ``N.x`` is defined
by the following direction cosine matrix:

>>> dcm = Matrix([[1, 0, 0],
...               [0, cos(q1), -sin(q1)],
...               [0, sin(q1), cos(q1)]])
>>> A.orient_explicit(N, dcm)
>>> A.dcm(N)
Matrix([
[1,       0,      0],
[0,  cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])

This is equivalent to using ``orient_axis()``:

>>> B.orient_axis(N, N.x, q1)
>>> B.dcm(N)
Matrix([
[1,       0,      0],
[0,  cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])

**Note carefully that** ``N.dcm(B)`` **(the transpose) would be passed
into** ``orient_explicit()`` **for** ``A.dcm(N)`` **to match**
``B.dcm(N)``:

>>> A.orient_explicit(N, N.dcm(B))
>>> A.dcm(N)
Matrix([
[1,       0,      0],
[0,  cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])

+Amounts must be a SymPy Matrix type object.N)r   r3   r   rW   
orient_dcmr   )r-   r   r   s      r&   orient_explicitReferenceFrame.orient_explicit  s8    D 	V #z**IJJ&r)   c                 2   [        U5        [        U[        5      (       d  [        S5      eU R	                  XR
                  5        U R                  U5      nU R                  R                  X05        UR                  R                  X* 05        0 U l	        g)a  Sets the orientation of this reference frame relative to another (parent) reference frame
using a direction cosine matrix that describes the rotation from the child to the parent.

Parameters
==========

parent : ReferenceFrame
    Reference frame that this reference frame will be rotated relative
    to.
dcm : Matrix, shape(3, 3)
    Direction cosine matrix that specifies the relative rotation
    between the two reference frames.

Warns
======

UserWarning
    If the orientation creates a kinematic loop.

Examples
========

Setup variables for the examples:

>>> from sympy import symbols, Matrix, sin, cos
>>> from sympy.physics.vector import ReferenceFrame
>>> q1 = symbols('q1')
>>> A = ReferenceFrame('A')
>>> B = ReferenceFrame('B')
>>> N = ReferenceFrame('N')

A simple rotation of ``A`` relative to ``N`` about ``N.x`` is defined
by the following direction cosine matrix:

>>> dcm = Matrix([[1, 0, 0],
...               [0,  cos(q1), sin(q1)],
...               [0, -sin(q1), cos(q1)]])
>>> A.orient_dcm(N, dcm)
>>> A.dcm(N)
Matrix([
[1,       0,      0],
[0,  cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])

This is equivalent to using ``orient_axis()``:

>>> B.orient_axis(N, N.x, q1)
>>> B.dcm(N)
Matrix([
[1,       0,      0],
[0,  cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])

r   N)
r   r3   r   rW   r   r   r   rc   r   r`   )r-   r   r   r   s       r&   r   ReferenceFrame.orient_dcm  s}    p 	V #z**IJJ		&%% '!!6.1##T5M2r)   c           	         US:X  a;  [        / SQS[        U5      [        U5      * /S[        U5      [        U5      //5      $ US:X  a;  [        [        U5      S[        U5      // SQ[        U5      * S[        U5      //5      $ US:X  a;  [        [        U5      [        U5      * S/[        U5      [        U5      S// SQ/5      $ g)	z'DCM for simple axis 1,2,or 3 rotations.r=   rS   r   rK   rT   r   rU   N)rg   r   r   )r-   r   r   s      r&   _rotReferenceFrame._rotU  s    199s5zCJ;7s5z3u:68 9 9 QYCJ3u:6$ ZKCJ79 : : QYCJUQ7JE
A6$& ' ' r)   c                    [        U5      n[        U5       H)  u  pE[        U[        5      (       a  M  [	        U5      X4'   M+     Sn[        [        U5      SS5      nXv;  a  [        S5      eU Vs/ s H  n[        U5      PM     nn[        U5      S[        U5      -  s=:X  a  S:X  d  O  [        S5      e[        Xs5       V	V
s/ s H  u  pU R                  X5      PM     nn	n
X7U4$ s  snf s  sn
n	f )a  Helper for orient_body_fixed and orient_space_fixed.

Parameters
==========
angles : 3-tuple of sympifiable
    Three angles in radians used for the successive rotations.
rotation_order : 3 character string or 3 digit integer
    Order of the rotations. The order can be specified by the strings
    ``'XZX'``, ``'131'``, or the integer ``131``. There are 12 unique
    valid rotation orders.

Returns
=======

amounts : list
    List of sympifiables corresponding to the rotation angles.
rot_order : list
    List of integers corresponding to the axis of rotation.
rot_matrices : list
    List of DCM around the given axis with corresponding magnitude.

123231312132213321121131212232313323 XYZxyz123123z(The rotation order is not a valid order.r   z*Body orientation takes 3 values & 3 orders)rY   r   r3   r   r   r   rV   rW   intrZ   zipr   )r-   anglesrotation_orderamountsrl   vapproved_orders	rot_orderrorderamountrot_matricess               r&   _parse_consecutive_rotations+ReferenceFrame._parse_consecutive_rotationsd  s    . v,g&DAa(($QZ
 'B c.18XF	+FGG%./YSVY	/GC	N 27a7HII/29/FH/FOU 		%0/F 	 H<// 0Hs   0C(C-c                    SSK Jn  [        U5        U R                  X#5      u  pVnU R	                  XS   US   -  US   -  5        [        S5       Vs/ s H  n[        SS5      PM     n	n[        U5       H*  u  pXZ   R                  UR                  5      X   US-
  '   M,     U	S   US   R                  U	S   US   R                  U	S   -  -   -  -   u  pnXR                  -  XR                  -  -   XR                  -  -   nU R                  R                  X05        UR                  R                  X* 05        0 U l        gs  snf )a,  Rotates this reference frame relative to the parent reference frame
by right hand rotating through three successive body fixed simple axis
rotations. Each subsequent axis of rotation is about the "body fixed"
unit vectors of a new intermediate reference frame. This type of
rotation is also referred to rotating through the `Euler and Tait-Bryan
Angles`_.

.. _Euler and Tait-Bryan Angles: https://en.wikipedia.org/wiki/Euler_angles

The computed angular velocity in this method is by default expressed in
the child's frame, so it is most preferable to use ``u1 * child.x + u2 *
child.y + u3 * child.z`` as generalized speeds.

Parameters
==========

parent : ReferenceFrame
    Reference frame that this reference frame will be rotated relative
    to.
angles : 3-tuple of sympifiable
    Three angles in radians used for the successive rotations.
rotation_order : 3 character string or 3 digit integer
    Order of the rotations about each intermediate reference frames'
    unit vectors. The Euler rotation about the X, Z', X'' axes can be
    specified by the strings ``'XZX'``, ``'131'``, or the integer
    ``131``. There are 12 unique valid rotation orders (6 Euler and 6
    Tait-Bryan): zxz, xyx, yzy, zyz, xzx, yxy, xyz, yzx, zxy, xzy, zyx,
    and yxz.

Warns
======

UserWarning
    If the orientation creates a kinematic loop.

Examples
========

Setup variables for the examples:

>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q1, q2, q3 = symbols('q1, q2, q3')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
>>> B1 = ReferenceFrame('B1')
>>> B2 = ReferenceFrame('B2')
>>> B3 = ReferenceFrame('B3')

For example, a classic Euler Angle rotation can be done by:

>>> B.orient_body_fixed(N, (q1, q2, q3), 'XYX')
>>> B.dcm(N)
Matrix([
[        cos(q2),                            sin(q1)*sin(q2),                           -sin(q2)*cos(q1)],
[sin(q2)*sin(q3), -sin(q1)*sin(q3)*cos(q2) + cos(q1)*cos(q3),  sin(q1)*cos(q3) + sin(q3)*cos(q1)*cos(q2)],
[sin(q2)*cos(q3), -sin(q1)*cos(q2)*cos(q3) - sin(q3)*cos(q1), -sin(q1)*sin(q3) + cos(q1)*cos(q2)*cos(q3)]])

This rotates reference frame B relative to reference frame N through
``q1`` about ``N.x``, then rotates B again through ``q2`` about
``B.y``, and finally through ``q3`` about ``B.x``. It is equivalent to
three successive ``orient_axis()`` calls:

>>> B1.orient_axis(N, N.x, q1)
>>> B2.orient_axis(B1, B1.y, q2)
>>> B3.orient_axis(B2, B2.x, q3)
>>> B3.dcm(N)
Matrix([
[        cos(q2),                            sin(q1)*sin(q2),                           -sin(q2)*cos(q1)],
[sin(q2)*sin(q3), -sin(q1)*sin(q3)*cos(q2) + cos(q1)*cos(q3),  sin(q1)*cos(q3) + sin(q3)*cos(q1)*cos(q2)],
[sin(q2)*cos(q3), -sin(q1)*cos(q2)*cos(q3) - sin(q3)*cos(q1), -sin(q1)*sin(q3) + cos(q1)*cos(q2)*cos(q3)]])

Acceptable rotation orders are of length 3, expressed in as a string
``'XYZ'`` or ``'123'`` or integer ``123``. Rotations about an axis
twice in a row are prohibited.

>>> B.orient_body_fixed(N, (q1, q2, 0), 'ZXZ')
>>> B.orient_body_fixed(N, (q1, q2, 0), '121')
>>> B.orient_body_fixed(N, (q1, q2, q3), 123)

r   r   r=   rK   r   Nr   r   r   r   r   r   r	   r   r   r   r   rP   rQ   rR   rc   r   r`   r-   r   r   r   r   r   r   r   rL   rot_vecsrl   r   u1u2u3r   s                   r&   orient_body_fixed ReferenceFrame.orient_body_fixed  s8   d 	BV+/+L+L,$(L		&q/LO;l1oMN).q2AE!QK2!),HA%,Z__^5F5F%GHK	" -a[<?#4#4QK,q/++hqk99$; ;
FF{R&&[(2;6!!6.1##T5M2 3   Ec                    SSK Jn  [        U5        U R                  X#5      u  pVnU R	                  XS   US   -  US   -  5        [        S5       Vs/ s H  n[        SS5      PM     n	n[        U5       H*  u  pXZ   R                  UR                  5      X   US-
  '   M,     U	S   US   R                  U	S   US   R                  U	S   -  -   -  -   u  pnXR                  -  XR                  -  -   XR                  -  -   nU R                  R                  X05        UR                  R                  X* 05        0 U l        gs  snf )a[  Rotates this reference frame relative to the parent reference frame
by right hand rotating through three successive space fixed simple axis
rotations. Each subsequent axis of rotation is about the "space fixed"
unit vectors of the parent reference frame.

The computed angular velocity in this method is by default expressed in
the child's frame, so it is most preferable to use ``u1 * child.x + u2 *
child.y + u3 * child.z`` as generalized speeds.

Parameters
==========
parent : ReferenceFrame
    Reference frame that this reference frame will be rotated relative
    to.
angles : 3-tuple of sympifiable
    Three angles in radians used for the successive rotations.
rotation_order : 3 character string or 3 digit integer
    Order of the rotations about the parent reference frame's unit
    vectors. The order can be specified by the strings ``'XZX'``,
    ``'131'``, or the integer ``131``. There are 12 unique valid
    rotation orders.

Warns
======

UserWarning
    If the orientation creates a kinematic loop.

Examples
========

Setup variables for the examples:

>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q1, q2, q3 = symbols('q1, q2, q3')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
>>> B1 = ReferenceFrame('B1')
>>> B2 = ReferenceFrame('B2')
>>> B3 = ReferenceFrame('B3')

>>> B.orient_space_fixed(N, (q1, q2, q3), '312')
>>> B.dcm(N)
Matrix([
[ sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1)],
[-sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3)],
[                           sin(q3)*cos(q2),        -sin(q2),                           cos(q2)*cos(q3)]])

is equivalent to:

>>> B1.orient_axis(N, N.z, q1)
>>> B2.orient_axis(B1, N.x, q2)
>>> B3.orient_axis(B2, N.y, q3)
>>> B3.dcm(N).simplify()
Matrix([
[ sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1)],
[-sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3)],
[                           sin(q3)*cos(q2),        -sin(q2),                           cos(q2)*cos(q3)]])

It is worth noting that space-fixed and body-fixed rotations are
related by the order of the rotations, i.e. the reverse order of body
fixed will give space fixed and vice versa.

>>> B.orient_space_fixed(N, (q1, q2, q3), '231')
>>> B.dcm(N)
Matrix([
[cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3), -sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1)],
[       -sin(q2),                           cos(q2)*cos(q3),                            sin(q3)*cos(q2)],
[sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1),  sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3)]])

>>> B.orient_body_fixed(N, (q3, q2, q1), '132')
>>> B.dcm(N)
Matrix([
[cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3), -sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1)],
[       -sin(q2),                           cos(q2)*cos(q3),                            sin(q3)*cos(q2)],
[sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1),  sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3)]])

r   r   rK   r=   r   Nr   r   s                   r&   orient_space_fixed!ReferenceFrame.orient_space_fixed  s8   ` 	BV+/+L+L,$(L		&q/LO;l1oMN).q2AE!QK2!),HA%,Z__^5F5F%GHK	" -a[<?#4#4QK,q/++hqk99$; ;
FF{R&&[(2;6!!6.1##T5M2 3r  c           	         SSK Jn  [        U5        [        U5      n[	        U5       H)  u  pE[        U[        5      (       a  M  [        U5      X$'   M+     [        U[        [        45      [        U5      S:H  -  (       d  [        S5      eUu  pgp[        US-  US-  -   US-  -
  U	S-  -
  SXx-  Xi-  -
  -  SXh-  Xy-  -   -  /SXx-  Xi-  -   -  US-  US-  -
  US-  -   U	S-  -
  SX-  Xg-  -
  -  /SXy-  Xh-  -
  -  SXg-  X-  -   -  US-  US-  -
  US-  -
  U	S-  -   //5      n
U R                  X5        UR                  nUu  pgp[        Xk5      n[        X{5      n[        X5      n[        X5      nSX-  X-  -   X-  -
  X-  -
  -  nSX-  X-  -   X-  -
  X-  -
  -  nSX-  X-  -   X-  -
  X-  -
  -  n[        [        UUU/5      U 4/5      nU R                  R!                  UU05        UR                  R!                  U U* 05        0 U l        g)a  Sets the orientation of this reference frame relative to a parent
reference frame via an orientation quaternion. An orientation
quaternion is defined as a finite rotation a unit vector, ``(lambda_x,
lambda_y, lambda_z)``, by an angle ``theta``. The orientation
quaternion 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)``

See `Quaternions and Spatial Rotation
<https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation>`_ on
Wikipedia for more information.

Parameters
==========
parent : ReferenceFrame
    Reference frame that this reference frame will be rotated relative
    to.
numbers : 4-tuple of sympifiable
    The four quaternion scalar numbers as defined above: ``q0``,
    ``q1``, ``q2``, ``q3``.

Warns
======

UserWarning
    If the orientation creates a kinematic loop.

Examples
========

Setup variables for the examples:

>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')

Set the orientation:

>>> B.orient_quaternion(N, (q0, q1, q2, q3))
>>> B.dcm(N)
Matrix([
[q0**2 + q1**2 - q2**2 - q3**2,             2*q0*q3 + 2*q1*q2,            -2*q0*q2 + 2*q1*q3],
[           -2*q0*q3 + 2*q1*q2, q0**2 - q1**2 + q2**2 - q3**2,             2*q0*q1 + 2*q2*q3],
[            2*q0*q2 + 2*q1*q3,            -2*q0*q1 + 2*q2*q3, q0**2 - q1**2 - q2**2 + q3**2]])

r   r      z'Amounts are a list or tuple of length 4rK   N)r   r   r   rY   r   r3   r   r   rX   rZ   rW   rg   r   r   r   rc   r   r`   )r-   r   numbersr   rl   r   q0q1q2q3parent_orient_quaterniontq0dq1dq2dq3dr   r   r   r   s                       r&   orient_quaternion ReferenceFrame.orient_quaternionT  sb   j 	BVw-g&DAa(($QZ
 ' 7T5M2c'la6GHEFF RURU]RU*RU2"'BG+,"'BG+,. "'BG+,URU]RU*RU2"'BG+,. "'BG+,"'BG+,URU]RU*RU245 6 	! 			&3 2k2k2k2k#(SX%038;<#(SX%038;<#(SX%038;<B|,d345!!64.1##TD5M2r)   c                    [        U5        Sn[        [        U5      SS5      nUR                  5       nXE;  a  [	        S5      eUS:X  a  U R                  XS   US   5        gUS:X  a  U R                  X5        gUS	:X  a  U R                  XU5        gUS
:X  a  U R                  XU5        gUS:X  a  U R                  X5        g[        S5      e)a  Sets the orientation of this reference frame relative to another
(parent) reference frame.

.. note:: It is now recommended to use the ``.orient_axis,
   .orient_body_fixed, .orient_space_fixed, .orient_quaternion``
   methods for the different rotation types.

Parameters
==========

parent : ReferenceFrame
    Reference frame that this reference frame will be rotated relative
    to.
rot_type : str
    The method used to generate the direction cosine matrix. Supported
    methods are:

    - ``'Axis'``: simple rotations about a single common axis
    - ``'DCM'``: for setting the direction cosine matrix directly
    - ``'Body'``: three successive rotations about new intermediate
      axes, also called "Euler and Tait-Bryan angles"
    - ``'Space'``: three successive rotations about the parent
      frames' unit vectors
    - ``'Quaternion'``: rotations defined by four parameters which
      result in a singularity free direction cosine matrix

amounts :
    Expressions defining the rotation angles or direction cosine
    matrix. These must match the ``rot_type``. See examples below for
    details. The input types are:

    - ``'Axis'``: 2-tuple (expr/sym/func, Vector)
    - ``'DCM'``: Matrix, shape(3,3)
    - ``'Body'``: 3-tuple of expressions, symbols, or functions
    - ``'Space'``: 3-tuple of expressions, symbols, or functions
    - ``'Quaternion'``: 4-tuple of expressions, symbols, or
      functions

rot_order : str or int, optional
    If applicable, the order of the successive of rotations. The string
    ``'123'`` and integer ``123`` are equivalent, for example. Required
    for ``'Body'`` and ``'Space'``.

Warns
======

UserWarning
    If the orientation creates a kinematic loop.

r   r   r   *The supplied order is not an approved typeAXISr=   r   DCMBODYSPACE
QUATERNION#That is not an implemented rotationN)r   r   rV   upperrW   r   r   r  r  r  NotImplementedError)r-   r   rot_typer   r   r   s         r&   orientReferenceFrame.orient  s    h 	VBc)nhA	>>#+HIIvVQZ<  1""6I> ##FY?%""63 &&KLLr)   c                    U R                  XXgS9nSn	[        [        U5      SS5      nUR                  5       nXI;  a  [	        S5      eUS:X  a  UR                  XS   US   5        U$ US	:X  a  UR                  X5        U$ US
:X  a  UR                  XU5        U$ US:X  a  UR                  XU5        U$ US:X  a  UR                  X5        U$ [        S5      e)a|
  Returns a new reference frame oriented with respect to this
reference frame.

See ``ReferenceFrame.orient()`` for detailed examples of how to orient
reference frames.

Parameters
==========

newname : str
    Name for the new reference frame.
rot_type : str
    The method used to generate the direction cosine matrix. Supported
    methods are:

    - ``'Axis'``: simple rotations about a single common axis
    - ``'DCM'``: for setting the direction cosine matrix directly
    - ``'Body'``: three successive rotations about new intermediate
      axes, also called "Euler and Tait-Bryan angles"
    - ``'Space'``: three successive rotations about the parent
      frames' unit vectors
    - ``'Quaternion'``: rotations defined by four parameters which
      result in a singularity free direction cosine matrix

amounts :
    Expressions defining the rotation angles or direction cosine
    matrix. These must match the ``rot_type``. See examples below for
    details. The input types are:

    - ``'Axis'``: 2-tuple (expr/sym/func, Vector)
    - ``'DCM'``: Matrix, shape(3,3)
    - ``'Body'``: 3-tuple of expressions, symbols, or functions
    - ``'Space'``: 3-tuple of expressions, symbols, or functions
    - ``'Quaternion'``: 4-tuple of expressions, symbols, or
      functions

rot_order : str or int, optional
    If applicable, the order of the successive of rotations. The string
    ``'123'`` and integer ``123`` are equivalent, for example. Required
    for ``'Body'`` and ``'Space'``.
indices : tuple of str
    Enables the reference frame's basis unit vectors to be accessed by
    Python's square bracket indexing notation using the provided three
    indice strings and alters the printing of the unit vectors to
    reflect this choice.
latexs : tuple of str
    Alters the LaTeX printing of the reference frame's basis unit
    vectors to the provided three valid LaTeX strings.

Examples
========

>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame, vlatex
>>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
>>> N = ReferenceFrame('N')

Create a new reference frame A rotated relative to N through a simple
rotation.

>>> A = N.orientnew('A', 'Axis', (q0, N.x))

Create a new reference frame B rotated relative to N through body-fixed
rotations.

>>> B = N.orientnew('B', 'Body', (q1, q2, q3), '123')

Create a new reference frame C rotated relative to N through a simple
rotation with unique indices and LaTeX printing.

>>> C = N.orientnew('C', 'Axis', (q0, N.x), indices=('1', '2', '3'),
... latexs=(r'\hat{\mathbf{c}}_1',r'\hat{\mathbf{c}}_2',
... r'\hat{\mathbf{c}}_3'))
>>> C['1']
C['1']
>>> print(vlatex(C['1']))
\hat{\mathbf{c}}_1

)rk   r_   rj   r   r   r   r  r  r=   r   r  r  r  r  r   )r%   r   rV   r!  rW   r   r   r  r  r  r"  )
r-   newnamer#  r   r   rk   r_   rj   newframer   s
             r&   	orientnewReferenceFrame.orientnew   s   d >>'*1 " BBc)nhA	>>#+HIIv  qz71:>   $$T3  &&ti@   ''yA  %&&t5  &&KLLr)   c                     US:X  a  [        S5      n[        U5      n[        U5        U R                  R	                  X05        UR                  R	                  X* 05        g)a  Define the angular acceleration Vector in a ReferenceFrame.

Defines the angular acceleration of this ReferenceFrame, in another.
Angular acceleration can be defined with respect to multiple different
ReferenceFrames. Care must be taken to not create loops which are
inconsistent.

Parameters
==========

otherframe : ReferenceFrame
    A ReferenceFrame to define the angular acceleration in
value : Vector
    The Vector representing angular acceleration

Examples
========

>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_acc(N, V)
>>> A.ang_acc_in(N)
10*N.x

r   N)r   r   r   rd   r   r-   r   values      r&   set_ang_accReferenceFrame.set_ang_accp  U    : A:1IEe$Z !!:"56  ''v7r)   c                     US:X  a  [        S5      n[        U5      n[        U5        U R                  R	                  X05        UR                  R	                  X* 05        g)ay  Define the angular velocity vector in a ReferenceFrame.

Defines the angular velocity of this ReferenceFrame, in another.
Angular velocity can be defined with respect to multiple different
ReferenceFrames. Care must be taken to not create loops which are
inconsistent.

Parameters
==========

otherframe : ReferenceFrame
    A ReferenceFrame to define the angular velocity in
value : Vector
    The Vector representing angular velocity

Examples
========

>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_vel(N, V)
>>> A.ang_vel_in(N)
10*N.x

r   N)r   r   r   rc   r   r,  s      r&   set_ang_velReferenceFrame.set_ang_vel  r0  r)   c                     U R                   $ )z=The basis Vector for the ReferenceFrame, in the x direction. )rM   r,   s    r&   rP   ReferenceFrame.x       wwr)   c                     U R                   $ )z=The basis Vector for the ReferenceFrame, in the y direction. )rN   r,   s    r&   rQ   ReferenceFrame.y  r6  r)   c                     U R                   $ )z=The basis Vector for the ReferenceFrame, in the z direction. )rO   r,   s    r&   rR   ReferenceFrame.z  r6  r)   c                 X    [         R                  " U R                  U R                  5      $ )z:Unit dyad of basis Vectors x and x for the ReferenceFrame.)r   outerrP   r,   s    r&   xxReferenceFrame.xx       ||DFFDFF++r)   c                 X    [         R                  " U R                  U R                  5      $ )z:Unit dyad of basis Vectors x and y for the ReferenceFrame.)r   r<  rP   rQ   r,   s    r&   xyReferenceFrame.xy  r?  r)   c                 X    [         R                  " U R                  U R                  5      $ )z:Unit dyad of basis Vectors x and z for the ReferenceFrame.)r   r<  rP   rR   r,   s    r&   xzReferenceFrame.xz  r?  r)   c                 X    [         R                  " U R                  U R                  5      $ )z:Unit dyad of basis Vectors y and x for the ReferenceFrame.)r   r<  rQ   rP   r,   s    r&   yxReferenceFrame.yx  r?  r)   c                 X    [         R                  " U R                  U R                  5      $ )z:Unit dyad of basis Vectors y and y for the ReferenceFrame.)r   r<  rQ   r,   s    r&   yyReferenceFrame.yy  r?  r)   c                 X    [         R                  " U R                  U R                  5      $ )z:Unit dyad of basis Vectors y and z for the ReferenceFrame.)r   r<  rQ   rR   r,   s    r&   yzReferenceFrame.yz  r?  r)   c                 X    [         R                  " U R                  U R                  5      $ )z:Unit dyad of basis Vectors z and x for the ReferenceFrame.)r   r<  rR   rP   r,   s    r&   zxReferenceFrame.zx  r?  r)   c                 X    [         R                  " U R                  U R                  5      $ )z:Unit dyad of basis Vectors z and y for the ReferenceFrame.)r   r<  rR   rQ   r,   s    r&   zyReferenceFrame.zy  r?  r)   c                 X    [         R                  " U R                  U R                  5      $ )z:Unit dyad of basis Vectors z and z for the ReferenceFrame.)r   r<  rR   r,   s    r&   zzReferenceFrame.zz  r?  r)   c                 N    U R                   U R                  -   U R                  -   $ )z#Unit dyadic for the ReferenceFrame.)r=  rJ  rV  r,   s    r&   uReferenceFrame.u  s      ww 477**r)   c                     SSK Jn  U R                  U5      nU" U/X!5      S   n[        U5      S:X  a  US   $ [	        U5      $ )a  Returns the partial angular velocities of this frame in the given
frame with respect to one or more provided generalized speeds.

Parameters
==========
frame : ReferenceFrame
    The frame with which the angular velocity is defined in.
gen_speeds : functions of time
    The generalized speeds.

Returns
=======
partial_velocities : tuple of Vector
    The partial angular velocity vectors corresponding to the provided
    generalized speeds.

Examples
========

>>> from sympy.physics.vector import ReferenceFrame, dynamicsymbols
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> u1, u2 = dynamicsymbols('u1, u2')
>>> A.set_ang_vel(N, u1 * A.x + u2 * N.y)
>>> A.partial_velocity(N, u1)
A.x
>>> A.partial_velocity(N, u1, u2)
(A.x, N.y)

r   )partial_velocityr=   )r   r\  r   rZ   rX   )r-   r!   
gen_speedsr\  velpartialss         r&   r\  ReferenceFrame.partial_velocity  sJ    @ 	Dooe$#SE:=a@x=AA;?"r)   )rd   rc   rf   rb   ra   re   r`   rM   rN   rO   r"   r_   r^   r    r]   r[   rh   )NNN)r   )r   NNN).r@   rA   rB   rC   rD   ri   rm   rq   ru   rx   __repr__r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r$  r)  r.  r2  rE   rP   rQ   rR   r=  rA  rD  rG  rJ  rM  rP  rS  rV  rY  r\  rF   r9   r)   r&   r   r   U   s    FY+v4*. HFOP	<)V!>F"HTl38jWrH'TCJ'(0TbH`DZxNM` ?A7;n`"8H"8H       , , , , , , , , , , , , , , , , , , + +(#r)   c                 ^    SSK Jn  [        U [        5      (       d  U" U [        S5      5      eg )Nr=   )VectorTypeErrorA)vectorrc  r3   r   )r5   rc  s     r&   r   r   $  s)    'e^,,e^C%899 -r)   N)sympyr   r   r   r   r   r   r	   r
   rg   r   sympy.core.symbolr   sympy.simplify.trigsimpr   sympy.physics.vector.vectorr   r   sympy.utilities.miscr   warningsr   __all__r   r   r   r9   r)   r&   <module>rm     sT   G G G $ , = * ,
-E@F E@PL# L#^.:r)   