概要
不思議のダンジョンなローグライクゲームを製作中、円形のマップ欲しいな~と思い、二次元配列に円を描くアルゴリズムが無いか探してみた。
無事発見し、きれいな円を描くことに成功した。
参考サイト
具体的な方法
準備
まずは、円を描くために適当な二次元配列を用意。今回は、0をデフォの値、1を円にしたいところ、とした。
(初期値は一旦0で埋めておく)
const int size = 30;
int area[size][size];
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
area[y][x] = 0;
}
}
次に、描きたい円の半径と中心点を決める。
今回はテストコードなので、適当に決める。
// 半径r
int r = 10;
// 中心点
int x0 = size / 2;
int y0 = size / 2;
外周の円を描く
次に、参考サイト1つ目と2つ目にあるように、外周を描いていく。
正直クソコード感が否めない。
void set_dot(int _x, int _y)
{
area[_x][_y] = 1;
}
int x = r;
int y = 0;
int F = -2 * r + 3;
while (x >= y)
{
set_dot(x0 + x, y0 + y);
set_dot(x0 - x, y0 + y);
set_dot(x0 + x, y0 - y);
set_dot(x0 - x, y0 - y);
set_dot(x0 + y, y0 + x);
set_dot(x0 - y, y0 + x);
set_dot(x0 + y, y0 - x);
set_dot(x0 - y, y0 - x);
if (F >= 0) {
x--;
F -= 4 * x;
}
y++;
F += 4 * y + 2;
}
これで円形の完成。
でも今回は、ローグライクのダンジョンマップ用の円なので、円の内側も埋めていく。
円の内側を埋める
この作業に関しては、area[y][x]が円形の内側にあるかどうかを判定すればいいため、円の方程式を利用する。(参考サイト3)
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
// 判定用
int lx = (x - x0) * (x - x0);
int ly = (y - y0) * (y - y0);
int lr = r * r;
if (lx + ly < lr)
{
area[y][x] = 1;
}
}
}