- TD,
Je travaille actuellement sur un projet pour lequel j’ai besoin de tracer des quarts de cercles avec des pixels. Ces quarts cercles devant avoir une certaine épaisseur, j’ai décidé de procéder en traçant un certain nombre de quarts de cercles concentriques jusqu’à obtenir l’épaisseur désirée. L’algorithme de Bresenham (ou midpoint algorithm en anglais) est le plus courant mais il a l’inconvénient de laisser des trous entre les cercles. Il se trouve qu’il existe un algorithme ne laissant pas de trous entre les cercles : celui d’Andres. J’ai beaucoup de mal à trouver des informations sur cet algorithme.
J’éprouve des difficultés à implémenter correctement l’algorithme d’Andres. Le pseudo-code donné sur Wikipédia ne fonctionne que pour les cercles dont le centre est pris au centre d’un pixel. Ce que je cherche à faire, c’est tracer un cercle dont le centre est le coin d’un pixel. Je ne souhaite pas couper des cercles de diamètre impair pour obtenir mes quarts de cercles car je veux obtenir la meilleure circularité possible pour mon motif global. Fort heureusement, j’ai pu retrouver l’article original 1 ou Andres explique comment obtenir exactement ce que je veux, et c’est là que ça coince : j’obtiens des trous entre mes cercles !
Pour ceux qui n’ont pas accès à l’article, voici l’algorithme donné et les explications (en pages 7 et 8 du PDF) :
Notez que $x$ est initialisé à $S$ au début de l’algorithme. Je pense qu’il s’agit d’une erreur car d’une part il n’est fait mention nulle part de ce $S$ dans tout l’article, et d’autre part il est dit juste avant que le premier point est $(1,R)$. De plus, l’indentation n’est pas des plus claires notamment pour le else if
.
Mon implémentation est la suivante :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | def half_integer_centered_circle(xc, yc, R): x = 1 y = R d = R while y >= x: draw_pixel(xc + x, yc + y) draw_pixel(xc + x, yc - y + 1) draw_pixel(xc - x + 1, yc + y) draw_pixel(xc - x + 1, yc - y + 1) draw_pixel(xc + y, yc + x) draw_pixel(xc + y, yc - x + 1) draw_pixel(xc - y + 1, yc + x) draw_pixel(xc - y + 1, yc - x + 1) if d > x: d = d - x x = x + 1 elif d < R + 1 - y: d = d + y - 1 y = y - 1 else: d = d + y - x - 1 x = x + 1 y = y - 1 |
Voici quelques quarts de cercles successifs ayant été calculés par mon implémentation :
Il est évident que non seulement il y a des trous (ce que l’algorithme est censé éviter) mais en plus le quart de cercle de trois pixels de large n’est pas identique à celui donné dans l’article. Par ailleurs, le motif obtenu n’est pas très circulaire. En plus, théoriquement on doit trouver dans certains cas plusieurs pixels en ordonnée pour une même abscisse pour l’octant entre $\frac\pi4$ et $\frac\pi2$, mais je n’en obtient qu’un seul pour tous mes tests.
Autant j’ai réussi à adapter l’algorithme de Bresenham à mon besoin, autant là je sèche et je m’en remets à votre expertise.
-
C’est moi qui ai ajouté la référence sur Wikipédia. ↩