Le diagramme de Voronoi
A propos du code
Définition
Algorithme facile
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define NB_POINTS 20
struct SPoint
{
int x, y;
Color col;
};
int main(int argc, char* argv[])
{
SPoint points[NB_POINTS];
float radius = 1.0;
// init the window
gfx.init("Voronoi", SCREEN_WIDTH, SCREEN_HEIGHT);
gfx.init2D();
gfx.clearScreen(Color(0, 0, 0, SDL_ALPHA_OPAQUE));
// init the points
srand(time(NULL));
for (int i = 0; i < NB_POINTS; ++i)
{
points[i].x = rand() % SCREEN_WIDTH;
points[i].y = rand() % SCREEN_HEIGHT;
points[i].col = Color((rand() % 128) + 128,
(rand() % 128) + 128,
(rand() % 128) + 128);
}
Ensuite, pour chaque point on va dessiner le cercle. Si vous ne comprenez pas les formules utilisées pour tracer le
while (sys.isQuitRequested() == false)
{
sys.processEvents();
// drawing
for (int i = 0; i < NB_POINTS; ++i)
{
// draw circles
for (float a = 0.0; a < 2.0 * M_PI; a += M_PI / 1500.0)
{
int x = points[i].x + (int)(radius * cos(a));
int y = points[i].y + (int)(radius * sin(a));
// if pixel is not out of screen
if (x >= 0 && x < SCREEN_WIDTH &&
y >= 0 && y < SCREEN_HEIGHT)
{
// if pixel is empty
if (gfx.getPixel(x, y).argb == Color(0, 0, 0, SDL_ALPHA_OPAQUE).argb)
gfx.setPixel(x, y, points[i].col);
}
}
Enfin on va dessiner les points au dessus des cercles, augmenter le rayon et reboucler.
// draw points
gfx.setPixel(points[i].x , points[i].y , Color(1, 1, 1, SDL_ALPHA_OPAQUE));
gfx.setPixel(points[i].x , points[i].y - 1, Color(1, 1, 1, SDL_ALPHA_OPAQUE));
gfx.setPixel(points[i].x , points[i].y + 1, Color(1, 1, 1, SDL_ALPHA_OPAQUE));
gfx.setPixel(points[i].x - 1, points[i].y , Color(1, 1, 1, SDL_ALPHA_OPAQUE));
gfx.setPixel(points[i].x + 1, points[i].y , Color(1, 1, 1, SDL_ALPHA_OPAQUE));
}
// increase radius
radius += 1.0;
gfx.render();
sys.wait(50);
}
Télécharger le code source
Télécharger l'exécutable pour Windows
Le résultat ressemble à l'image qu'on a vu auparavant.
Réfléchir d'une autre façon
for (int y = 0; y < SCREEN_HEIGHT; ++y)
for (int x = 0; x < SCREEN_WIDTH; ++x)
{
Maintenant, si on suit le définition qu'on a donnée au début, ce pixel est à l'intérieur de la cellule d'un germe.
int nearest = 0;
Sint32 nearestDist = 1000000000;
for (int i = 0; i < NB_POINTS; ++i)
{
Sint32 dx = points[i].x - x;
Sint32 dy = points[i].y - y;
Sint32 dist = dx * dx + dy * dy;
if (dist < nearestDist)
{
nearest = i;
nearestDist = dist;
}
}
Maintenant il suffit de dessiner le pixel avec la couleur du point le plus proche.
if (sqrt(nearestDist) <= radius)
gfx.setPixel(x, y, points[nearest].col);
Télécharger le code source
Télécharger l'exécutable pour Windows
Avec ce programme, maintenant les lignes sont parfaitement droites.