sclass ManyCirclePainter { int w, h; new L circles; int[] pixels; L[] startCircle, stopCircle; srecord Circle(Pt center, int radius) {} run { pixels = new int[w*h]; if (pixels.length == 0) ret; int nCircles = l(circles); startCircle = new L[h]; stopCircle = new L[h]; for (circle : circles) { int y1 = max(0, circle.center.y-circle.radius); int y2 = circle.center.y+circle.radius+1; if (y1 >= y2) continue; startCircle[y1] = addOrCreate(startCircle[y1], circle); if (y2 < h) stopCircle[y2] = addOrCreate(stopCircle[y2], circle); } int[] startStop = new[w]; new Set liveCircles; int iPixel = 0; for y to h: { fillArray(startStop, 0); addAll(liveCircles, startCircle[y]); removeAll(liveCircles, stopCircle[y]); for (c : liveCircles) { // width of circle at this line int width = iround(sqrt(sqr(c.radius)-sqr(y-c.center.y))); int x1 = c.center.x-width, x2 = c.center.x+width+1; if (x1 > w || x2 <= 0) continue; // not visible at all at this row startStop[max(x1, 0)]++; if (x2 < w) startStop[x2]--; } int count = 0; for x to w: { count += startStop[x]; pixels[iPixel++] = countToColor(count, nCircles); } } } int countToColor(int count, int nCircles) { ret rgbIntFromBrightness(count/16.0); } }