Le source : CercleEtDisque.cpp
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2005 */
/* Illustration du trace */
/* de cercle et de disque */
/* par l'algorithme */
/* de Bresenham (Midpoint) */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "ModuleCouleurs.h"
#include "ModuleMenus.h"
#include "ModuleReshape.h"
#include "ModuleFont.h"
#ifndef M_PI
#define M_PI 3.14159F
#endif
static int aff = 0;
static int r = 10;
static int yy = 0;
static int cc = 0;
static int c = 1;
static int f1;
static int fv;
void circle(int *p1,float r) {
glColor4fv(couleurBleu());
glBegin(GL_LINE_LOOP);
for ( int i = 0; i < 360; i++ ) {
float angle = i * M_PI / 180;
float x = (float) (p1[0] + r*cos(angle));
float y = (float) (p1[1] + r*sin(angle));
glVertex2f(x,y); }
glEnd();
}
void pixel(int x,int y,float *c) {
glColor4fv(c);
glBegin(GL_QUADS);
glVertex2f(x-0.5F,y-0.5F);
glVertex2f(x-0.5F,y+0.5F);
glVertex2f(x+0.5F,y+0.5F);
glVertex2f(x+0.5F,y-0.5F);
glEnd();
glColor4fv(couleurNoir());
glBegin(GL_LINE_LOOP);
glVertex2f(x-0.5F,y-0.5F);
glVertex2f(x-0.5F,y+0.5F);
glVertex2f(x+0.5F,y+0.5F);
glVertex2f(x+0.5F,y-0.5F);
glEnd();
}
void trame(int xi,int xf,int y,float *c) {
for ( int i = xi; i <= xf; i++ )
pixel(i,y,c);
}
int comptePixelsTrame(int xi,int xf) {
return(xf-xi+1);
}
void pixelsSymetriques8(int x,int y,float *c) {
pixel( x, y,c);
pixel(-x, y,c);
pixel( x,-y,c);
pixel(-x,-y,c);
pixel( y, x,c);
pixel(-y, x,c);
pixel( y,-x,c);
pixel(-y,-x,c);
}
void pixelsSymetriques4(int x,int y,float *c) {
pixel( x, y,c);
pixel( x,-y,c);
pixel( y, x,c);
pixel(-y, x,c);
}
void pixelsSymetriques4(int cd,float *c) {
pixel( cd, cd,c);
pixel( cd,-cd,c);
pixel(-cd, cd,c);
pixel(-cd,-cd,c);
}
void cercle(float *c,int r) {
int x,y,d;
x = 0;
y = r;
d = 1 - r;
if ( r == 0 ) {
pixel(0,0,c);
return; }
pixelsSymetriques4(0,y,c);
if ( r == 1 ) {
return; }
while ( y > x ) {
if ( d < 0 )
d += 2 * x + 3;
else {
d += 2 * (x - y) + 5;
y--; }
x++;
if ( x < y )
pixelsSymetriques8(x,y,c);
else
if ( x == y )
pixelsSymetriques4(x,c); }
}
void cercleIncomplet(float *c,int r,int max) {
int x,y,d;
x = 0;
y = r;
d = 1 - r;
if ( r == 0 ) {
pixel(0,0,c);
return; }
pixelsSymetriques4(0,y,c);
if ( r == 1 ) {
return; }
if ( r == 0 )
return;
int cp = 0;
while ( ( y > x ) && ( cp < max ) ) {
cp++;
if ( d < 0 )
d += 2 * x + 3;
else {
d += 2 * (x - y) + 5;
y--; }
x++;
if ( x < y )
pixelsSymetriques8(x,y,c);
else
if ( x == y )
pixelsSymetriques4(x,c); }
}
void disque(float *c,int r) {
int x,y,d;
x = 0;
y = r;
d = 1 - r;
if ( r == 0 ) {
pixel(0,0,c);
return; }
if ( r == 1 ) {
pixel(0,y,c);
pixel(0,-y,c);
return; }
trame(-y,y,x,c);
while ( y > x ) {
if ( d < 0 )
d += 2 * x + 3;
else {
if ( y > x ) {
trame(-x,x,y,c);
trame(-x,x,-y,c); }
d += 2 * (x - y) + 5;
y--; }
x++;
if ( y >= x ) {
trame(-y,y,x,c);
trame(-y,y,-x,c); } }
}
void disqueIncomplet(float *c,int r,int max) {
int x,y,d;
x = 0;
y = r;
d = 1 - r;
if ( r == 0 ) {
pixel(0,0,c);
return; }
if ( r == 1 ) {
pixel(0,y,c);
pixel(0,-y,c);
return; }
trame(-y,y,x,c);
int cp = 0;
while ( ( y > x ) && ( cp < max ) ) {
cp++;
if ( d < 0 )
d += 2 * x + 3;
else {
if ( y > x ) {
trame(-x,x,y,c);
trame(-x,x,-y,c); }
d += 2 * (x - y) + 5;
y--; }
x++;
if ( y >= x ) {
trame(-y,y,x,c);
trame(-y,y,-x,c); } }
}
void display() {
int p[] = { 0,0 };
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
switch (aff) {
case 0 : if ( ( cc == 1 ) || ( cc == 2 ) )
disque(couleurVert(),r);
if ( ( cc == 0 ) || ( cc == 2 ) )
cercle(couleurRouge(),r);
if ( c )
circle(p,r);
break;
case 1 : if ( ( cc == 1 ) || ( cc == 2 ) )
disqueIncomplet(couleurVert(),r,yy);
if ( ( cc == 0 ) || ( cc == 2 ) )
cercleIncomplet(couleurRouge(),r,yy);
if ( c )
circle(p,r);
break; }
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void myinit() {
glShadeModel(GL_SMOOTH);
glClearColor(0.8F,0.8F,0.8F,1.0F);
}
void postRedisplay() {
glutPostWindowRedisplay(f1);
glutPostWindowRedisplay(fv);
}
void key(unsigned char key,int x,int y) {
switch ( key ) {
case 'r' : r--;
if ( r < 0 )
r = 0;
postRedisplay();
break;
case 'R' : r++;
if ( r > 28 )
r = 28;
postRedisplay();
break;
case 'c' :
case 'C' : c = !c;
postRedisplay();
break;
case ' ' : cc = (cc+1)%3;
postRedisplay();
break;
case 43 : yy++;
if ( yy == 60 )
yy = 0;
postRedisplay();
break;
case 45 : yy--;
if ( yy == -1 )
yy = 0;
postRedisplay();
break;
case 0x0D : yy = 0;
aff = !aff;
postRedisplay();
break;
case 0x1B : exit(0);
break; }
}
int comptePixelsCercle(int r) {
int x,y,d;
x = 0;
y = r;
d = 1 - r;
if ( r == 0 ) {
return(1); }
if ( r == 1 ) {
return(4); }
int cpt = 4;
while ( y > x ) {
if ( d < 0 )
d += 2 * x + 3;
else {
d += 2 * (x - y) + 5;
y--; }
x++;
if ( x < y )
cpt += 8;
else
if ( x == y )
cpt += 4; }
return(cpt);
}
int comptePixelsCercleIncomplet(int r,int max) {
int x,y,d;
x = 0;
y = r;
d = 1 - r;
if ( r == 0 ) {
return(1); }
if ( r == 1 ) {
return(4); }
int cpt = 4;
int cp = 0;
while ( ( y > x ) && ( cp < max ) ) {
cp++;
if ( d < 0 )
d += 2 * x + 3;
else {
d += 2 * (x - y) + 5;
y--; }
x++;
if ( x < y )
cpt += 8;
else
if ( x == y )
cpt += 4; }
return(cpt);
}
int comptePixelsDisque(int r) {
int x,y,d;
x = 0;
y = r;
d = 1 - r;
if ( r == 0 ) {
return(1); }
if ( r == 1 ) {
return(5); }
int cpt = comptePixelsTrame(-y,y);
while ( y > x ) {
if ( d < 0 )
d += 2 * x + 3;
else {
if ( y > x ) {
cpt += comptePixelsTrame(-x,x);
cpt += comptePixelsTrame(-x,x); }
d += 2 * (x - y) + 5;
y--; }
x++;
if ( y >= x ) {
cpt += comptePixelsTrame(-y,y);
cpt += comptePixelsTrame(-y,y); } }
return(cpt);
}
int comptePixelsDisqueIncomplet(int r,int max) {
int x,y,d;
x = 0;
y = r;
d = 1 - r;
if ( r == 0 ) {
return(1); }
if ( r == 1 ) {
return(5); }
int cpt = comptePixelsTrame(-y,y);
int cp = 0;
while ( ( y > x ) && ( cp < max ) ) {
cp++;
if ( d < 0 )
d += 2 * x + 3;
else {
if ( y > x ) {
cpt += comptePixelsTrame(-x,x);
cpt += comptePixelsTrame(-x,x); }
d += 2 * (x - y) + 5;
y--; }
x++;
if ( y >= x ) {
cpt += comptePixelsTrame(-y,y);
cpt += comptePixelsTrame(-y,y); } }
return(cpt);
}
void displayV(void) {
glClearColor(0.0F,0.0F,0.0F,1.0F) ;
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
glPushMatrix();
float pos = 1.0F;
glColor4fv(couleurBlanc());
placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
simpleBitmapOutput(1,REGULAR8x13,"RAYON : %6d",r);
pos += 1.0F;
switch (aff) {
case 0 : if ( ( cc == 0 ) || ( cc == 2 ) ) {
placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
simpleBitmapOutput(1,
REGULAR8x13,
"2*PI*R : %9.2f",
2*M_PI*r);
pos += 1.0F;
placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
simpleBitmapOutput(1,
REGULAR8x13,
"PIXELS DU CERCLE : %6d",
comptePixelsCercle(r));
pos += 1.0F; }
if ( ( cc == 1 ) || ( cc == 2 ) ) {
placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
simpleBitmapOutput(1,
REGULAR8x13,
"PI*R*R : %9.2f",
M_PI*r*r);
pos += 1.0F;
placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
simpleBitmapOutput(1,
REGULAR8x13,
"PIXELS DU DISQUE : %6d",
comptePixelsDisque(r));
pos += 1.0F; }
break;
case 1 : if ( ( cc == 0 ) || ( cc == 2 ) ) {
placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
simpleBitmapOutput(1,
REGULAR8x13,
"PIXELS DU CERCLE : %6d",
comptePixelsCercleIncomplet(r,yy));
pos += 1.0F; }
if ( ( cc == 1 ) || ( cc == 2 ) ) {
placeFontCursor(5.0F,-pos*20.0F,0.0F) ;
simpleBitmapOutput(1,
REGULAR8x13,
"PIXELS DU DISQUE : %6d",
comptePixelsDisqueIncomplet(r,yy));
pos += 1.0F; }
break; }
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void reshapeV(int w,int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,w,-h,0,-1.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc,char **argv) {
glutInit(&argc,argv);
{ glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(300,300);
glutInitWindowPosition(50,50);
f1 = glutCreateWindow("Cercle et disque par Bresenham");
myinit();
creationMenuBasique();
setParametresOrthoBasique(-30.0,30.0,-30.0,30.0,-40.0,40.0);
glutReshapeFunc(reshapeOrthoBasique);
glutKeyboardFunc(key);
glutDisplayFunc(display); }
{ glutInitWindowSize(300,70);
glutInitWindowPosition(50,380);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
fv = glutCreateWindow("Valeurs");
creationMenuBasique();
glutDisplayFunc(displayV);
glutReshapeFunc(reshapeV);
glutKeyboardFunc(key); }
glutMainLoop();
return(0);
}