'Returns a rotated copy of this image.  This method returns a
copy of this image, rotated the given number of degrees counter
clockwise around its centre.
:param angle: In degrees counter clockwise.
:param resample: An optional resampling filter.  This can be
one of :py:attr:`PIL.Image.NEAREST` (use nearest neighbour),
:py:attr:`PIL.Image.BILINEAR` (linear interpolation in a 2x2
environment), or :py:attr:`PIL.Image.BICUBIC`
(cubic spline interpolation in a 4x4 environment).
If omitted, or if the image has mode "1" or "P", it is
set :py:attr:`PIL.Image.NEAREST`. See :ref:`concept-filters`.
:param expand: Optional expansion flag.  If true, expands the output
image to make it large enough to hold the entire rotated image.
If false or omitted, make the output image the same size as the
input image.  Note that the expand flag assumes rotation around
the center and no translation.
:param center: Optional center of rotation (a 2-tuple).  Origin is
the upper left corner.  Default is the center of the image.
:param translate: An optional post-rotate translation (a 2-tuple).
:returns: An :py:class:`~PIL.Image.Image` object.'

def rotate(self, angle, resample=NEAREST, expand=0, center=None, translate=None):

    angle = (angle % 360.0)
    if (not (center or translate)):
        if (angle == 0):
            return self.copy()
        if (angle == 180):
            return self.transpose(ROTATE_180)
        if ((angle == 90) and expand):
            return self.transpose(ROTATE_90)
        if ((angle == 270) and expand):
            return self.transpose(ROTATE_270)
    (w, h) = self.size
    if (translate is None):
        translate = [0, 0]
    if (center is None):
        center = [(w / 2.0), (h / 2.0)]
    angle = (- math.radians(angle))
    matrix = [round(math.cos(angle), 15), round(math.sin(angle), 15), 0.0, round((- math.sin(angle)), 15), round(math.cos(angle), 15), 0.0]
    def transform(x, y, matrix):
        (a, b, c, d, e, f) = matrix
        return ((((a * x) + (b * y)) + c), (((d * x) + (e * y)) + f))
    (matrix[2], matrix[5]) = transform(((- center[0]) - translate[0]), ((- center[1]) - translate[1]), matrix)
    matrix[2] += center[0]
    matrix[5] += center[1]
    if expand:
        xx = []
        yy = []
        for (x, y) in ((0, 0), (w, 0), (w, h), (0, h)):
            (x, y) = transform(x, y, matrix)
            xx.append(x)
            yy.append(y)
        nw = int((math.ceil(max(xx)) - math.floor(min(xx))))
        nh = int((math.ceil(max(yy)) - math.floor(min(yy))))
        (matrix[2], matrix[5]) = transform(((- (nw - w)) / 2.0), ((- (nh - h)) / 2.0), matrix)
        (w, h) = (nw, nh)
    return self.transform((w, h), AFFINE, matrix, resample)
