Tracer un cercle avec brensenham

Contenu du snippet

Implémentation de l'algo de Brensenham-Cercle qui permet à partir du centre et du rayon du cercle de le tracer point par point. Cet algo est optimisé: il n'utilise que des valeurs entieres, et il n'y a que des additions et soustractions dans la boucle principale.

Source / Exemple :


#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>

/*
Info.Graphique(Infographie) : Brensenham-Cercle

http://www.Software-DS.com

Dessine un cercle point par point par l'algo de BrensenhamCercle

Compilation : (Fonctionne sur MacOSX si vous avez installe X11)
gcc -o cercle CercleBrensenham.c -L/usr/X11R6/lib -lX11

  • /
/* variables globales */ GC gc; Display *display; int screen; Window win,root; int win_larg,win_haut; unsigned long white_pixel, black_pixel; /* prototypes */ void contact_serveur(); void Creat_fenetre(void); void gerer_evenement(); void BrensenhamCercle(int r, int x_centre,int y_centre); void AffichePixel(int x,int y, int x_centre,int y_centre); /* ******************************************************************** */ void contact_serveur() { if ((display = XOpenDisplay("")) == NULL) { fprintf(stderr, "Can't open Display\n"); exit(1); } } /* contact_serveur */ /* ******************************************************************** */ void Creat_fenetre(void) { short border_width; screen = DefaultScreen(display); root = RootWindow(display,screen); white_pixel= WhitePixel(display,screen); black_pixel= BlackPixel(display,screen); border_width = 3; win_larg = DisplayWidth(display,screen)/3; win_haut = DisplayHeight(display,screen)/3; win = XCreateSimpleWindow(display,root,0,0,win_larg,win_haut, border_width,black_pixel,white_pixel); gc=DefaultGC(display,screen); XStoreName(display,win,"CercleBrensenham - DS"); XMapWindow(display,win); } /* Creat_fenetre */ /* ******************************************************************** */ void gerer_evenement(){ char *str1="http://www.Software-DS.com"; int i,x_centre=140,y_centre=120; XSelectInput(display,win,ExposureMask | KeyPressMask); for(;;) { XEvent ev; XNextEvent(display,&ev); switch(ev.type) { case Expose : /* On va afficher des dessins ;) */ /* on dessine des axes centres sur le centre du cercle */ XDrawLine(display,win,gc,0,y_centre,x_centre*2,y_centre); XDrawLine(display,win,gc,x_centre,0,x_centre,y_centre*2); /* on dessine 5 cercles de meme centre */ for(i=1;i<6;i++) { /* on dessine une cible */ BrensenhamCercle(i*20,x_centre,y_centre); } break; case KeyPress : /* on appuie sur une touche pour quitter */ XClearWindow(display,win); XDrawString(display,win,gc,win_larg/5,win_haut*2/5,str1,strlen(str1)); XFlush(display); sleep(3); /* une petite pause avant de quitter */ XDestroyWindow(display,win); XCloseDisplay(display); exit(0); break; default : fprintf(stderr,"J'ai recu un evt : %d\n",ev.type); break; } /* switch */ } /* for */ } /* gerer_evts */ /* ******************************************************************** */ int main() { contact_serveur(); Creat_fenetre(); gerer_evenement(); return 0; } /* main */ /* ******************************************************************** */ void BrensenhamCercle(int r,int x_centre,int y_centre) { /* r est le rayon du cercle. (x_centre,x_centre) les coordonnees du centre du cercle */ int x,y,d; x=0; y=r; d=(5-r)/4; AffichePixel(x,y,x_centre,y_centre); while(y>x) { if (d<0) d+=x+x+3; else { d+=x+x-y-y+5; y--; } x++; AffichePixel(x,y,x_centre,y_centre); } /* while */ } /* BrensenhamCercle */ /* ******************************************************************** */ void AffichePixel(int x, int y, int x_centre, int y_centre) { /* (x,y) les coordonnes du pixel a dessiner, (x_centre,x_centre) les coordonnees du centre du cercle */ /* d'apres les symetries d'un cercle, on peut un pixel dessiner a 8 endroits en meme temps */ XDrawPoint(display,win,gc, x_centre+x, y_centre+y); XDrawPoint(display,win,gc, x_centre+x, y_centre-y); XDrawPoint(display,win,gc, x_centre-x, y_centre+y); XDrawPoint(display,win,gc, x_centre-x, y_centre-y); XDrawPoint(display,win,gc, x_centre+y, y_centre+x); XDrawPoint(display,win,gc, x_centre+y, y_centre-x); XDrawPoint(display,win,gc, x_centre-y, y_centre+x); XDrawPoint(display,win,gc, x_centre-y, y_centre-x); } /* AffichePixel */

Conclusion :


Pour ceux qui sont interessé par Brensenham, il y a aussi un code source pour tracer des droites ici :
http://www.cppfrance.com/code.aspx?ID=23206

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.