javaで書いたサンプルコードです。 実行ディレクトリに「CircleRenderTest.png」という画像ファイルを出力します。 フレームは使っていません。
// CircleRenderTest.java import java.io.File; import javax.imageio.ImageIO; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; public class CircleRenderTest { public static final int IMAGE_SIZE = 420; public static final String FILE_NAME = "CircleRenderTest.png"; public static final int ALPHA_MAX = 255; public static final int RADIUS_MAX = 200; private int [][] _D; private BufferedImage _img; public void initD() { _D = new int[RADIUS_MAX + 1][]; _D[0] = new int[1]; _D[0][0] = 0; for(int r = 1; r <= RADIUS_MAX; r++) { int y_max = (int)(Math.ceil( (double)r / Math.sqrt(2.0) ) ); _D[r] = new int[y_max + 1]; for(int y = 0; y <= y_max; y++) { double x = Math.sqrt(r * r - y * y); _D[r][y] = (int)(ALPHA_MAX * (Math.ceil(x) - x) ); } } } public void drawCircle(int cx, int cy, int r, int color) { int[] Dr = _D[r]; int x = r; int y = 0; int d = 0; int d_old = 0; // 軸上の点は4wayでいいんだけど、手抜き setPixel8way(cx, cy, x, y, color, ALPHA_MAX); while(y < x - 1) // 内側のピクセルと45度の線を比べる { y++; d = Dr[y]; if(d < d_old) { x--; } setPixel8way(cx, cy, x , y, color, ALPHA_MAX - d); // 外側のピクセル setPixel8way(cx, cy, x - 1, y, color, d); // 内側のピクセル d_old = d; } } public void setPixel8way(int cx, int cy, int x, int y, int color, int alpha) { int rgba = alpha << 24 | color; _img.setRGB(cx + x, cy + y, rgba); _img.setRGB(cx + x, cy - y, rgba); _img.setRGB(cx - x, cy + y, rgba); _img.setRGB(cx - x, cy - y, rgba); _img.setRGB(cx + y, cy + x, rgba); _img.setRGB(cx + y, cy - x, rgba); _img.setRGB(cx - y, cy + x, rgba); _img.setRGB(cx - y, cy - x, rgba); } public void run() { _img = new BufferedImage(IMAGE_SIZE, IMAGE_SIZE, BufferedImage.TYPE_INT_ARGB); Graphics g = _img.createGraphics(); initD(); int color = 0; for(int r = 0; r <= RADIUS_MAX; r += 10) { drawCircle( IMAGE_SIZE / 2, IMAGE_SIZE / 2, r, calcColor(color++) ); } try { ImageIO.write(_img, "png", new File(FILE_NAME) ); } catch(Exception exc) { exc.printStackTrace(); } } public int calcColor(int r) { int rgb = (r % 6) + 1; return ( (rgb & 0x4) > 0 ? 0xff0000 : 0) | ( (rgb & 0x2) > 0 ? 0x00ff00 : 0) | ( (rgb & 0x1) > 0 ? 0x0000ff : 0); } public static void main(String[] args) { CircleRenderTest thisApp = new CircleRenderTest(); thisApp.run(); } }
実行結果はこんな感じ。
実行結果の画像を保存してペイントソフトなどで拡大すると、アンチエイリアスがかかっているのが確認できます。 ただし、WindowsXPのMSペイントはアルファ値に対応していないらしく、アンチエイリアスが確認できません。 (以降のMSペイントはどうなんでしょう?) 適当なペイントソフトを用意して見てください。
サンプルコードはコピー&ペースト可です。 しかし、いくつか注意点があります。
コピー&ペーストしてコーディングする場合は、↑の項目を各自で改良して使ってください。 それと、次の項目に書いた課題も参照。