ó
¡¼™\c           @   sý   d  d l  m Z d  d l m Z m Z m Z m Z m Z m Z m	 Z	 m
 Z m Z d  d l m Z d  d l Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d	 e f d
 „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d „  Z d S(   iÿÿÿÿ(   t   Basic(	   t   sympifyt   eyet   sint   cost	   rot_axis1t	   rot_axis2t	   rot_axis3t   ImmutableMatrixt   Symbol(   t   cacheitNt   Orienterc           B   s   e  Z d  Z d „  Z RS(   s/   
    Super-class for all orienter classes.
    c         C   s   |  j  S(   sV   
        The rotation matrix corresponding to this orienter
        instance.
        (   t   _parent_orient(   t   self(    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyt   rotation_matrix   s    (   t   __name__t
   __module__t   __doc__R   (    (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR      s   t   AxisOrienterc           B   sM   e  Z d  Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z	 RS(   s+   
    Class to denote an axis orienter.
    c         C   sd   t  | t j j ƒ s$ t d ƒ ‚ n  t | ƒ } t t |  ƒ j |  | | ƒ } | | _	 | | _
 | S(   Ns   axis should be a Vector(   t
   isinstancet   sympyt   vectort   Vectort	   TypeErrorR   t   superR   t   __new__t   _anglet   _axis(   t   clst   anglet   axist   obj(    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR      s    			c         C   s   d S(   sá  
        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, ))

        N(    (   R   R   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyt   __init__&   s    c         C   sÂ   t  j j |  j | ƒ 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(   sø   
        The rotation matrix corresponding to this orienter
        instance.

        Parameters
        ==========

        system : CoordSys3D
            The coordinate system wrt which the rotation matrix
            is to be computed
        i   i    i   i   (   R   R   t   expressR   t	   normalizet	   to_matrixR   R   t   TR   t   MatrixR   (   R   t   systemR   t   thetat   parent_orient(    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR   D   s    	q	c         C   s   |  j  S(   N(   R   (   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR   ]   s    c         C   s   |  j  S(   N(   R   (   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR   a   s    (
   R   R   R   R   R    R
   R   t   propertyR   R   (    (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR      s   		t   ThreeAngleOrienterc           B   sS   e  Z d  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z RS(   s3   
    Super-class for Body and Space orienters.
    c         C   sî  d } | } t  | ƒ j ƒ  } t | ƒ d k s? t d ƒ ‚ n  g  | D] } | j d d ƒ ^ qF } g  | D] } | j d d ƒ ^ qk } g  | D] } | j d d ƒ ^ q } d j | ƒ } | | k rØ t d ƒ ‚ n  t | d ƒ } t | d ƒ }	 t | d ƒ }
 t | ƒ } t | ƒ } t | ƒ } |  j rat	 | | ƒ t	 |	 | ƒ t	 |
 | ƒ } n) t	 |
 | ƒ t	 |	 | ƒ t	 | | ƒ } | j
 } t t |  ƒ j |  | | | t | ƒ ƒ } | | _ | | _ | | _ | | _ | | _ | S(   Nt   123t   231t   312t   132t   213t   321t   121t   131t   212t   232t   313t   323t    i   s%   rot_order should be a str of length 3t   Xt   1t   Yt   2t   Zt   3s   Invalid rot_type parameteri    i   i   (   R+   R,   R-   R.   R/   R0   R1   R2   R3   R4   R5   R6   R7   (   t   strt   uppert   lenR   t   replacet   joint   intR   t	   _in_ordert   _rotR$   R   R*   R   R	   t   _angle1t   _angle2t   _angle3t
   _rot_orderR   (   R   t   angle1t   angle2t   angle3t	   rot_ordert   approved_orderst   original_rot_ordert   it   a1t   a2t   a3R(   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR   k   sB      %%%							c         C   s   |  j  S(   N(   RF   (   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyRJ   “   s    c         C   s   |  j  S(   N(   RG   (   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyRK   —   s    c         C   s   |  j  S(   N(   RH   (   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyRL   ›   s    c         C   s   |  j  S(   N(   RI   (   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyRM   Ÿ   s    (	   R   R   R   R   R)   RJ   RK   RL   RM   (    (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR*   f   s   	(t   BodyOrienterc           B   s&   e  Z d  Z e Z d „  Z d „  Z RS(   s*   
    Class to denote a body-orienter.
    c         C   s   t  j |  | | | | ƒ } | S(   N(   R*   R   (   R   RJ   RK   RL   RM   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR   «   s    	c         C   s   d S(   s’  
        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')

        N(    (   R   RJ   RK   RL   RM   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR    °   s    7(   R   R   R   t   TrueRD   R   R    (    (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyRT   ¤   s   	t   SpaceOrienterc           B   s&   e  Z d  Z e Z d „  Z d „  Z RS(   s+   
    Class to denote a space-orienter.
    c         C   s   t  j |  | | | | ƒ } | S(   N(   R*   R   (   R   RJ   RK   RL   RM   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR   ñ   s    	c         C   s   d S(   s¢  
        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, ))

        N(    (   R   RJ   RK   RL   RM   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR    ö   s    0(   R   R   R   t   FalseRD   R   R    (    (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyRV   ê   s   	t   QuaternionOrienterc           B   s\   e  Z d  Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z	 RS(   s0   
    Class to denote a quaternion-orienter.
    c         C   sr  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 t |  ƒ j |  | | | | ƒ } | | _ | | _ | | _ | | _	 | | _
 | S(   Ni   (   R   R%   R$   R   RX   R   t   _q0t   _q1t   _q2t   _q3R   (   R   t   q0t   q1t   q2t   q3R(   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR   .  s,    +	$					c         C   s   d S(   s¨  
        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, ))

        N(    (   R   RJ   RK   RL   RM   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR    J  s    %c         C   s   |  j  S(   N(   RY   (   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR]   q  s    c         C   s   |  j  S(   N(   RZ   (   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR^   u  s    c         C   s   |  j  S(   N(   R[   (   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR_   y  s    c         C   s   |  j  S(   N(   R\   (   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyR`   }  s    (
   R   R   R   R   R    R)   R]   R^   R_   R`   (    (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyRX   )  s   		'c         C   sa   |  d k r t  t | ƒ j ƒ S|  d k r> t  t | ƒ j ƒ S|  d k r] t  t | ƒ j ƒ Sd S(   s)   DCM for simple axis 1, 2 or 3 rotations. i   i   i   N(   R%   R   R$   R   R   (   R   R   (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyRE   ‚  s    (   t   sympy.core.basicR    R   R   R   R   R   R   R   R   R   R%   R	   t   sympy.core.cacheR
   t   sympy.vectorR   R   R*   RT   RV   RX   RE   (    (    (    s5   lib/python2.7/site-packages/sympy/vector/orienters.pyt   <module>   s   @Q>F?Y