/* Dessin d'un segment de droite par Bresenham */
/* Remplissage 2D d'un triangle */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2010 */
#if defined(WIN32) || defined(WIN64)
#define _CRTDBG_MAP_ALLOC
#if defined(_DEBUG)
#define _AFXDLL
#include <afx.h>
#endif
#endif
#include <stdlib.h>
#if defined(WIN32) || defined(WIN64)
#include <crtdbg.h>
#endif
#include <stdio.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "Position2D.h"
#include "Segment2D.h"
#include "Triangle2D.h"
#include "Trace.h"
/* Variables globales */
static int sc = 0;
/* Fonction executee lors d'un changement */
/* de la taille de la fenetre OpenGL */
/* Configuration d'une camera de visualisation */
/* en projection en parallele orthographique */
void reshape(int tx,int ty) {
glViewport(0,0,tx,ty);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho((-tx/2)/10.0,(-tx/2+tx)/10.0,
(-ty/2)/10.0,(-ty/2+ty)/10.0,
-1.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin */
void display(void) {
glClearColor(0.6F,0.6F,0.6F,1.0F) ;
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) ;
Position2D *ps11 = new Position2D(-15.0,9.0);
Position2D *ps12 = new Position2D(10.0,-10.0);
Segment2D *s1 = new Segment2D(ps11,ps12);
Position2D *ps21 = new Position2D(3.0,2.0);
Position2D *ps22 = new Position2D(15.0,6.0);
Segment2D *s2 = new Segment2D(ps21,ps22);
Position2D *ps32 = new Position2D(-7.0,-13.0);
Position2D *ps31 = new Position2D(-17.0,5.0);
Segment2D *s3 = new Segment2D(ps31,ps32);
Position2D *pt1 = new Position2D(-13.0,9.0);
Position2D *pt2 = new Position2D(11.0,13.0);
Position2D *pt3 = new Position2D(2.0,-10.0);
Triangle2D *t = new Triangle2D(pt1,pt2,pt3);
glPushMatrix();
if ( sc == 0 ) {
glColor3f(0.0F,1.0F,0.0F);
s1->trace();
s2->trace();
s3->trace(); }
if ( ( sc == 2 ) || ( sc == 3 ) ) {
glColor3f(0.0F,0.0F,1.0F);
t->remplit(); }
if ( ( sc == 1 ) || ( sc == 3 ) ) {
glColor3f(1.0F,0.0F,0.0F);
t->trace(); }
glPopMatrix();
delete(s1);
delete(ps11);
delete(ps12);
delete(s2);
delete(ps21);
delete(ps22);
delete(s3);
delete(ps31);
delete(ps32);
delete(pt1);
delete(pt2);
delete(pt3);
delete(t);
glFlush();
glutSwapBuffers();
int error = glGetError();
if ( error != GL_NO_ERROR )
printf("Attention, erreur OpenGL %d\n",error);
}
/* Fonction executee lors de la frappe */
/* d'une touche alphanumerique du clavier */
void keyboard(unsigned char key,int x,int y) {
switch ( key ) {
case 0x0D : sc = (sc+1)%4;
glutPostRedisplay();
break;
case 0x1B : exit(0); }
}
/* Fonction d'initialisation d'OpenGL */
void init(void) {
glPointSize(10.0F);
}
/* Fonction principale */
int main(int argc,char **argv) {
#if defined(WIN32) || defined(WIN64)
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
//_crtBreakAlloc = 109;
#endif
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(400,300);
glutInitWindowPosition(50,50);
glutCreateWindow("Bresenham & remplissage triangle");
init();
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}
/* Position en coordonnees homogenes 2D */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2010 */
#ifndef ____POSITION2D____
#define ____POSITION2D____
class Position2D {
public :
double c[3];
public :
Position2D(void);
Position2D(double x,double y);
Position2D(Position2D *p);
~Position2D(void);
void print(void);
};
#endif
/* Position en coordonnees homogenes 2D */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2010 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "Position2D.h"
Position2D::Position2D(void) {
c[0] = c[1] = 0.0;
c[2] = 1.0;
}
Position2D::Position2D(double x,double y) {
c[0] = x;
c[1] = y;
c[2] = 1.0;
}
Position2D::Position2D(Position2D *p) {
c[0] = p->c[0];
c[1] = p->c[1];
c[2] = p->c[2];
}
Position2D::~Position2D(void) {
}
void Position2D::print(void) {
printf("%20.14lf %20.14lf %lf",c[0],c[1],c[2]);
}
/* Segment en 2D */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2010 */
#ifndef ____SEGMENT2D____
#define ____SEGMENT2D____
class Position2D;
class Rectangle2D;
class Segment2D {
public :
Position2D *pi,*pf;
public :
Segment2D(void);
Segment2D(Position2D *p1,Position2D *p2);
Segment2D(Segment2D *s);
~Segment2D(void);
void print(void);
void trace(void);
int clip(Rectangle2D *r);
};
#endif
/* Segment en 2D */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2010 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "Segment2D.h"
#include "Position2D.h"
#include "Rectangle2D.h"
#include "Trace.h"
Segment2D::Segment2D(void) {
pi = new Position2D();
pf = new Position2D();
}
Segment2D::Segment2D(Position2D *p1,Position2D *p2) {
pi = new Position2D(p1);
pf = new Position2D(p2);
}
Segment2D::Segment2D(Segment2D *s) {
pi = new Position2D(s->pi);
pf = new Position2D(s->pf);
}
Segment2D::~Segment2D(void) {
delete(pi);
delete(pf);
}
void Segment2D::print(void) {
pi->print();
printf("\n");
pf->print();
printf("\n");
}
static int round(double v) {
return((int) (v + (( v > 0.0 ) ? 0.4999 : -0.4999)));
}
void Segment2D::trace(void) {
traceSegment(round(pi->c[0]),round(pi->c[1]),
round(pf->c[0]),round(pf->c[1]));
}
double intersection(double ai,double bi,
double af,double bf,double val) {
if ( af-ai != 0 )
return(bi + (val-ai)/(af-ai)*(bf-bi));
else
return(1000000.0);
}
int code(Position2D *p,Rectangle2D *r) {
int code = 0;
if ( p->c[0] < r->ig->c[0] )
code += 1;
if ( p->c[0] > r->sd->c[0] )
code += 2;
if ( p->c[1] < r->ig->c[1] )
code += 4;
if ( p->c[1] > r->sd->c[1] )
code += 8;
return(code);
}
int Segment2D::clip(Rectangle2D *r) {
int c1,c2;
c1 = code(pi,r);
c2 = code(pf,r);
while ( ( c1 || c2 ) && ( (c1&c2) == 0 ) ) {
if ( !c1 ) {
Position2D p = *pi;
*pi = *pf;
*pf = p;
int aux = c1;
c1 = c2;
c2 = aux; }
if ( (c1&0x01) != 0 ) {
pi->c[1] = intersection(pi->c[0],pi->c[1],
pf->c[0],pf->c[1],
r->ig->c[0]);
pi->c[0] = r->ig->c[0]; }
else
if ( (c1&0x02) != 0 ) {
pi->c[1] = intersection(pi->c[0],pi->c[1],
pf->c[0],pf->c[1],
r->sd->c[0]);
pi->c[0] = r->sd->c[0]; }
else
if ( (c1&0x04) != 0 ) {
pi->c[0] = intersection(pi->c[1],pi->c[0],
pf->c[1],pf->c[0],
r->ig->c[1]);
pi->c[1] = r->ig->c[1]; }
else
if ( (c1&0x08) != 0 ) {
pi->c[0] = intersection(pi->c[1],pi->c[0],
pf->c[1],pf->c[0],
r->sd->c[1]);
pi->c[1] = r->sd->c[1]; }
c1 = code(pi,r); }
return ( !c1 && !c2);
}
/* Triangle en 2D */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2010 */
#ifndef ____TRIANGLE2D____
#define ____TRIANGLE2D____
class Position2D;
class Triangle2D {
public :
Position2D *p1,*p2,*p3;
public :
Triangle2D(void);
Triangle2D(Position2D *pt1,
Position2D *pt2,
Position2D *pt3);
Triangle2D(Triangle2D *t);
~Triangle2D(void);
void print(void);
void trace(void);
void remplit(void);
};
#endif
/* Triangle en 2D */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2010 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "Triangle2D.h"
#include "Position2D.h"
#include "Trace.h"
Triangle2D::Triangle2D(void) {
p1 = new Position2D();
p2 = new Position2D();
p3 = new Position2D();
}
Triangle2D::Triangle2D(Position2D *pt1,
Position2D *pt2,
Position2D *pt3) {
p1 = new Position2D(pt1);
p2 = new Position2D(pt2);
p3 = new Position2D(pt3);
}
Triangle2D::Triangle2D(Triangle2D *t) {
p1 = new Position2D(t->p1);
p2 = new Position2D(t->p2);
p3 = new Position2D(t->p3);
}
Triangle2D::~Triangle2D(void) {
delete(p1);
delete(p2);
delete(p3);
}
void Triangle2D::print(void) {
p1->print();
printf("\n");
p2->print();
printf("\n");
p3->print();
printf("\n");
}
static int round(double v) {
return((int) (v + (( v > 0.0 ) ? 0.4999 : -0.4999)));
}
void Triangle2D::trace(void) {
traceSegment(round(p1->c[0]),round(p1->c[1]),
round(p2->c[0]),round(p2->c[1]));
traceSegment(round(p1->c[0]),round(p1->c[1]),
round(p3->c[0]),round(p3->c[1]));
traceSegment(round(p3->c[0]),round(p3->c[1]),
round(p2->c[0]),round(p2->c[1]));
}
static void gereAbscisse(int x,int y,int *xmin,int *xmax) {
if ( x < xmin[y] )
xmin[y] = x;
if ( x > xmax[y] )
xmax[y] = x;
}
static void traceCote(int xi,int yi,int xf,int yf,
int *xmin,int *xmax,int ymin) {
int i,cumul;
yi -= ymin;
yf -= ymin;
int x = xi;
int y = yi;
int dx = xf - xi;
int dy = yf - yi;
int xinc = ( dx > 0 ) ? 1 : -1;
int yinc = ( dy > 0 ) ? 1 : -1;
dx = abs(dx);
dy = abs(dy);
gereAbscisse(x,y,xmin,xmax);
if ( dx > dy ) {
cumul = dx / 2;
for ( i = 1 ; i <= dx ; i++ ) {
x += xinc;
cumul += dy;
if (cumul >= dx) {
cumul -= dx;
y += yinc; }
gereAbscisse(x,y,xmin,xmax); } }
else {
cumul = dy / 2;
for ( i = 1 ; i <= dy ; i++ ) {
y += yinc;
cumul += dx;
if ( cumul >= dy ) {
cumul -= dy;
x += xinc; }
gereAbscisse(x,y,xmin,xmax); } }
}
void Triangle2D::remplit(void) {
int ymin = round(p1->c[1]);
int ymax = round(p1->c[1]);
if ( round(p2->c[1]) < ymin )
ymin = round(p2->c[1]);
if ( round(p2->c[1]) > ymax )
ymax = round(p2->c[1]);
if ( round(p3->c[1]) < ymin )
ymin = round(p3->c[1]);
if ( round(p3->c[1]) > ymax )
ymax = round(p3->c[1]);
int dy = ymax-ymin+1;
int *xmin =(int *) calloc(dy,sizeof(int));
int *xmax =(int *) calloc(dy,sizeof(int));
for ( int i = 0 ; i < dy ; i++ ) {
xmax[i] = -1000000;
xmin[i] = 1000000; }
traceCote(round(p1->c[0]),round(p1->c[1]),
round(p2->c[0]),round(p2->c[1]),
xmin,xmax,ymin);
traceCote(round(p1->c[0]),round(p1->c[1]),
round(p3->c[0]),round(p3->c[1]),
xmin,xmax,ymin);
traceCote(round(p3->c[0]),round(p3->c[1]),
round(p2->c[0]),round(p2->c[1]),
xmin,xmax,ymin);
glBegin(GL_POINTS);
for ( int y = ymin ; y <= ymax ; y++ )
for ( int x = xmin[y-ymin] ; x <= xmax[y-ymin] ; x++ )
glVertex2i(x,y);
glEnd();
free(xmin);
free(xmax);
}
/* Fonctions de dessin OpenGL */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2010 */
#ifndef ____TRACE____
#define ____TRACE____
void traceSegment(int xi,int yi,int xf,int yf);
#endif
/* Fonctions de dessin OpenGL */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2010 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
void traceSegment(int xi,int yi,int xf,int yf) {
glBegin(GL_POINTS);
int i,cumul;
int x = xi;
int y = yi;
int dx = xf - xi;
int dy = yf - yi;
int xinc = ( dx > 0 ) ? 1 : -1;
int yinc = ( dy > 0 ) ? 1 : -1;
dx = abs(dx);
dy = abs(dy);
glVertex2i(x,y);
if ( dx > dy ) {
cumul = dx / 2;
for ( i = 1 ; i <= dx ; i++ ) {
x += xinc;
cumul += dy;
if (cumul >= dx) {
cumul -= dx;
y += yinc; }
glVertex2i(x,y); } }
else {
cumul = dy / 2;
for ( i = 1 ; i <= dy ; i++ ) {
y += yinc;
cumul += dx;
if ( cumul >= dy ) {
cumul -= dy;
x += xinc; }
glVertex2i(x,y); } }
glEnd();
}