円の一部(半円など)を塗る処理
Javaのグラフィックコマンドには、円(drawOval)や円塗り(fillOval)が
ありますが、drawOval(int x, int y, int width, int height);と
矩形の様な座標指定です(内接する円/楕円が描画されます)。
毎度、管理人イガジーです。
中心(x,y)と半径(r)を指定して描画したい時は
void drawCircle(int x, int y, int r) {
g.fillOval(x-r, y-r, r*2, r*2);
}
というメソッドを使うと良いでしょう。
それはともかく、半円塗りや月の形塗りなど、
円の一部を塗る場合は自前で描画することになります。
半円を塗る場合は、例えば次のようなコードになるでしょう。
int r=120;
int x0=140; int y0=140;
for (int y=-r;y<=0;++y) {
int x2;
// x2=(int)Math.sqrt(r*r-y*y);
double ac=Math.acos((double)y/(double)r);
x2=(int)((double)r*Math.sin(ac)); // 円周
g.setColor(Color.YELLOW);
g.drawLine(x0, y0+y, x0+x2, y0+y);
g.drawLine(x0, y0-y, x0+x2, y0-y);
g.setColor(Color.DARK_GRAY);
g.drawLine(x0-x2, y0+y, x0-1, y0+y);
g.drawLine(x0-x2, y0-y, x0-1, y0-y);
}
ここで、(x0,y0)は、円の中心の座標です。
円周を表す数式は、x*x+y*y=r*r ですから
yを指定した時のxは、x=±sqr(r*r-y*y) で求められます。
あるいは、x=r*cos(α), y=r*sin(α) でもあるので
x=r*Math.sin(acos(y/r)); でも求められます。
どちらの式で計算しても結果は同じです。
半円を塗る場合は、中心線(x=0) から円周に向かって
線を引けば良いわけです。
三角関数など、doubleの演算回数は少ない方が良いので
y0+y の時の x座標(x2)を使って
y0-y の時の描画も行なってしまうのが効率的です。
同様に、必要なら x0+x2 と同時に x0-x2(反対側)の
塗り処理も行なってしまうのがよいでしょう。
月の形を描画する場合は
double age=4.8; // 月齢
double theta=Math.PI*age/14.765;
for (int y=-r;y<=0;++y) {
int x2,x1;
// x2=(int)Math.sqrt(r*r-y*y);
double ac=Math.acos((double)y/(double)r);
x2=(int)((double)r*Math.sin(ac)); // 円周
x1=(int)((double)r*Math.cos(theta)*Math.sin(ac)); // 月の形
if ((age>1.0)&&(age<29.0)) {
if (age<15.0) {
g.setColor(Color.YELLOW);
g.drawLine(x0+x1, y0+y, x0+x2, y0+y);
g.drawLine(x0+x1, y0-y, x0+x2, y0-y);
g.setColor(Color.DARK_GRAY);
g.drawLine(x0-x2, y0+y, x0+x1-1, y0+y);
g.drawLine(x0-x2, y0-y, x0+x1-1, y0-y);
}else{
g.setColor(Color.YELLOW);
g.drawLine(x0-x2, y0+y, x0-x1, y0+y);
g.drawLine(x0-x2, y0-y, x0-x1, y0-y);
g.setColor(Color.DARK_GRAY);
g.drawLine(x0-x1-1, y0+y, x0+x2, y0+y);
g.drawLine(x0-x1-1, y0-y, x0+x2, y0-y);
}
}else{
g.setColor(Color.DARK_GRAY);
g.drawLine(x0-x2, y0+y, x0+x2, y0+y);
g.drawLine(x0-x2, y0-y, x0+x2, y0-y);
}
}
という感じになるでしょう。
ここで、ageは月齢です。値を色々変えて試してみてください。
月齢1.0以下、および29.0以上は新月扱い(黄色い部分無し)
にしています。
これでそれっぽい月の形が描画できると思います。
この記事へのコメントはこちら