K i<ddlmZddlmZddlmZddlmZmZm Z ddl m Z ddl m Z ddl mZddlmZdd lmZdd lmZdd lmZdd lmZdd lmZddlmZmZmZm Z ddl!m"Z"ddl mZddl#m$Z$ddl%m&Z&ddl'Z(ddl)m*Z*m+Z+m,Z,m-Z-m.Z.GddeZ/dZ0ddl1m2Z2y))Callable)Basic)cacheit)SDummyLambda)Str)symbols)ImmutableDenseMatrix) MatrixBase)solve) BaseScalar)Tuple)diff)sqrt)acosatan2cossin)eyesimplify)trigsimpN)Orienter AxisOrienter BodyOrienter SpaceOrienterQuaternionOrienterceZdZdZ d fd ZdZdZedZedZ dZ edZ ed Z d Z ed Zed Zed ZdZdZdZdZdZdZdZedZdZ d!dZ d"dZ d"dZ d"dZ d"dZ! d"dZ"d!dZ# d#dZ$eje$_edZ%xZ&S)$ CoordSys3Dz6 Represents a coordinate system in 3-D space. c t|}tjj}tjj} t |ts t d|| tdt tttfr1t dtr d}d}ntddnt tr-tdt\} } } t| | | f| | | nVt tr t!n:t t tfrn#t dj#t%|t't)d }n+t |ts t d |j+}|t |t,s t d | |j.}nCt ||s t d |j0D]} t | t2std |j4j7|dz|}n|j.}| |dz} t||t trKt,j9dd|}\j:t,j=d}fd}nt t rj>}t,jA|}|K|jCtDjFtDjFtDjFfk7r tdt,j=|}t,jI|}nft tr:t,jKs td}t,jM|}d}nfd}t,j=}d}|Vt trgd}nAt t r-j>dk(rgd}nj>dk(rgd}n gd}ngd}|gd}|tN||t!||}ntN||t!|}||_)tUd|t|}|D cgc] } d| d|d }} |D cgc] } | d| }} ||_+tYd||d|d}tYd||d|d}tYd ||d |d }|||f|_-tUd!|t|}|D cgc] } d"| d|d }} |D cgc] } | d| }} ||_.||_+t3d||d|d} t3d||d|d} t3d ||d |d } | | | f|_/|_0||_1|| | | |_2||_3ti||d| ti||d| ti||d | ti||d|ti||d|ti||d |||_5|jj|jjjl|_6n||_6||_7||_8|Scc} wcc} wcc} wcc} w)#a} The orientation/location parameters are necessary if this system is being defined at a certain orientation or location wrt another. Parameters ========== name : str The name of the new CoordSys3D instance. transformation : Lambda, Tuple, str Transformation defined by transformation equations or chosen from predefined ones. location : Vector The position vector of the new system's origin wrt the parent instance. rotation_matrix : SymPy ImmutableMatrix The rotation matrix of the new coordinate system with respect to the parent. In other words, the output of new_system.rotation_matrix(parent). parent : CoordSys3D The coordinate system wrt which the orientation/location (or both) is being defined. vector_names, variable_names : iterable(optional) Iterables of 3 strings each, with custom names for base vectors and base scalars of the new system respectively. Used for simple str printing. zname should be a stringNz?specify either `transformation` or `location`/`rotation_matrix`rzx1 x2 x3clsztransformation: wrong type {}z5rotation_matrix should be an ImmutableMatrix instancez"parent should be a CoordSys3D/Nonezlocation should be a Vectorz'location should not contain BaseScalarsz.origin cartesiancfjt|dz |dz |dz gzS)Nrr")invMatrix)xyzlrs _/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/vector/coordsysrect.pyz$CoordSys3D.__new__..s;QUUWV1Q41Q41Q4(6*.*z=Parent for pre-defined coordinate system should be Cartesian.zHThe transformation equation does not create orthogonal coordinate systemc|||SN)r+r,r-transformations r0r1z$CoordSys3D.__new__..sN1a4Kr2)x1x2x3 sphericalr/thetaphi cylindrical)r/r<r-r+r,r-)ijk vector_namesz \mathbf{\hat{z}_{z}}_r(variable_namesz \mathbf{{)9strsympyvectorVectorPoint isinstance TypeError ValueErrorrtuplelistr rrr rr formattyper r as_immutabler zero free_symbolsrorigin locate_new!_compose_rotation_and_translation _projections_get_lame_coeffname_get_transformation_lambdaslame_coefficientsrOne_set_inv_trans_equations_check_orthogonality_calculate_lame_coeffsuper__new___name_check_strings _vector_names BaseVector _base_vectors_variable_names _base_scalars_transformation_transformation_lambda_lame_coefficients"_transformation_from_parent_lambdasetattr_parent_root_parent_rotation_matrix_origin)r$rZr6parentlocationrotation_matrixrCrErIrJr7r8r9r+rUlambda_transformation lambda_lamelambda_inversetrnameobj latex_vects pretty_vectsv1v2v3 latex_scalarspretty_scalarsr.r/ __class__s ` @@r0rbzCoordSys3D.__new__sjH4y$$ ""$$56 6  %$/*E "@AA.5%*>?nQ/<&4Q&7O-a0H%+N1,=,:1,=&?NNH5$ZU; B!'R (6r2r(B"DNC0!$^!4NS&M:!006tN7K0LNN  "23q6:Ooz:!233-::.68F{{H4)+,F  !"?H=N ne ,$.$P$Pq!q!% ! "DAqA$44[AK*N  ,#((F$.$J$J6$R !!++-!%%1FF$&?@@$44VB "GHH$2 !$::;PQK!N$K !$44^DK!N  !.&1!3NC0!&&+5%:N#((M9%8N%4N!0  *L  '/SY8C'/SY0C  ~|4L) ,.67=. .5AB1d+B B( 3 QQ @ 3 QQ @ 3 QQ @RL '6n-,.45d;. .7EF!Q-FF,( 3q 1=3C D 3q 1=3C D 3q 1=3C DRL,%:"!,RR!81?.^A&+^A&+^A&+\!_b)\!_b)\!_b) ;; " ))CICI&5#  k.B.Fs'X9=X>5Y Yc|jSr4)rc)selfprinters r0 _sympystrzCoordSys3D._sympystrs zzr2c4t|jSr4)iter base_vectorsrs r0__iter__zCoordSys3D.__iter__sD%%'((r2c\tdt\}}}||||}tt|d|t|d|t|d|g}tt|d|t|d|t|d|g}tt|d|t|d|t|d|g}t d|||fDryt |j |dk(r;t |j |dk(rt |j |dk(ryy) a Helper method for _connect_to_cartesian. It checks if set of transformation equations create orthogonal curvilinear coordinate system Parameters ========== equations : Lambda Lambda of transformation equations x1, x2, x3r#rr"r(c3VK|]!}t|d|dz|dzdk(#yw)rr"r(Nr).0r@s r0 z2CoordSys3D._check_orthogonality..s/GQx!qt ad*+q0Gs')FT)r rr*ranyrdot) equationsr7r8r9r}r~rs r0r_zCoordSys3D._check_orthogonalitys0\u5 Bb"b) T)A,+)A,+T)A,-CEFT)A,+)A,+T)A,-CEFT)A,+)A,+T)A,-CEF G2r2,G Gr #q(XbffRj-AQ-FRVVBZ(A-r2cH|dk(rdS|dk(rdS|dk(rdStd)z Store information about inverse transformation equations for pre-defined coordinate systems. Parameters ========== curv_coord_name : str Name of coordinate system r&c |||fSr4r5r?s r0r1z5CoordSys3D._set_inv_trans_equations..5s Aq!9r2r:c t|dz|dzz|dzzt|t|dz|dzz|dzzz t||fSNr()rrrr?s r0r1z5CoordSys3D._set_inv_trans_equations..8sVQTAqD[1a4'(QtAqD1a4K!Q$.//0a $r2r>cDt|dz|dzzt|||fSr)rrr?s r0r1z5CoordSys3D._set_inv_trans_equations..>s)QTAqD[!a $r2...Vs3$`TUQVVDaAYR 1M,N%O$`s47)rN)r7r8r9solvedr+r,r-s```r0r1z;CoordSys3D._calculate_inv_trans_equations..Vsu$`$`Y_$``r2N)r rrjr rm) rr7r8r9rrr+r,r-s @@@@r0_calculate_inv_trans_equationsz)CoordSys3D._calculate_inv_trans_equationsFs \uDA B)/1a((R4  ! q(!! q(!! q(*,.B.gsquuaee'<r2r:c@tj||t|zfSr4)rr]rr;s r0r1z,CoordSys3D._get_lame_coeff..isaeeQ#e* -Er2r>cDtj|tjfSr4rr/r<hs r0r1z,CoordSys3D._get_lame_coeff..ksAEE1aee+<r2zAWrong set of parameters. Type of coordinate system is not defined)rKrFrMr _calculate_lame_coefficientsrs r0rYzCoordSys3D._get_lame_coeffXs^ os ++-<<+-EE-/<<IJ J66GGr2cfdS)z It calculates Lame coefficients for given transformations equations. Parameters ========== equations : Lambda Lambda of transformation equations. c tt|||d|dzt|||d|dzzt|||d|dzztt|||d|dzt|||d|dzzt|||d|dzztt|||d|dzt|||d|dzzt|||d|dzzfS)Nrr(r")rr)r7r8r9rs r0r1z2CoordSys3D._calculate_lame_coeff..}sOtIb"b$9!$.s 1ayr2r:c|t|zt|z|t|zt|z|t|zfSr4)rrr;s r0r1z8CoordSys3D._get_transformation_lambdas..s<c%jLS)c%jLS)c%jL.r2r>c<|t|z|t|z|fSr4)rrrs r0r1z8CoordSys3D._get_transformation_lambdas..s"c%jLc%jL,r2rN)rKrFrMrs r0r[z&CoordSys3D._get_transformation_lambdass^ os ++-00+- -/ DE E ,r2c0t|t|zS)z Returns the transformation equations obtained from rotation matrix. Parameters ========== matrix : Matrix Rotation matrix equations : tuple Transformation equations )rNr*)r$matrixrs r0_rotation_trans_equationsz$CoordSys3D._rotation_trans_equationssVfY//00r2c|jSr4)rrrs r0rUzCoordSys3D.origins ||r2c|jSr4)rgrs r0rzCoordSys3D.base_vectors!!!r2c|jSr4)rirs r0 base_scalarszCoordSys3D.base_scalarsrr2c|jSr4)rlrs r0r\zCoordSys3D.lame_coefficientss&&&r2c<|j|jSr4)rkrrs r0transformation_to_parentz#CoordSys3D.transformation_to_parents*t**D,=,=,?@@r2c~|j td|j|jjS)NzHno parent coordinate system, use `transformation_from_parent_function()`)rorMrmrrs r0transformation_from_parentz%CoordSys3D.transformation_from_parentsF << GH H6t66!\\668: :r2c|jSr4)rmrs r0#transformation_from_parent_functionz.CoordSys3D.transformation_from_parent_functions666r2cddlm}t|tst t |dz||k(r t dS||jk(r |jS|j|k(r|jjS|||\}}t d}t|D]}|||jz}t|dzt|D]}|||jjz} |S)ar Returns the direction cosine matrix(DCM), also known as the 'rotation matrix' of this coordinate system with respect to another system. If v_a is a vector defined in system 'A' (in matrix format) and v_b is the same vector defined in system 'B', then v_a = A.rotation_matrix(B) * v_b. A SymPy Matrix is returned. Parameters ========== other : CoordSys3D The system which the DCM is generated to. Examples ======== >>> from sympy.vector import CoordSys3D >>> from sympy import symbols >>> q1 = symbols('q1') >>> N = CoordSys3D('N') >>> A = N.orient_new_axis('A', q1, N.i) >>> N.rotation_matrix(A) Matrix([ [1, 0, 0], [0, cos(q1), -sin(q1)], [0, sin(q1), cos(q1)]]) r)_pathz is not a CoordSys3Dr%r") sympy.vector.functionsrrKr rLrFrrorqTrangelen)rotherr rootindexpathresultr@s r0ruzCoordSys3D.rotation_matrixsB 1%,CJ234 4 D=q6M dll "// / ]]d "0022 2e, 4Qy! 6A d1g55 5F 6y1}c$i0 8A d1g5577 7F 8 r2c8|jj|S)ab Returns the position vector of the origin of this coordinate system with respect to another Point/CoordSys3D. Parameters ========== other : Point/CoordSys3D If other is a Point, the position of this system's origin wrt it is returned. If its an instance of CoordSyRect, the position wrt its origin is returned. Examples ======== >>> from sympy.vector import CoordSys3D >>> N = CoordSys3D('N') >>> N1 = N.locate_new('N1', 10 * N.i) >>> N.position_wrt(N1) (-10)*N.i )rU position_wrt)rrs r0rzCoordSys3D.position_wrts0{{''..r2c zt|j|j|}t|j Dcgc] \}}|||z }}}|j |t |z}t|j Dcic]\}}|t||c}}Scc}}wcc}}w)as Returns a dictionary which expresses the coordinate variables (base scalars) of this frame in terms of the variables of otherframe. Parameters ========== otherframe : CoordSys3D The other system to map the variables to. Examples ======== >>> from sympy.vector import CoordSys3D >>> from sympy import Symbol >>> A = CoordSys3D('A') >>> q = Symbol('q') >>> B = A.orient_new_axis('B', q, A.k) >>> A.scalar_map(B) {A.x: B.x*cos(q) - B.y*sin(q), A.y: B.x*sin(q) + B.y*cos(q), A.z: B.z} )rNr to_matrix enumeraterrur*r)rr origin_coordsr@r+relocated_scalars vars_matrixs r0 scalar_mapzCoordSys3D.scalar_map(s2d//6@@GH )253E3E3G)HJ!%Aq!11JJ++E2/01 &d&7&7&9:<Aq8KN++< < J >> from sympy.vector import CoordSys3D >>> A = CoordSys3D('A') >>> B = A.locate_new('B', 10 * A.i) >>> B.origin.position_wrt(A.origin) 10*A.i )rtrCrErs)rhrer )rrZpositionrCrEs r0rVzCoordSys3D.locate_newJs@>  !!11N  --L$'3)7!%' 'r2c| |j}| |j}t|tr>t|tr|j |}n|j }t |}nSttd}|D]:}t|tr||j |z}(||j z}<t||||||S)at Creates a new CoordSys3D oriented in the user-specified way with respect to this system. Please refer to the documentation of the orienter classes for more information about the orientation procedure. Parameters ========== name : str The name of the new CoordSys3D instance. orienters : iterable/Orienter An Orienter or an iterable of Orienters for orienting the new coordinate system. If an Orienter is provided, it is applied to get the new system. If an iterable is provided, the orienters will be applied in the order in which they appear in the iterable. location : Vector(optional) The location of the new coordinate system's origin wrt this system's origin. If not specified, the origins are taken to be coincident. vector_names, variable_names : iterable(optional) Iterables of 3 strings each, with custom names for base vectors and base scalars of the new system respectively. Used for simple str printing. Examples ======== >>> from sympy.vector import CoordSys3D >>> from sympy import symbols >>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3') >>> N = CoordSys3D('N') Using an AxisOrienter >>> from sympy.vector import AxisOrienter >>> axis_orienter = AxisOrienter(q1, N.i + 2 * N.j) >>> A = N.orient_new('A', (axis_orienter, )) Using a BodyOrienter >>> from sympy.vector import BodyOrienter >>> body_orienter = BodyOrienter(q1, q2, q3, '123') >>> B = N.orient_new('B', (body_orienter, )) Using a SpaceOrienter >>> from sympy.vector import SpaceOrienter >>> space_orienter = SpaceOrienter(q1, q2, q3, '312') >>> C = N.orient_new('C', (space_orienter, )) Using a QuaternionOrienter >>> from sympy.vector import QuaternionOrienter >>> q_orienter = QuaternionOrienter(q0, q1, q2, q3) >>> D = N.orient_new('D', (q_orienter, )) r%)rurCrErtrs) rhrerKrrrurr*rr )rrZ orientersrtrCrE final_matrixorienters r0 orient_newzCoordSys3D.orient_newssB  !!11N  --L i *)\2(88> (88: $L1L!#a&>L% ?h 5 H$<$>L  ? $ '3)7#+!% ' 'r2c~| |j}| |j}t||}|j|||||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 ========== name : string The name of the new coordinate system 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 location : Vector(optional) The location of the new coordinate system's origin wrt this system's origin. If not specified, the origins are taken to be coincident. vector_names, variable_names : iterable(optional) Iterables of 3 strings each, with custom names for base vectors and base scalars of the new system respectively. Used for simple str printing. Examples ======== >>> from sympy.vector import CoordSys3D >>> from sympy import symbols >>> q1 = symbols('q1') >>> N = CoordSys3D('N') >>> B = N.orient_new_axis('B', q1, N.i + 2 * N.j) rtrCrE)rhrerr)rrZangleaxisrtrCrErs r0orient_new_axiszCoordSys3D.orient_new_axissVN  !!11N  --Lt,tX(0,8.<> >r2c Jt||||} |j|| |||S)an 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 ========== name : string The name of the new coordinate system angle1, angle2, angle3 : Expr Three successive angles to rotate the coordinate system by rotation_order : string String defining the order of axes for rotation location : Vector(optional) The location of the new coordinate system's origin wrt this system's origin. If not specified, the origins are taken to be coincident. vector_names, variable_names : iterable(optional) Iterables of 3 strings each, with custom names for base vectors and base scalars of the new system respectively. Used for simple str printing. Examples ======== >>> from sympy.vector import CoordSys3D >>> 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, >>> D = N.orient_new_body('D', q1, q2, q3, '123') is same as >>> D = N.orient_new_axis('D', q1, N.i) >>> D = D.orient_new_axis('D', q2, D.j) >>> D = D.orient_new_axis('D', q3, D.k) 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. >>> B = N.orient_new_body('B', q1, q2, q3, '123') >>> B = N.orient_new_body('B', q1, q2, 0, 'ZXZ') >>> B = N.orient_new_body('B', 0, 0, 0, 'XYX') r)rr rrZangle1angle2angle3rotation_orderrtrCrErs r0orient_new_bodyzCoordSys3D.orient_new_bodys8B GtX(0,8.<> >r2c Jt||||} |j|| |||S)a Space rotation is similar to Body rotation, but the rotations are applied in the opposite order. Parameters ========== name : string The name of the new coordinate system angle1, angle2, angle3 : Expr Three successive angles to rotate the coordinate system by rotation_order : string String defining the order of axes for rotation location : Vector(optional) The location of the new coordinate system's origin wrt this system's origin. If not specified, the origins are taken to be coincident. vector_names, variable_names : iterable(optional) Iterables of 3 strings each, with custom names for base vectors and base scalars of the new system respectively. Used for simple str printing. See Also ======== CoordSys3D.orient_new_body : method to orient via Euler angles Examples ======== >>> from sympy.vector import CoordSys3D >>> 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, >>> D = N.orient_new_space('D', q1, q2, q3, '312') is same as >>> B = N.orient_new_axis('B', q1, N.i) >>> C = B.orient_new_axis('C', q2, N.j) >>> D = C.orient_new_axis('D', q3, N.k) r)rrrs r0orient_new_spacezCoordSys3D.orient_new_spaceKs8v!HtX(0,8.<> >r2c Jt||||} |j|| |||S)aF 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 ========== name : string The name of the new coordinate system q0, q1, q2, q3 : Expr The quaternions to rotate the coordinate system by location : Vector(optional) The location of the new coordinate system's origin wrt this system's origin. If not specified, the origins are taken to be coincident. vector_names, variable_names : iterable(optional) Iterables of 3 strings each, with custom names for base vectors and base scalars of the new system respectively. Used for simple str printing. Examples ======== >>> from sympy.vector import CoordSys3D >>> from sympy import symbols >>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3') >>> N = CoordSys3D('N') >>> B = N.orient_new_quaternion('B', q0, q1, q2, q3) r)rr) rrZq0q1q2q3rtrCrErs r0orient_new_quaternionz CoordSys3D.orient_new_quaternions8b&b"b"5tX(0,8.<> >r2c"t|||||S)a  Returns a CoordSys3D which is connected to self by transformation. Parameters ========== name : str The name of the new CoordSys3D instance. transformation : Lambda, Tuple, str Transformation defined by transformation equations or chosen from predefined ones. vector_names, variable_names : iterable(optional) Iterables of 3 strings each, with custom names for base vectors and base scalars of the new system respectively. Used for simple str printing. Examples ======== >>> from sympy.vector import CoordSys3D >>> a = CoordSys3D('a') >>> b = a.create_new('b', transformation='spherical') >>> b.transformation_to_parent() (b.r*sin(b.theta)*cos(b.phi), b.r*sin(b.phi)*sin(b.theta), b.r*cos(b.theta)) >>> b.transformation_from_parent() (sqrt(a.x**2 + a.y**2 + a.z**2), acos(a.z/sqrt(a.x**2 + a.y**2 + a.z**2)), atan2(a.y, a.x)) )rsr6rErC)r )rrZr6rErCs r0 create_newzCoordSys3D.create_news>$tN)7lT Tr2c yr4r5) rrZrtrursrCrEr{r|rrr6s r0__init__zCoordSys3D.__init__s r2cfd|S|jDcgc]}|j|c}\fdfdScc}w)Nc6tj|||fSr4)r r)r+r,r-rots r0r1z>CoordSys3D._compose_rotation_and_translation..sJ@@q!QiPr2c |z|z|zfSr4r5)r+r,r-dxdydzs r0r1z>CoordSys3D._compose_rotation_and_translation..s F F F r2c|||Sr4r5)r+r,r-r/ts r0r1z>CoordSys3D._compose_rotation_and_translation..sq!Aq!*~r2)rr) r translationrsr@rrrr/rs ` @@@@@r0rWz,CoordSys3D._compose_rotation_and_translationsO P >H282E2E2GHQkooa(H B  .- IsA)NNNNNN)NN)NNN) NNNNNNNNNN)'__name__ __module__ __qualname____doc__rbrr staticmethodr_r^rrYr`rr[ classmethodrpropertyrUrrr\rrrrurrrrVrrrrrrrrW __classcell__)rs@r0r r sGKHL^@)  DAA<a$HH.0: EE<11 ""'A:73j / /2 0>f26:>E>P37;??>BDH@D5>n TD=A@DDH59 H . .r2r c|dz}t|dk7r t||D]}t|trt |y)Nz& must be an iterable of 3 string-typesr%)rrMrKrFrL)arg_nameargerrorstrss r0rdrdsGBBH 3x1}"" &!S!H% %&r2)rf)3collections.abcrsympy.core.basicrsympy.core.cacher sympy.corerrrsympy.core.symbolr r sympy.matrices.immutabler r*sympy.matrices.matrixbaser sympy.solversr sympy.vector.scalarrsympy.core.containersrsympy.core.functionr(sympy.functions.elementary.miscellaneousr(sympy.functions.elementary.trigonometricrrrrsympy.matrices.densersympy.simplify.simplifyrsympy.simplify.trigsimpr sympy.vectorrGsympy.vector.orientersrrrrrr rdsympy.vector.vectorrfr5r2r0r!si$"$''!%C0*'$9LL$9,,GGa.a.H&+r2