'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.
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.'

def __new__(cls, name, location=None, rotation_matrix=None, parent=None, vector_names=None, variable_names=None):

    name = str(name)
    Vector = sympy.vector.Vector
    BaseVector = sympy.vector.BaseVector
    Point = sympy.vector.Point
    if (not isinstance(name, string_types)):
        raise TypeError('name    should    be    a    string')
    if (rotation_matrix is None):
        parent_orient = Matrix(eye(3))
    else:
        if (not isinstance(rotation_matrix, Matrix)):
            raise TypeError(('rotation_matrix    should    be    an    Immutable' + 'Matrix    instance'))
        parent_orient = rotation_matrix
    if (parent is not None):
        if (not isinstance(parent, CoordSys3D)):
            raise TypeError(('parent    should    be    a    ' + 'CoordSys3D/None'))
        if (location is None):
            location = Vector.zero
        else:
            if (not isinstance(location, Vector)):
                raise TypeError('location    should    be    a    Vector')
            for x in location.free_symbols:
                if isinstance(x, BaseScalar):
                    raise ValueError(('location    should    not    contain' + '    BaseScalars'))
        origin = parent.origin.locate_new((name + '.origin'), location)
    else:
        location = Vector.zero
        origin = Point((name + '.origin'))
    if (parent is not None):
        obj = super(CoordSys3D, cls).__new__(cls, Symbol(name), location, parent_orient, parent)
    else:
        obj = super(CoordSys3D, cls).__new__(cls, Symbol(name), location, parent_orient)
    obj._name = name
    if (vector_names is None):
        vector_names = ((name + '.i'), (name + '.j'), (name + '.k'))
        latex_vects = [('\\mathbf{\\hat{i}_{%s}}' % name), ('\\mathbf{\\hat{j}_{%s}}' % name), ('\\mathbf{\\hat{k}_{%s}}' % name)]
        pretty_vects = ((name + '_i'), (name + '_j'), (name + '_k'))
    else:
        _check_strings('vector_names', vector_names)
        vector_names = list(vector_names)
        latex_vects = [('\\mathbf{\\hat{%s}_{%s}}' % (x, name)) for x in vector_names]
        pretty_vects = [((name + '_') + x) for x in vector_names]
    obj._i = BaseVector(vector_names[0], 0, obj, pretty_vects[0], latex_vects[0])
    obj._j = BaseVector(vector_names[1], 1, obj, pretty_vects[1], latex_vects[1])
    obj._k = BaseVector(vector_names[2], 2, obj, pretty_vects[2], latex_vects[2])
    if (variable_names is None):
        variable_names = ((name + '.x'), (name + '.y'), (name + '.z'))
        latex_scalars = [('\\mathbf{{x}_{%s}}' % name), ('\\mathbf{{y}_{%s}}' % name), ('\\mathbf{{z}_{%s}}' % name)]
        pretty_scalars = ((name + '_x'), (name + '_y'), (name + '_z'))
    else:
        _check_strings('variable_names', vector_names)
        variable_names = list(variable_names)
        latex_scalars = [('\\mathbf{{%s}_{%s}}' % (x, name)) for x in variable_names]
        pretty_scalars = [((name + '_') + x) for x in variable_names]
    obj._x = BaseScalar(variable_names[0], 0, obj, pretty_scalars[0], latex_scalars[0])
    obj._y = BaseScalar(variable_names[1], 1, obj, pretty_scalars[1], latex_scalars[1])
    obj._z = BaseScalar(variable_names[2], 2, obj, pretty_scalars[2], latex_scalars[2])
    obj._h1 = S.One
    obj._h2 = S.One
    obj._h3 = S.One
    obj._transformation_eqs = (obj._x, obj._y, obj._y)
    obj._inv_transformation_eqs = (lambda x, y, z: (x, y, z))
    obj._parent = parent
    if (obj._parent is not None):
        obj._root = obj._parent._root
    else:
        obj._root = obj
    obj._parent_rotation_matrix = parent_orient
    obj._origin = origin
    return obj
