Returns a generator that produces the (x, y) points of the vertices of a regular polygon.
    `x` and `y` mark the center of the polygon, `radius` indicates the size,
    `sides` specifies what kind of polygon it is.

    Odd-sided polygons have a pointed corner at the top and flat horizontal
    side at the bottom. The `rotationDegrees` argument will rotate the polygon
    counterclockwise.

    The polygon can be stretched by passing `stretchHorizontal` or `stretchVertical`
    arguments. Passing `2.0` for `stretchHorizontal`, for example, will double with
    width of the polygon.

    If `filled` is set to `True`, the generator will also produce the interior
    (x, y) points.

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

    >>> list(polygonVertices(10, 10, 8, 5))
    [(10, 2.0), (3, 8.0), (6, 16.0), (14, 16.0), (17, 8.0)]
    >>> drawPoints(polygonVertices(10, 10, 8, 5))
    ,,,,,,,O,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    O,,,,,,,,,,,,,O
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,O,,,,,,,O,,,
    >>> drawPoints(polygonVertices(10, 10, 8, 5, rotationDegrees=20))
    ,,,,,O,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,O
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    O,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,O
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,O,,,,,,,,

def polygonVertices(x, y, radius, sides, rotationDegrees=0, stretchHorizontal=1.0, stretchVertical=1.0):
    """
    Returns a generator that produces the (x, y) points of the vertices of a regular polygon.
    `x` and `y` mark the center of the polygon, `radius` indicates the size,
    `sides` specifies what kind of polygon it is.

    Odd-sided polygons have a pointed corner at the top and flat horizontal
    side at the bottom. The `rotationDegrees` argument will rotate the polygon
    counterclockwise.

    The polygon can be stretched by passing `stretchHorizontal` or `stretchVertical`
    arguments. Passing `2.0` for `stretchHorizontal`, for example, will double with
    width of the polygon.

    If `filled` is set to `True`, the generator will also produce the interior
    (x, y) points.

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

    >>> list(polygonVertices(10, 10, 8, 5))
    [(10, 2.0), (3, 8.0), (6, 16.0), (14, 16.0), (17, 8.0)]
    >>> drawPoints(polygonVertices(10, 10, 8, 5))
    ,,,,,,,O,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    O,,,,,,,,,,,,,O
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,,
    ,,,O,,,,,,,O,,,
    >>> drawPoints(polygonVertices(10, 10, 8, 5, rotationDegrees=20))
    ,,,,,O,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,O
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    O,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,O
    ,,,,,,,,,,,,,,
    ,,,,,,,,,,,,,,
    ,,,,,O,,,,,,,,
    """

    # TODO - validate x, y, radius, sides

    # Setting the start point like this guarantees a flat side will be on the "bottom" of the polygon.
    if sides % 2 == 1:
        angleOfStartPointDegrees = 90 + rotationDegrees
    else:
        angleOfStartPointDegrees = 90 + rotationDegrees - (180 / sides)

    for sideNum in range(sides):
        angleOfPointRadians = math.radians(angleOfStartPointDegrees + (360 / sides * sideNum))

        yield (  int(math.cos(angleOfPointRadians) * radius  * stretchHorizontal) + x,
               -(int(math.sin(angleOfPointRadians) * radius) * stretchVertical)   + y)