// start from center static LongIterator pixelSpiral_longIterator(int w, int h) { ret pixelSpiral_longIterator(w/2, h/2, w, h); } // thanks to https://stackoverflow.com/questions/398299/looping-in-a-spiral // firstIntFromLong(l) = x, secondIntFromLong(l) = y static LongIterator pixelSpiral_longIterator(int sx, int sy, int imageWidth, int imageHeight, int maxPixels default Int.MAX_VALUE) { ret new LongIterator { int x, y, dx, dy = -1; int maxPixels2 = min(maxPixels, sqr(max4(sx+1, imageWidth-sx, sy+1, imageHeight-sy)*2)); int i; long pixel; bool done; void fetch { while (i++ < maxPixels2) { int px = sx+x, py = sy+y; if ((x == y) || ((x < 0) && (x == -y)) || ((x > 0) && (x == 1-y))) { int t=dx; dx=-dy; dy=t; } x += dx; y += dy; if (px >= 0 && py >= 0 && px < imageWidth && py < imageHeight) ret with pixel = twoIntsToLong(px, py); } set done; } { fetch(); } public bool hasNext() { ret !done; } public long next() { long p = pixel; fetch(); ret p; } }; }