Returns a generator that produces the (x, y) tuples for the outline of a circle.

    `x` and `y` are the center of the circle, `radius` is the size.

    (Note: The `filled` and `thickness` parameter is not yet implemented.)

    >>> list(circle(0, 0, 7))
    [(-6, 3), (0, 7), (4, -6), (-7, 0), (7, -1), (7, -2), (2, -7), (5, -5), (-5, 5), (-1, -7), (-2, -7), (-4, 6), (7, 2), (5, 5), (-5, -5), (6, -4), (6, 3), (-6, 4), (3, 6), (-3, 6), (6, 4), (1, -7), (6, -3), (7, 1), (-6, -4), (-7, 2), (-4, -6), (-2, 7), (-1, 7), (2, 7), (7, 0), (-7, -1), (-7, -2), (4, 6), (0, -7), (-6, -3), (-7, 1), (1, 7), (3, -6), (-3, -6)]
    >>> drawPoints(circle(0, 0, 7))
    ,,,,,OOOOO,,,,,
    ,,,OO,,,,,OO,,,
    ,,O,,,,,,,,,O,,
    ,O,,,,,,,,,,,O,
    ,O,,,,,,,,,,,O,
    O,,,,,,,,,,,,,O
    O,,,,,,,,,,,,,O
    O,,,,,,,,,,,,,O
    O,,,,,,,,,,,,,O
    O,,,,,,,,,,,,,O
    ,O,,,,,,,,,,,O,
    ,O,,,,,,,,,,,O,
    ,,O,,,,,,,,,O,,
    ,,,OO,,,,,OO,,,
    ,,,,,OOOOO,,,,,

def circle(x, y, radius, filled=False, thickness=1):
    """
    Returns a generator that produces the (x, y) tuples for the outline of a circle.

    `x` and `y` are the center of the circle, `radius` is the size.

    (Note: The `filled` and `thickness` parameter is not yet implemented.)

    >>> list(circle(0, 0, 7))
    [(-6, 3), (0, 7), (4, -6), (-7, 0), (7, -1), (7, -2), (2, -7), (5, -5), (-5, 5), (-1, -7), (-2, -7), (-4, 6), (7, 2), (5, 5), (-5, -5), (6, -4), (6, 3), (-6, 4), (3, 6), (-3, 6), (6, 4), (1, -7), (6, -3), (7, 1), (-6, -4), (-7, 2), (-4, -6), (-2, 7), (-1, 7), (2, 7), (7, 0), (-7, -1), (-7, -2), (4, 6), (0, -7), (-6, -3), (-7, 1), (1, 7), (3, -6), (-3, -6)]
    >>> drawPoints(circle(0, 0, 7))
    ,,,,,OOOOO,,,,,
    ,,,OO,,,,,OO,,,
    ,,O,,,,,,,,,O,,
    ,O,,,,,,,,,,,O,
    ,O,,,,,,,,,,,O,
    O,,,,,,,,,,,,,O
    O,,,,,,,,,,,,,O
    O,,,,,,,,,,,,,O
    O,,,,,,,,,,,,,O
    O,,,,,,,,,,,,,O
    ,O,,,,,,,,,,,O,
    ,O,,,,,,,,,,,O,
    ,,O,,,,,,,,,O,,
    ,,,OO,,,,,OO,,,
    ,,,,,OOOOO,,,,,
    """
    # Mid-point/Bresenham's Circle algorithm from https://www.daniweb.com/programming/software-development/threads/321181/python-bresenham-circle-arc-algorithm
    # and then modified to remove duplicates.

    # The order that the xy points are returned is rather unconventional due to the optimizations in the code, it is not a simple clockwise/counterclockwise sweep.
    if filled or thickness != 1:
        raise NotImplementedError('The pybresenham module is under development and the filled, thickness, and endcap parameters are not implemented. You can contribute at https://github.com/asweigart/pybresenham')

    switch = 3 - (2 * radius)
    cx = 0
    cy = radius
    """
    # NOTE - This code leaves a point missing from the final circle on the left side. Until I can figure it out, I'm usin the old algorithm, which unforuntately defeats the purpose of having a generator.
    # 1st quarter/octant starts clockwise at 12 o'clock
    while cx <= cy:
        # Duplicates are formed whenever cx or cy is 0, or when cx == cy.
        # I've rearranged the original code to minimize if statements,
        # though it makes the code a bit inscrutable.
        yield ( cx + x, -cy + y) # 1st quarter 1st octant
        if cx != cy:
            yield ( cy + x, -cx + y) # 1st quarter 2nd octant
        if cx != 0:
            yield ( cy + x,  cx + y) # 2nd quarter 3rd octant
            if cy != 0:
                yield (-cx + x,  cy + y) # 3rd quarter 5th octant
                yield (-cy + x, -cx + y) # 4th quarter 7th octant
                if cx != cy:
                    yield (-cy + x,  cx + y) # 3rd quarter 6th octant
                    yield (-cx + x, -cy + y) # 4th quarter 8th octant
        if cy != 0 and cx != cy:
            yield ( cx + x,  cy + y) # 2nd quarter 4th octant

        if switch < 0:
            switch += (4 * cx) + 6
        else:
            switch += (4 * (cx - cy)) + 10
            cy -= 1
        cx += 1
    """
    points = set()
    while cx <= cy:
        # first quarter first octant
        points.add((cx + x,-cy + y))
        # first quarter 2nd octant
        points.add((cy + x,-cx + y))
        # second quarter 3rd octant
        points.add((cy + x,cx + y))
        # second quarter 4.octant
        points.add((cx + x,cy + y))
        # third quarter 5.octant
        points.add((-cx + x,cy + y))
        # third quarter 6.octant
        points.add((-cy + x,cx + y))
        # fourth quarter 7.octant
        points.add((-cy + x,-cx + y))
        # fourth quarter 8.octant
        points.add((-cx + x,-cy + y))
        if switch < 0:
            switch = switch + (4 * cx) + 6
        else:
            switch = switch + (4 * (cx - cy)) + 10
            cy = cy - 1
        cx = cx + 1
    return iter(points)