Cercles pleins
A propos du code
Remplir le cercle
void circle(int centerX, int centerY, int radius, Color c)
{
int x = 0;
int y = radius;
int m = 5 - 4 * radius;
while (x <= y)
{
gfx.line(centerX - x, centerY - y, centerX + x, centerY - y, c);
gfx.line(centerX - y, centerY - x, centerX + y, centerY - x, c);
gfx.line(centerX - y, centerY + x, centerX + y, centerY + x, c);
gfx.line(centerX - x, centerY + y, centerX + x, centerY + y, c);
if (m > 0)
{
y--;
m -= 8 * y;
}
x++;
m += 8 * x + 4;
}
}
Et comme dans l'article précédent, on va chronométrer le dessin de 10000 cercles:
// time 10000 circles
sys.StartPerfCounter();
for (int i = 0; i < 10000; i++)
circle(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 150, Color(255, 255, 255));
printf("%f\n", sys.StopPerfCounter());
Télécharger le code source
Télécharger l'exécutable pour Windows
Ce code prend environ 480 ms sur mon ordinateur.
Eviter de sur-dessiner
while (x <= y)
{
gfx.line(centerX - y, centerY - x, centerX + y, centerY - x, c);
gfx.line(centerX - y, centerY + x, centerX + y, centerY + x, c);
if (m > 0)
{
gfx.line(centerX - x, centerY - y, centerX + x, centerY - y, c);
gfx.line(centerX - x, centerY + y, centerX + x, centerY + y, c);
y--;
m -= 8 * y;
}
x++;
m += 8 * x + 4;
}
Télécharger le code source
Télécharger l'exécutable pour Windows
Ce code prend environ 435 ms.
Utiliser des rectangles
while (x <= y)
{
gfx.rectFill(centerX - y, centerY - x, centerX + y + 1, centerY - x + 1, c);
gfx.rectFill(centerX - y, centerY + x, centerX + y + 1, centerY + x + 1, c);
if (m > 0)
{
gfx.rectFill(centerX - x, centerY - y, centerX + x + 1, centerY - y + 1, c);
gfx.rectFill(centerX - x, centerY + y, centerX + x + 1, centerY + y + 1, c);
y--;
m -= 8 * y;
}
Télécharger le code source
Télécharger l'exécutable pour Windows
Ce code est un peu plus rapide. Il prend environ 410 ms.
Utiliser des boucles simples
while (x <= y)
{
for (int xx = centerX - y; xx <= centerX + y; xx++)
gfx.setPixel(xx, centerY - x, c);
for (int xx = centerX - y; xx <= centerX + y; xx++)
gfx.setPixel(xx, centerY + x, c);
if (m > 0)
{
for (int xx = centerX - x; xx <= centerX + x; xx++)
gfx.setPixel(xx, centerY - y, c);
for (int xx = centerX - x; xx <= centerX + x; xx++)
gfx.setPixel(xx, centerY + y, c);
y--;
m -= 8 * y;
}
Télécharger le code source
Télécharger l'exécutable pour Windows
Encore une fois, c'est un peu plus rapide. Cette version tourne en à peu près 400 ms.
Réduire les boucles
while (x <= y)
{
for (int xx = centerX - y; xx <= centerX + y; xx++)
{
gfx.setPixel(xx, centerY - x, c);
gfx.setPixel(xx, centerY + x, c);
}
if (m > 0)
{
for (int xx = centerX - x; xx <= centerX + x; xx++)
{
gfx.setPixel(xx, centerY - y, c);
gfx.setPixel(xx, centerY + y, c);
}
y--;
m -= 8 * y;
}
Télécharger le code source
Télécharger l'exécutable pour Windows
Cette version prend entre 360 et 370 ms.
Utiliser des index
inline void setPixel(int pos, Color c)
{
mPixels2D[pos] = c;
}
Et notre boucle de dessin va maintenant devenir:
while (x <= y)
{
int pos1 = gfx.pixelPos2D(centerX - y, centerY - x);
int pos2 = gfx.pixelPos2D(centerX - y, centerY + x);
for (int xx = centerX - y; xx <= centerX + y; xx++)
{
gfx.setPixel(pos1++, c);
gfx.setPixel(pos2++, c);
}
if (m > 0)
{
int pos1 = gfx.pixelPos2D(centerX - x, centerY - y);
int pos2 = gfx.pixelPos2D(centerX - x, centerY + y);
for (int xx = centerX - x; xx <= centerX + x; xx++)
{
gfx.setPixel(pos1++, c);
gfx.setPixel(pos2++, c);
}
y--;
m -= 8 * y;
}
Télécharger le code source
Télécharger l'exécutable pour Windows
Cette version est juste un peu plus rapide, elle prend entre 350 et 360 ms.
Séparer les boucles
while (x <= y)
{
int pos = gfx.pixelPos2D(centerX - y, centerY - x);
for (int xx = centerX - y; xx <= centerX + y; xx++)
gfx.setPixel(pos++, c);
pos = gfx.pixelPos2D(centerX - y, centerY + x);
for (int xx = centerX - y; xx <= centerX + y; xx++)
gfx.setPixel(pos++, c);
if (m > 0)
{
pos = gfx.pixelPos2D(centerX - x, centerY - y);
for (int xx = centerX - x; xx <= centerX + x; xx++)
gfx.setPixel(pos++, c);
pos = gfx.pixelPos2D(centerX - x, centerY + y);
for (int xx = centerX - x; xx <= centerX + x; xx++)
gfx.setPixel(pos++, c);
y--;
m -= 8 * y;
}
Télécharger le code source
Télécharger l'exécutable pour Windows
Ce code prend autour de 285 ms.
Utiliser des pointeurs
while (x <= y)
{
Color* ptr = &gfx.mPixels2D[gfx.pixelPos2D(centerX - y, centerY - x)];
for (int xx = centerX - y; xx <= centerX + y; xx++)
*ptr++ = c;
ptr = &gfx.mPixels2D[gfx.pixelPos2D(centerX - y, centerY + x)];
for (int xx = centerX - y; xx <= centerX + y; xx++)
*ptr++ = c;
if (m > 0)
{
ptr = &gfx.mPixels2D[gfx.pixelPos2D(centerX - x, centerY - y)];
for (int xx = centerX - x; xx <= centerX + x; xx++)
*ptr++ = c;
ptr = &gfx.mPixels2D[gfx.pixelPos2D(centerX - x, centerY + y)];
for (int xx = centerX - x; xx <= centerX + x; xx++)
*ptr++ = c;
y--;
m -= 8 * y;
}
Télécharger le code source
Télécharger l'exécutable pour Windows
Cette dernière version prend environ 240 ms, c'est 2 fois plus rapide que la première.