def _draw_arc_arrow(self, inner_radius, outer_radius, startangle, endangle, color, border=None, shaft_height_ratio=0.4, head_length_ratio=0.5, orientation='right', colour=None, **kwargs):
    'Draw an arrow along an arc.'
    if (colour is not None):
        color = colour
    if (border is None):
        border = color
    if (color is None):
        color = colour
    if ((color == colors.white) and (border is None)):
        strokecolor = colors.black
    elif (border is None):
        strokecolor = color
    elif (border is not None):
        strokecolor = border
    (startangle, endangle) = (min(startangle, endangle), max(startangle, endangle))
    if ((orientation != 'left') and (orientation != 'right')):
        raise ValueError(("Invalid orientation %s, should be 'left' or 'right'" % repr(orientation)))
    angle = float((endangle - startangle))
    middle_radius = (0.5 * (inner_radius + outer_radius))
    boxheight = (outer_radius - inner_radius)
    shaft_height = (boxheight * shaft_height_ratio)
    shaft_inner_radius = (middle_radius - (0.5 * shaft_height))
    shaft_outer_radius = (middle_radius + (0.5 * shaft_height))
    headangle_delta = max(0.0, min(((abs(boxheight) * head_length_ratio) / middle_radius), abs(angle)))
    if (angle < 0):
        headangle_delta *= (- 1)
    if (orientation == 'right'):
        headangle = (endangle - headangle_delta)
    else:
        headangle = (startangle + headangle_delta)
    if (startangle <= endangle):
        headangle = max(min(headangle, endangle), startangle)
    else:
        headangle = max(min(headangle, startangle), endangle)
    assert ((startangle <= headangle <= endangle) or (endangle <= headangle <= startangle)), (startangle, headangle, endangle, angle)
    (startcos, startsin) = (cos(startangle), sin(startangle))
    (headcos, headsin) = (cos(headangle), sin(headangle))
    (endcos, endsin) = (cos(endangle), sin(endangle))
    (x0, y0) = (self.xcenter, self.ycenter)
    if ((0.5 >= abs(angle)) and (abs(headangle_delta) >= abs(angle))):
        if (orientation == 'right'):
            (x1, y1) = ((x0 + (inner_radius * startsin)), (y0 + (inner_radius * startcos)))
            (x2, y2) = ((x0 + (outer_radius * startsin)), (y0 + (outer_radius * startcos)))
            (x3, y3) = ((x0 + (middle_radius * endsin)), (y0 + (middle_radius * endcos)))
        else:
            (x1, y1) = ((x0 + (inner_radius * endsin)), (y0 + (inner_radius * endcos)))
            (x2, y2) = ((x0 + (outer_radius * endsin)), (y0 + (outer_radius * endcos)))
            (x3, y3) = ((x0 + (middle_radius * startsin)), (y0 + (middle_radius * startcos)))
        return Polygon([x1, y1, x2, y2, x3, y3], strokeColor=(border or color), fillColor=color, strokeLineJoin=1, strokewidth=0)
    elif (orientation == 'right'):
        p = ArcPath(strokeColor=strokecolor, fillColor=color, strokeLineJoin=1, strokewidth=0, **kwargs)
        p.addArc(self.xcenter, self.ycenter, shaft_inner_radius, (90 - ((headangle * 180) / pi)), (90 - ((startangle * 180) / pi)), moveTo=True)
        p.addArc(self.xcenter, self.ycenter, shaft_outer_radius, (90 - ((headangle * 180) / pi)), (90 - ((startangle * 180) / pi)), reverse=True)
        p.lineTo((x0 + (outer_radius * headsin)), (y0 + (outer_radius * headcos)))
        if (abs(angle) < 0.5):
            p.lineTo((x0 + (middle_radius * endsin)), (y0 + (middle_radius * endcos)))
            p.lineTo((x0 + (inner_radius * headsin)), (y0 + (inner_radius * headcos)))
        else:
            dx = min(0.1, (abs(angle) / 50.0))
            x = dx
            while (x < 1):
                r = (outer_radius - (x * (outer_radius - middle_radius)))
                a = (headangle + (x * (endangle - headangle)))
                p.lineTo((x0 + (r * sin(a))), (y0 + (r * cos(a))))
                x += dx
            p.lineTo((x0 + (middle_radius * endsin)), (y0 + (middle_radius * endcos)))
            x = dx
            while (x < 1):
                r = (middle_radius - (x * (middle_radius - inner_radius)))
                a = (headangle + ((1 - x) * (endangle - headangle)))
                p.lineTo((x0 + (r * sin(a))), (y0 + (r * cos(a))))
                x += dx
            p.lineTo((x0 + (inner_radius * headsin)), (y0 + (inner_radius * headcos)))
        p.closePath()
        return p
    else:
        p = ArcPath(strokeColor=strokecolor, fillColor=color, strokeLineJoin=1, strokewidth=0, **kwargs)
        p.addArc(self.xcenter, self.ycenter, shaft_inner_radius, (90 - ((endangle * 180) / pi)), (90 - ((headangle * 180) / pi)), moveTo=True, reverse=True)
        p.addArc(self.xcenter, self.ycenter, shaft_outer_radius, (90 - ((endangle * 180) / pi)), (90 - ((headangle * 180) / pi)), reverse=False)
        p.lineTo((x0 + (outer_radius * headsin)), (y0 + (outer_radius * headcos)))
        if (abs(angle) < 0.5):
            p.lineTo((x0 + (middle_radius * startsin)), (y0 + (middle_radius * startcos)))
            p.lineTo((x0 + (inner_radius * headsin)), (y0 + (inner_radius * headcos)))
        else:
            dx = min(0.1, (abs(angle) / 50.0))
            x = dx
            while (x < 1):
                r = (outer_radius - (x * (outer_radius - middle_radius)))
                a = (headangle + (x * (startangle - headangle)))
                p.lineTo((x0 + (r * sin(a))), (y0 + (r * cos(a))))
                x += dx
            p.lineTo((x0 + (middle_radius * startsin)), (y0 + (middle_radius * startcos)))
            x = dx
            while (x < 1):
                r = (middle_radius - (x * (middle_radius - inner_radius)))
                a = (headangle + ((1 - x) * (startangle - headangle)))
                p.lineTo((x0 + (r * sin(a))), (y0 + (r * cos(a))))
                x += dx
            p.lineTo((x0 + (inner_radius * headsin)), (y0 + (inner_radius * headcos)))
        p.closePath()
        return p
Draw an arrow along an arc.
def _draw_arc_arrow(self, inner_radius, outer_radius, startangle, endangle, color, border=None, shaft_height_ratio=0.4, head_length_ratio=0.5, orientation='right', colour=None, **kwargs):
    
    if (colour is not None):
        color = colour
    if (border is None):
        border = color
    if (color is None):
        color = colour
    if ((color == colors.white) and (border is None)):
        strokecolor = colors.black
    elif (border is None):
        strokecolor = color
    elif (border is not None):
        strokecolor = border
    (startangle, endangle) = (min(startangle, endangle), max(startangle, endangle))
    if ((orientation != 'left') and (orientation != 'right')):
        raise ValueError(("Invalid orientation %s, should be 'left' or 'right'" % repr(orientation)))
    angle = float((endangle - startangle))
    middle_radius = (0.5 * (inner_radius + outer_radius))
    boxheight = (outer_radius - inner_radius)
    shaft_height = (boxheight * shaft_height_ratio)
    shaft_inner_radius = (middle_radius - (0.5 * shaft_height))
    shaft_outer_radius = (middle_radius + (0.5 * shaft_height))
    headangle_delta = max(0.0, min(((abs(boxheight) * head_length_ratio) / middle_radius), abs(angle)))
    if (angle < 0):
        headangle_delta *= (- 1)
    if (orientation == 'right'):
        headangle = (endangle - headangle_delta)
    else:
        headangle = (startangle + headangle_delta)
    if (startangle <= endangle):
        headangle = max(min(headangle, endangle), startangle)
    else:
        headangle = max(min(headangle, startangle), endangle)
    assert ((startangle <= headangle <= endangle) or (endangle <= headangle <= startangle)), (startangle, headangle, endangle, angle)
    (startcos, startsin) = (cos(startangle), sin(startangle))
    (headcos, headsin) = (cos(headangle), sin(headangle))
    (endcos, endsin) = (cos(endangle), sin(endangle))
    (x0, y0) = (self.xcenter, self.ycenter)
    if ((0.5 >= abs(angle)) and (abs(headangle_delta) >= abs(angle))):
        if (orientation == 'right'):
            (x1, y1) = ((x0 + (inner_radius * startsin)), (y0 + (inner_radius * startcos)))
            (x2, y2) = ((x0 + (outer_radius * startsin)), (y0 + (outer_radius * startcos)))
            (x3, y3) = ((x0 + (middle_radius * endsin)), (y0 + (middle_radius * endcos)))
        else:
            (x1, y1) = ((x0 + (inner_radius * endsin)), (y0 + (inner_radius * endcos)))
            (x2, y2) = ((x0 + (outer_radius * endsin)), (y0 + (outer_radius * endcos)))
            (x3, y3) = ((x0 + (middle_radius * startsin)), (y0 + (middle_radius * startcos)))
        return Polygon([x1, y1, x2, y2, x3, y3], strokeColor=(border or color), fillColor=color, strokeLineJoin=1, strokewidth=0)
    elif (orientation == 'right'):
        p = ArcPath(strokeColor=strokecolor, fillColor=color, strokeLineJoin=1, strokewidth=0, **kwargs)
        p.addArc(self.xcenter, self.ycenter, shaft_inner_radius, (90 - ((headangle * 180) / pi)), (90 - ((startangle * 180) / pi)), moveTo=True)
        p.addArc(self.xcenter, self.ycenter, shaft_outer_radius, (90 - ((headangle * 180) / pi)), (90 - ((startangle * 180) / pi)), reverse=True)
        p.lineTo((x0 + (outer_radius * headsin)), (y0 + (outer_radius * headcos)))
        if (abs(angle) < 0.5):
            p.lineTo((x0 + (middle_radius * endsin)), (y0 + (middle_radius * endcos)))
            p.lineTo((x0 + (inner_radius * headsin)), (y0 + (inner_radius * headcos)))
        else:
            dx = min(0.1, (abs(angle) / 50.0))
            x = dx
            while (x < 1):
                r = (outer_radius - (x * (outer_radius - middle_radius)))
                a = (headangle + (x * (endangle - headangle)))
                p.lineTo((x0 + (r * sin(a))), (y0 + (r * cos(a))))
                x += dx
            p.lineTo((x0 + (middle_radius * endsin)), (y0 + (middle_radius * endcos)))
            x = dx
            while (x < 1):
                r = (middle_radius - (x * (middle_radius - inner_radius)))
                a = (headangle + ((1 - x) * (endangle - headangle)))
                p.lineTo((x0 + (r * sin(a))), (y0 + (r * cos(a))))
                x += dx
            p.lineTo((x0 + (inner_radius * headsin)), (y0 + (inner_radius * headcos)))
        p.closePath()
        return p
    else:
        p = ArcPath(strokeColor=strokecolor, fillColor=color, strokeLineJoin=1, strokewidth=0, **kwargs)
        p.addArc(self.xcenter, self.ycenter, shaft_inner_radius, (90 - ((endangle * 180) / pi)), (90 - ((headangle * 180) / pi)), moveTo=True, reverse=True)
        p.addArc(self.xcenter, self.ycenter, shaft_outer_radius, (90 - ((endangle * 180) / pi)), (90 - ((headangle * 180) / pi)), reverse=False)
        p.lineTo((x0 + (outer_radius * headsin)), (y0 + (outer_radius * headcos)))
        if (abs(angle) < 0.5):
            p.lineTo((x0 + (middle_radius * startsin)), (y0 + (middle_radius * startcos)))
            p.lineTo((x0 + (inner_radius * headsin)), (y0 + (inner_radius * headcos)))
        else:
            dx = min(0.1, (abs(angle) / 50.0))
            x = dx
            while (x < 1):
                r = (outer_radius - (x * (outer_radius - middle_radius)))
                a = (headangle + (x * (startangle - headangle)))
                p.lineTo((x0 + (r * sin(a))), (y0 + (r * cos(a))))
                x += dx
            p.lineTo((x0 + (middle_radius * startsin)), (y0 + (middle_radius * startcos)))
            x = dx
            while (x < 1):
                r = (middle_radius - (x * (middle_radius - inner_radius)))
                a = (headangle + ((1 - x) * (startangle - headangle)))
                p.lineTo((x0 + (r * sin(a))), (y0 + (r * cos(a))))
                x += dx
            p.lineTo((x0 + (inner_radius * headsin)), (y0 + (inner_radius * headcos)))
        p.closePath()
        return p