/* Position en coordonnees homogenes 2D */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2011 */
#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 2011 */
#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 2011 */
#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);
double abscisse(double y);
double ordonnee(double x);
int clip(Rectangle2D *r);
};
#endif
/* Segment en 2D */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2011 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "Segment2D.h"
#include "Position2D.h"
#include "Rectangle2D.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)));
}
int code(Position2D *p,Rectangle2D *r) {
int code = 0x0000;
if ( p->c[0] < r->ig->c[0] )
code |= 0x0001;
if ( p->c[0] > r->sd->c[0] )
code |= 0x0002;
if ( p->c[1] < r->ig->c[1] )
code |= 0x0004;
if ( p->c[1] > r->sd->c[1] )
code |= 0x0008;
return(code);
}
double Segment2D::abscisse(double y) {
double a = (pf->c[1]-pi->c[1])/(pf->c[0]-pi->c[0]);
double b = pi->c[1] - a*pi->c[0];
return((y-b)/a);
}
double Segment2D::ordonnee(double x) {
double a = (pf->c[1]-pi->c[1])/(pf->c[0]-pi->c[0]);
double b = pi->c[1] - a*pi->c[0];
return(a*x+b);
}
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&0x0001) != 0 ) {
pi->c[1] = ordonnee(r->ig->c[0]);
pi->c[0] = r->ig->c[0]; }
else
if ( (c1&0x0002) != 0 ) {
pi->c[1] = ordonnee(r->sd->c[0]);
pi->c[0] = r->sd->c[0]; }
else
if ( (c1&0x0004) != 0 ) {
pi->c[0] = abscisse(r->ig->c[1]);
pi->c[1] = r->ig->c[1]; }
else
if ( (c1&0x0008) != 0 ) {
pi->c[0] = abscisse(r->sd->c[1]);
pi->c[1] = r->sd->c[1]; }
c1 = code(pi,r); }
return ( !c1 && !c2);
}
/* Rectangle en 2D */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2011 */
#ifndef ____RECTANGLE2D____
#define ____RECTANGLE2D____
class Position2D;
class Segment2D;
class Rectangle2D {
public :
Position2D *ig,*sd;
public :
Rectangle2D(void);
Rectangle2D(Position2D *p1,Position2D *p2);
Rectangle2D(Rectangle2D *s);
~Rectangle2D(void);
void print(void);
void clip(Segment2D *s);
};
#endif
/* Rectangle en 2D */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2011 */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "Rectangle2D.h"
#include "Position2D.h"
#include "Segment2D.h"
Rectangle2D::Rectangle2D(void) {
ig = new Position2D();
sd = new Position2D();
}
Rectangle2D::Rectangle2D(Position2D *p1,Position2D *p2) {
ig = new Position2D(p1);
sd = new Position2D(p2);
}
Rectangle2D::Rectangle2D(Rectangle2D *s) {
ig = new Position2D(s->ig);
sd = new Position2D(s->sd);
}
Rectangle2D::~Rectangle2D(void) {
delete(ig);
delete(sd);
}
void Rectangle2D::print(void) {
ig->print();
printf("\n");
sd->print();
printf("\n");
}
void Rectangle2D::clip(Segment2D *s) {
s->clip(this);
}
Le source : Cohen-Sutherland.cpp
/* Clipping de Cohen-Sutherland */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Septembre 2011 */
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "Rectangle2D.h"
#include "Position2D.h"
#include "Segment2D.h"
/* Variables et constantes globales */
static int scn = 0;
/* Fonction d'initialisation des parametres */
/* OpenGL ne changeant pas au cours de la vie */
/* du programme */
void init(void) {
}
/* Scene dessinee */
static void drawRectangle(Rectangle2D *r) {
glPushMatrix();
glBegin(GL_LINE_LOOP);
glVertex2d(r->ig->c[0],r->ig->c[1]);
glVertex2d(r->sd->c[0],r->ig->c[1]);
glVertex2d(r->sd->c[0],r->sd->c[1]);
glVertex2d(r->ig->c[0],r->sd->c[1]);
glEnd();
glPopMatrix();
}
static void drawSegment(Segment2D *s) {
glPushMatrix();
glBegin(GL_LINES);
glVertex2d(s->pi->c[0]+0.4999,s->pi->c[1]+0.4999);
glVertex2d(s->pf->c[0]+0.4999,s->pf->c[1]+0.4999);
glEnd();
glPopMatrix();
}
void sceneAvecClipping(void) {
Position2D *p1 = new Position2D(100.0,80.0);
Position2D *p2 = new Position2D(300.0,220.0);
Rectangle2D *r = new Rectangle2D(p1,p2);
delete(p1);
delete(p2);
glPushMatrix();
glColor3f(1.0F,1.0F,1.0F);
drawRectangle(r);
glPopMatrix();
for ( int i = 0 ; i < 100 ; i++ ) {
Position2D *pi = new Position2D(rand()%400,rand()%300);
Position2D *pf = new Position2D(rand()%400,rand()%300);
Segment2D *s = new Segment2D(pi,pf);
delete(pi);
delete(pf);
glColor3f(1.0F,0.0F,0.0F);
if ( s->clip(r) )
drawSegment(s);
delete(s); }
delete(r);
}
void sceneSansClipping(void) {
Position2D *p1 = new Position2D(100.0,80.0);
Position2D *p2 = new Position2D(300.0,220.0);
Rectangle2D *r = new Rectangle2D(p1,p2);
delete(p1);
delete(p2);
glPushMatrix();
glColor3f(1.0F,1.0F,1.0F);
drawRectangle(r);
glPopMatrix();
for ( int i = 0 ; i < 100 ; i++ ) {
Position2D *pi = new Position2D(rand()%400,rand()%300);
Position2D *pf = new Position2D(rand()%400,rand()%300);
Segment2D *s = new Segment2D(pi,pf);
delete(pi);
delete(pf);
glColor3f(1.0F,0.0F,0.0F);
drawSegment(s);
delete(s); }
delete(r);
}
/* Fonction executee lors d'un changement */
/* de la taille de la fenetre OpenGL */
void reshape(int tx,int ty) {
glViewport(0,0,tx,ty);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,tx,0,ty,-20.0,20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin */
void display(void) {
glClearColor(0.5F,0.5F,0.5F,0.5F);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
srand(1);
glPushMatrix();
if ( scn )
sceneAvecClipping();
else
sceneSansClipping();
glPopMatrix();
glFlush();
glutSwapBuffers();
int error = glGetError();
if ( error != GL_NO_ERROR )
printf("Erreur : %d\n",error);
}
/* Fonction executee lors de l'appui */
/* d'une touche alphanumerique du clavier */
void keyboard(unsigned char key,int x,int y) {
switch (key) {
case 0x0D :
scn = (scn+1)%2;
glutPostRedisplay();
break;
case 0x1B :
exit(0);
break; }
}
/* Fonction principale */
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(400,300);
glutInitWindowPosition(50,50);
glutCreateWindow("Clipping de Cohen-Sutherland");
init();
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}