#概要
こちらはC++ (DXライブラリ)を使って、ボロノイ図を作成する記事です。
以前、記事を書いた"~水彩ボロノイ図を線画~"とは違うアルゴリズムを使用しています。
DXライブラリはこちらからダウンロードできます。
何か不備がありましたら指摘していただければ幸いです。
#コード
1/12秒おきにボロノイ図が自動分割生成されるプログラムです。
このコードでは、最大で100個まで分割します。
Main.cpp
#define NOMINMAX
#include "DxLib.h"
#include <vector>
#include <chrono>
//横画面サイズ
#define MAP_X 512
//縦画面サイズ
#define MAP_Y 512
//原点の最大個数
#define VORONOI_COUNT_MAX 1
struct Point {
int x, y;
};
static int DistanceSqrd(const Point& point, int x, int y) {
int xd = x - point.x;
int yd = y - point.y;
return (xd * xd) + (yd * yd);
}
class Voronoi {
public:
//ボロノイ図を作る
void Make(int count) {
CreatePointColor(count);
CreateSites();
SetSitesPoints();
}
private:
std::vector<Point> points_;
std::vector<unsigned int> colors_;
//原点の場所と色を決定する
void CreatePointColor(int count) {
const int w = MAP_X - 20, h = MAP_Y - 20;
unsigned int c;
for (int i = 0; i < count; i++) {
points_.push_back({ GetRand(w) + 10, GetRand(h) + 10 });
c = GetColor(GetRand(100) + 150, GetRand(100) + 150, GetRand(100) + 150);
colors_.push_back(c);
}
}
//図形を線画
void CreateSites() {
int w = MAP_X, h = MAP_Y, d, ind, dist;
for (int hh = 0; hh < h; hh++) {
for (int ww = 0; ww < w; ww++) {
ind = -1;
dist = std::numeric_limits<int>::max();
for (int it = 0; it < points_.size(); it++) {
const Point& p = points_[it];
d = DistanceSqrd(p, ww, hh);
if (d < dist) {
dist = d;
ind = it;
}
}
if (ind > -1) DrawPixel(ww, hh, colors_[ind]);
}
}
}
//原点を線画
void SetSitesPoints() {
for (const auto& point : points_) {
int x = point.x, y = point.y;
for (int i = -1; i < 2; i++)
for (int j = -1; j < 2; j++)
DrawPixel(x + i, y + j, GetColor(0, 0, 0));
}
}
};
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
//log出力停止・ウィンドウモード変更・初期化・裏画面設定
SetOutApplicationLogValidFlag(FALSE), ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK);
//画面サイズの決定
SetGraphMode(MAP_X, MAP_Y, 32);
//タイトル文字
SetMainWindowText("Voronoi");
//ボロノイ図を線画
Voronoi diagram;
//時間
int time = 0;
int voronoiCount = 0;
//ボロノイ図を生成
diagram.Make(1 + GetRand(VORONOI_COUNT_MAX - 1));
while (ScreenFlip() == 0 && ProcessMessage() == 0) {
//1/12秒おきにボロノイ図を生成
if (time == 5 && voronoiCount < 100) {
diagram.Make(1 + GetRand(VORONOI_COUNT_MAX - 1));
time = 0;
voronoiCount++;
}
//ESCキーで終了
if (CheckHitKey(KEY_INPUT_ESCAPE)) break;
//時間を増やす
time++;
}
//DXライブラリの終了処理
DxLib_End();
return 0;
}
アニメーションしてみたらこんな感じ
##ソースコードのライセンス
These codes are licensed under CC0.
ソースコードは自由に使用してください。
#参考
DXライブラリ 関数リファレンスページ
新・C言語 ~ゲームプログラミングの館
ボロノイ図
ボロノイ図を作る
ボロノイ図とその3つの性質
ボロノイ分割とは?
GPUでボロノイ図を描画する
ボロノイ図の描画アルゴリズムについて
Voronoi diagram
vector