Batch Index du Forum
S’enregistrerRechercherFAQMembresGroupesConnexion
Répondre au sujet Page 1 sur 1
Faire des cercles (méthode de Bresenham)
Auteur Message
Répondre en citant
Message Faire des cercles (méthode de Bresenham) 
Hello me revoilà !
Je vous invite à aller voir mon premier partage avec la methode d'Andres : http://batch.xoo.it/t5974-Faire-des-cercles-methode-d-Andres.htm#p44835 Very Happy

Cette fois ci on utilise la méthode de Bresenham pour faire nos cercles à première vue on dirait 2 mêmes cercles mais ils sont différents à qq bouts de code et pixels près:

Andres:

Bresenham:


On peut voir la différence en alternant un algorithme après l'autre et en augmentant le rayon de 1:


Donc voilà la méthode Bresenham est beaucoup plus simple en code mais est désavantageuse niveau des pixels car il reste des trous (mais on pourrait le choisir car la forme du cercle est plus "fine" selon mon avis). La méthode de Andres est plus complexe en code mais le cercle précédent se colle parfaitement sur le suivant donc voilà je propose les 2.

Biensûre toujours utiliser pixelfnt pour un meilleur rendu... (les seuls désavantages c'est qu'on ne sait pas écrire sauf que j'y ai remédié ici : http://batch.xoo.it/t5915-Pixelfnt-enfin-utile.htm)

Voici ma source : https://fr.wikipedia.org/wiki/Algorithme_de_tracé_d%27arc_de_cercle_de_Bresenham

Code:
procédure tracerOctant (entier rayon, entier x_centre, entier y_centre)
        déclarer entier x, y, m ;
        x ← 0 ;
        y ← rayon ;                 // on se place en haut du cercle
        m ← 5 - 4*rayon ;           // initialisation
        Tant que x <= y             // tant qu'on est dans le second octant
                tracerPixel( x+x_centre, y+y_centre ) ;
                si m > 0 alors      // choix du point F
                        y ← y - 1 ;
                        m ← m-8*y ; // correspond au "d" des explications
                fin si ;
                x ← x+1 ;
                m ← m + 8*x+4 ;
        fin tant que ;
fin de procédure ;


Petite photo pour vous donner envie... :


Code:
@echo off
if defined __ goto hello
set __=.
call %0 %* | darkbox
set __=
pause>NUL
goto :eof
:hello
pixelfnt 1
mode con cols=1000 lines=1000
set x_pos=1
set y_pos=1
set r=10
set x=0
set y=%r%
set /a quatre_rayon=4*%r%
set /a m=5-%quatre_rayon%
:debut
if %x% GTR %y% pause>nul
set /a x_7_octant=%x%+%r%
set /a y_7_octant=%y%+%r%
set /a x_6_octant=%r%-%x%
set y_6_octant=%y_7_octant%
set x_1_octant=%y_6_octant%
set y_1_octant=%x_6_octant%
set /a x_8_octant=%y%+%r%
set /a y_8_octant=%x%+%r%
set x_2_octant=%x_7_octant%
set /a y_2_octant=%r%-%y%
set x_5_octant=%y_2_octant%
set y_5_octant=%x_2_octant%
set x_4_octant=%x_5_octant%
set y_4_octant=%y_1_octant%
set x_3_octant=%y_4_octant%
set /a y_3_octant=%x_4_octant%
set /a x_1_octant+=%x_pos%
set /a x_2_octant+=%x_pos%
set /a x_3_octant+=%x_pos%
set /a x_4_octant+=%x_pos%
set /a x_5_octant+=%x_pos%
set /a x_6_octant+=%x_pos%
set /a x_7_octant+=%x_pos%
set /a x_8_octant+=%x_pos%
set /a y_1_octant+=%y_pos%
set /a y_2_octant+=%y_pos%
set /a y_3_octant+=%y_pos%
set /a y_4_octant+=%y_pos%
set /a y_5_octant+=%y_pos%
set /a y_6_octant+=%y_pos%
set /a y_7_octant+=%y_pos%
set /a y_8_octant+=%y_pos%
if %x% LEQ %y% echo /c 0xc /g %x_1_octant% %y_1_octant% /a 219 /g %x_2_octant% %y_2_octant% /a 219 /g %x_3_octant% %y_3_octant% /a 219 /g %x_4_octant% %y_4_octant% /a 219 /g %x_5_octant% %y_5_octant% /a 219 /g %x_6_octant% %y_6_octant% /a 219 /g %x_7_octant% %y_7_octant% /a 219 /g %x_8_octant% %y_8_octant% /a 219
if %m% GTR 0 goto calcul_1
set /a x+=1
set /a m+=4
set /a huit_x=8*%x%
set /a m=%m%+%huit_x%
goto debut
:calcul_1
set /a y-=1
set /a huit_y=8*%y%
set /a m=%m%-%huit_y%
goto debut

Code:
@echo off
if defined __ goto hello
set __=.
call %0 %* | darkbox
set __=
pause>NUL
goto :eof
:hello
pixelfnt 1
mode con cols=100 lines=100
set r=10
set x_pos=20
set y_pos=20
set /a x_pos-=%r%
set /a y_pos-=%r%
set x=0
set y=%r%
set /a quatre_rayon=4*%r%
set /a m=5-%quatre_rayon%
:debut
if %x% GTR %y% pause>nul
set /a x_7_octant=%x%+%r%
set /a y_7_octant=%y%+%r%
set /a x_6_octant=%r%-%x%
set y_6_octant=%y_7_octant%
set x_1_octant=%y_6_octant%
set y_1_octant=%x_6_octant%
set /a x_8_octant=%y%+%r%
set /a y_8_octant=%x%+%r%
set x_2_octant=%x_7_octant%
set /a y_2_octant=%r%-%y%
set x_5_octant=%y_2_octant%
set y_5_octant=%x_2_octant%
set x_4_octant=%x_5_octant%
set y_4_octant=%y_1_octant%
set x_3_octant=%y_4_octant%
set /a y_3_octant=%x_4_octant%
set /a x_1_octant+=%x_pos%
set /a x_2_octant+=%x_pos%
set /a x_3_octant+=%x_pos%
set /a x_4_octant+=%x_pos%
set /a x_5_octant+=%x_pos%
set /a x_6_octant+=%x_pos%
set /a x_7_octant+=%x_pos%
set /a x_8_octant+=%x_pos%
set /a y_1_octant+=%y_pos%
set /a y_2_octant+=%y_pos%
set /a y_3_octant+=%y_pos%
set /a y_4_octant+=%y_pos%
set /a y_5_octant+=%y_pos%
set /a y_6_octant+=%y_pos%
set /a y_7_octant+=%y_pos%
set /a y_8_octant+=%y_pos%
if %x% LEQ %y% echo /c 0xc /g %x_1_octant% %y_1_octant% /a 219 /g %x_2_octant% %y_2_octant% /a 219 /g %x_3_octant% %y_3_octant% /a 219 /g %x_4_octant% %y_4_octant% /a 219 /g %x_5_octant% %y_5_octant% /a 219 /g %x_6_octant% %y_6_octant% /a 219 /g %x_7_octant% %y_7_octant% /a 219 /g %x_8_octant% %y_8_octant% /a 219
if %m% GTR 0 goto calcul_1
set /a x+=1
set /a m+=4
set /a huit_x=8*%x%
set /a m=%m%+%huit_x%
goto debut
:calcul_1
set /a y-=1
set /a huit_y=8*%y%
set /a m=%m%-%huit_y%
goto debut


La variable "r" est pour modifier le rayon
"X/Y_pos" servent à définir l'emplacement du cercle :
- par les extrêmes c'est à dire par la valeur le x la plus petite vers la gauche et la valeur de y la plus petite vers le haut (comme le positionnement d'une fenêtre windows)
- par le centre c'est à dire que la valeur donnée à X/Y_pos sera les coordonnées du centre (pour cela on soustrait juste le rayon à X/Y_pos)

Ensuite on peut imaginer cela comme un bout de code qu'on appelle via un
Code:
call
dans notre programme:
Code:
@echo off
if defined __ goto hello
set __=.
call %0 %* | darkbox
set __=
pause>NUL
goto :eof
:hello
Rem Votre programme
pixelfnt 1
mode con cols=100 lines=100
call:draw_cercle 10 20 20
pause>nul
Rem Fin de votre programme
Rem Bout de code qu'on appelle
:draw_cercle
set r=%~1
set x_pos=%~2
set y_pos=%~3
set /a x_pos-=%r%
set /a y_pos-=%r%
set x=0
set y=%r%
set /a quatre_rayon=4*%r%
set /a m=5-%quatre_rayon%
:loop_draw_cercle
if %x% GTR %y% goto:eof
set /a x_7_octant=%x%+%r%
set /a y_7_octant=%y%+%r%
set /a x_6_octant=%r%-%x%
set y_6_octant=%y_7_octant%
set x_1_octant=%y_6_octant%
set y_1_octant=%x_6_octant%
set /a x_8_octant=%y%+%r%
set /a y_8_octant=%x%+%r%
set x_2_octant=%x_7_octant%
set /a y_2_octant=%r%-%y%
set x_5_octant=%y_2_octant%
set y_5_octant=%x_2_octant%
set x_4_octant=%x_5_octant%
set y_4_octant=%y_1_octant%
set x_3_octant=%y_4_octant%
set /a y_3_octant=%x_4_octant%
set /a x_1_octant+=%x_pos%
set /a x_2_octant+=%x_pos%
set /a x_3_octant+=%x_pos%
set /a x_4_octant+=%x_pos%
set /a x_5_octant+=%x_pos%
set /a x_6_octant+=%x_pos%
set /a x_7_octant+=%x_pos%
set /a x_8_octant+=%x_pos%
set /a y_1_octant+=%y_pos%
set /a y_2_octant+=%y_pos%
set /a y_3_octant+=%y_pos%
set /a y_4_octant+=%y_pos%
set /a y_5_octant+=%y_pos%
set /a y_6_octant+=%y_pos%
set /a y_7_octant+=%y_pos%
set /a y_8_octant+=%y_pos%
if %x% LEQ %y% echo /c 0xc /g %x_1_octant% %y_1_octant% /a 219 /g %x_2_octant% %y_2_octant% /a 219 /g %x_3_octant% %y_3_octant% /a 219 /g %x_4_octant% %y_4_octant% /a 219 /g %x_5_octant% %y_5_octant% /a 219 /g %x_6_octant% %y_6_octant% /a 219 /g %x_7_octant% %y_7_octant% /a 219 /g %x_8_octant% %y_8_octant% /a 219
if %m% GTR 0 goto calcul_1
set /a x+=1
set /a m+=4
set /a huit_x=8*%x%
set /a m=%m%+%huit_x%
goto loop_draw_cercle
:calcul_1
set /a y-=1
set /a huit_y=8*%y%
set /a m=%m%-%huit_y%
goto loop_draw_cercle

Pour avoir le choix entre les deux méthodes dans un même programme
Code:
@echo off
setlocal enabledelayedexpansion enableextensions
if defined __ goto hello
set __=.
call %0 %* | darkbox
set __=
pause>NUL
goto :eof
:hello
Rem Votre programme
REM pixelfnt 1
mode con cols=100 lines=100
call:draw_cercle_Andres 10 20 20
call:draw_cercle_Bresenham 10 42 20
pause>nul
Rem Fin de votre programme
Rem Bout de code qu'on appelle
:draw_cercle_Andres
set r=%~1
set x_pos=%~2
set y_pos=%~3
set /a x_pos-=%r%
set /a y_pos-=%r%
set x=0
set y=%r%
set /a d=%r%-1
:loop_draw_cercle_Andres
set /a deux_x=%x%*2
set /a deux_r_moins_y=2*(%r%-%y%)
set /a y_moins_x=%y%-%x%
set /a y_moins_x_moins_un=%y_moins_x%-1
set /a deux_y_moins_x_moins_un=2*%y_moins_x_moins_un%
if %y% LSS %x% goto:eof
call:draw_cercle
if %d% GEQ %deux_x% goto calcul_1
if %d% LEQ %deux_r_moins_y% goto calcul_2
set /a d+=%deux_y_moins_x_moins_un%
set /a y-=1
set /a x+=1
goto loop_draw_cercle_Andres
:calcul_1
set /a d-=1
set /a d-=%deux_x%
set /a x+=1
goto loop_draw_cercle_Andres
:calcul_2
set /a deux_y=%y%*2
set /a d+=%deux_y%
set /a d-=1
set /a y-=1
goto loop_draw_cercle_Andres

:draw_cercle_Bresenham
set r=%~1
set x_pos=%~2
set y_pos=%~3
set /a x_pos-=%r%
set /a y_pos-=%r%
set x=0
set y=%r%
set /a quatre_rayon=4*%r%
set /a m=5-%quatre_rayon%
:loop_draw_cercle_Bresenham
if %x% GTR %y% goto:eof
call:draw_cercle
if %m% GTR 0 goto calcul_1
set /a x+=1
set /a m+=4
set /a huit_x=8*%x%
set /a m=%m%+%huit_x%
goto loop_draw_cercle_Bresenham
:calcul_1
set /a y-=1
set /a huit_y=8*%y%
set /a m=%m%-%huit_y%
goto loop_draw_cercle_Bresenham
:draw_cercle
set /a x_7_octant=%x%+%r%
set /a y_7_octant=%y%+%r%
set /a x_6_octant=%r%-%x%
set y_6_octant=%y_7_octant%
set x_1_octant=%y_6_octant%
set y_1_octant=%x_6_octant%
set /a x_8_octant=%y%+%r%
set /a y_8_octant=%x%+%r%
set x_2_octant=%x_7_octant%
set /a y_2_octant=%r%-%y%
set x_5_octant=%y_2_octant%
set y_5_octant=%x_2_octant%
set x_4_octant=%x_5_octant%
set y_4_octant=%y_1_octant%
set x_3_octant=%y_4_octant%
set /a y_3_octant=%x_4_octant%
set /a x_1_octant+=%x_pos%
set /a x_2_octant+=%x_pos%
set /a x_3_octant+=%x_pos%
set /a x_4_octant+=%x_pos%
set /a x_5_octant+=%x_pos%
set /a x_6_octant+=%x_pos%
set /a x_7_octant+=%x_pos%
set /a x_8_octant+=%x_pos%
set /a y_1_octant+=%y_pos%
set /a y_2_octant+=%y_pos%
set /a y_3_octant+=%y_pos%
set /a y_4_octant+=%y_pos%
set /a y_5_octant+=%y_pos%
set /a y_6_octant+=%y_pos%
set /a y_7_octant+=%y_pos%
set /a y_8_octant+=%y_pos%
if %y% GEQ %x% echo /c 0xc /g %x_1_octant% %y_1_octant% /a 219 /g %x_2_octant% %y_2_octant% /a 219 /g %x_3_octant% %y_3_octant% /a 219 /g %x_4_octant% %y_4_octant% /a 219 /g %x_5_octant% %y_5_octant% /a 219 /g %x_6_octant% %y_6_octant% /a 219 /g %x_7_octant% %y_7_octant% /a 219 /g %x_8_octant% %y_8_octant% /a 219
goto:eof


On voit d'ailleurs bien la différence entre les deux cercles l'un plus fin que l'autre (mais plus "carré"):

Enjoy! Okay



Dernière édition par programme le Ven 23 Fév 2018 - 22:25; édité 4 fois

______________________________________________________

Programme
Skype
Message Publicité 
PublicitéSupprimer les publicités ?


Répondre en citant
Message Faire des cercles (méthode de Bresenham) 
/!\ UPDATE DU CODE (petite erreur au niveau du déplacement "x_pos,y_pos")




______________________________________________________

Programme
Skype
Message Faire des cercles (méthode de Bresenham) 


Montrer les messages depuis:
Répondre au sujet Page 1 sur 1
  



Index | créer un forum | Forum gratuit d’entraide | Annuaire des forums gratuits | Signaler une violation | Conditions générales d'utilisation
Copyright 2008 - 2016 // Batch