def circlescan(x0, y0, r1, r2):
    if r1 < 0: raise ValueError("Initial radius must be non-negative")
    if r2 < 0: raise ValueError("Final radius must be non-negative")
    previous = []
    rstep = 1 if r2 >= r1 else -1
    for distance in range(r1, r2 + rstep, rstep):
        if distance == 0:
            yield x0, y0
        else:
            a = 0.707107
            rotations = {0: [[ 1, 0], [ 0, 1]],
                         1: [[ a, a], [-a, a]],
                         2: [[ 0, 1], [-1, 0]],
                         3: [[-a, a], [-a,-a]],
                         4: [[-1, 0], [ 0,-1]],
                         5: [[-a,-a], [ a,-a]],
                         6: [[ 0,-1], [ 1, 0]],
                         7: [[ a,-a], [ a, a]]}
            nangles = len(rotations)
            current = []
            for angle in range(nangles):
                x = 0
                y = distance
                d = 1 - distance
                while x < y:
                    xr = rotations[angle][0][0]*x + rotations[angle][0][1]*y
                    yr = rotations[angle][1][0]*x + rotations[angle][1][1]*y
                    xr = x0 + xr
                    yr = y0 + yr
                    point = (int(round(xr)), int(round(yr)))
                    if point not in previous:
                        yield xr, yr
                        current.append(point)
                    if (d < 0):
                        d += 3 + 2 * x
                    else:
                        d += 5 - 2 * (y-x)
                        y -= 1
                    x += 1
            previous = current