L'exécutable

Image1002.gif (3478 octets)   

Le source : TD-Clipping.cpp

/* Auteur: Nicolas JANEY                 */
/* nicolas.janey@univ-fcomte.fr          */
/* Avril 2001                            */
/* Le clipping de Cohen-Sutherland en 3D */

#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 "ModuleManipulateur.h"
#include "ModuleMenus.h"
#include "ModuleReshape.h"

struct coord_3D {
  float x ;
  float y ;
  float z ; } ;

struct segment {
  struct coord_3D pi ;
  struct coord_3D pf ; } ;

struct boite {
  struct coord_3D pi ;
  struct coord_3D pf ; } ;

static float anglex = 0.0F ;
static float angley = 0.0F ;
static int clip = 0 ;
struct segment s[5] = { {{5,5,5},{-1,-7,-8}},
                        {{8,-6,-4},{1,7,-2}},
                        {{-8,6,-7},{7,-3,8}},
                        {{2,6,-4},{-5,-7,4}},
                        {{5,2,-7},{-3,3,-1}} } ;
struct boite b = { {-4,-4,-4},{4,4,4} } ;

int code(coord_3D *p,boite *r) { 
  int c ;
  if ( p->x < r->pi.x )
    c = 1 ;
    else
    c = 0 ;
  if ( p->x > r->pf.x )
    c += 2 ;
  if ( p->y < r->pi.y )
    c += 4 ;
  if ( p->y > r->pf.y )
    c += 8 ;
  if ( p->z < r->pi.z )
    c += 16 ;
  if ( p->z > r->pf.z )
    c += 32 ;
  return(c) ;
}

int code_nul(int c) { 
  return(c == 0) ;
}

int pas1commun(int c1,int c2) { 
  return((c1&c2) == 0) ;
}

int code0(int c) { 
  return(c&1) ;
}

int code1(int c) { 
  return(c&2) ;
}

int code2(int c) { 
  return(c&4) ;
}

int code3(int c) { 
  return(c&8) ;
}

int code4(int c) { 
  return(c&16) ;
}

int code5(int c) { 
  return(c&32) ;
}

float intersection(float px,float py,float pz,float dx,float dy,float dz,float val,int type) {
  float res = 0.0F ;
  switch ( type ) {
  case 0 : if ( dx != 0 )
           res = (val-px)/dx ;
           else
       res = 1.0e+10 ;
         break ;
  case 1 : if ( dy != 0 )
           res = (val-py)/dy ;
           else
       res = 1.0e+10 ;
         break ;
  case 2 : if ( dz != 0 )
           res = (val-pz)/dz ;
           else
       res = 1.0e+10 ;
         break ; }
  return(res) ;
}

void clipping(struct segment *s,struct boite *b) {
  segment se = *s ;
  int c1,c2 ;
  coord_3D p ;
  c1 = code(&s->pi,b) ;
  c2 = code(&s->pf,b) ;
  float px,py,pz ;
  float dx,dy,dz ;
  px = s->pi.x ;
  py = s->pi.y ;
  pz = s->pi.z ;
  dx = px - s->pf.x ;
  dy = py - s->pf.y ;
  dz = pz - s->pf.z ;
  while ( ( !code_nul(c1) || !code_nul(c2) ) && ( pas1commun(c1,c2)  ) ) {
    if ( code_nul(c1) ) {
      p = s->pi ;
      s->pi = s->pf ;
      s->pf = p ;
      c1 = c2 ; }
    if ( code0(c1) ) {
      float coef = intersection(px,py,pz,dx,dy,dz,b->pi.x,0) ;
       s->pi.y = py + coef*dy ;
    s->pi.z = pz + coef*dz ;
      s->pi.x = b->pi.x ; }
      else
      if ( code1(c1) ) {
        float coef = intersection(px,py,pz,dx,dy,dz,b->pf.x,0) ;
       s->pi.y = py + coef*dy ;
    s->pi.z = pz + coef*dz ;
        s->pi.x = b->pf.x ; }
        else
        if ( code2(c1) ) {
          float coef = intersection(px,py,pz,dx,dy,dz,b->pi.y,1) ;
         s->pi.x = px + coef*dx ;
      s->pi.z = pz + coef*dz ;
          s->pi.y = b->pi.y ; }
          else
          if ( code3(c1) ) {
            float coef = intersection(px,py,pz,dx,dy,dz,b->pf.y,1) ;
           s->pi.x = px + coef*dx ;
      s->pi.z = pz + coef*dz ;
            s->pi.y = b->pf.y ; }
            else
            if ( code4(c1) ) {
              float coef = intersection(px,py,pz,dx,dy,dz,b->pi.z,2) ;
             s->pi.x = px + coef*dx ;
        s->pi.y = py + coef*dy ;
              s->pi.z = b->pi.z ; }
              else
              if ( code5(c1) ) {
                float coef = intersection(px,py,pz,dx,dy,dz,b->pf.z,2) ;
        s->pi.x = px + coef*dx ;
        s->pi.y = py + coef*dy ;
                s->pi.z = b->pf.z ; }
    c1 = code(&s->pi,b) ;
    c2 = code(&s->pf,b) ; }
  if ( code_nul(c1) && code_nul(c2) ) {
    glBegin(GL_LINES) ;
    glVertex3f(s->pi.x,s->pi.y,s->pi.z) ;
    glVertex3f(s->pf.x,s->pf.y,s->pf.z) ;
    glEnd() ; }
  *s = se ;
}

void display(void) {
  glClearColor(0.0F,0.0F,0.0F,0.0F);
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  manipulateurSouris();
  manipulateurClavier();
  glRotatef(30.0,1.0F,1.0F,1.0F) ;
  glColor4fv(couleurBlanc()) ;
  glPushMatrix();
  glTranslatef((b.pi.x+b.pf.x)/2,(b.pi.y+b.pf.y)/2,(b.pi.z+b.pf.z)/2) ;
  glScalef(b.pi.x-b.pf.x,b.pi.y-b.pf.y,b.pi.z-b.pf.z) ;
  glutWireCube(1.0F);
  glPopMatrix();
  glColor4fv(couleurRouge()) ;
  for ( int i = 0 ; i < 5 ; i++ )
    if ( clip ) {
      clipping(&s[i],&b) ; }
      else {
      glBegin(GL_LINES) ;
      glVertex3f(s[i].pi.x,s[i].pi.y,s[i].pi.z) ;
      glVertex3f(s[i].pf.x,s[i].pf.y,s[i].pf.z) ;
      glEnd() ; }
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
}

void myinit (void) {
  glShadeModel(GL_SMOOTH);
  glEnable(GL_DEPTH_TEST);
}

void key(unsigned char key,int x,int y) {
  if ( keyManipulateur(key,x,y) )
    glutPostRedisplay();
    else
    switch ( key ) {
      case ' '   : clip = 1-clip ;
                   glutPostRedisplay();
                   break;
      case 'a'   : b.pi.x += 0.05F ;
                   glutPostRedisplay();
                   break;
      case 'A'   : b.pi.x -= 0.1F ;
                   glutPostRedisplay();
                   break;
      case 'q'   : b.pf.x += 0.1F ;
                   glutPostRedisplay();
                   break;
      case 'Q'   : b.pf.x -= 0.1F ;
                   glutPostRedisplay();
                   break;
      case 'z'   : b.pi.y += 0.1F ;
                   glutPostRedisplay();
                   break;
      case 'Z'   : b.pi.y -= 0.1F ;
                   glutPostRedisplay();
                   break;
      case 's'   : b.pf.y += 0.1F ;
                   glutPostRedisplay();
                   break;
      case 'S'   : b.pf.y -= 0.1F ;
                   glutPostRedisplay();
                   break;
      case 'e'   : b.pi.z += 0.1F ;
                   glutPostRedisplay();
                   break;
      case 'E'   : b.pi.z -= 0.1F ;
                   glutPostRedisplay();
                   break;
      case 'd'   : b.pf.z += 0.1F ;
                   glutPostRedisplay();
                   break;
      case 'D'   : b.pf.z -= 0.1F ;
                   glutPostRedisplay();
                   break; }
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(300,300); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Clipping 3D"); 
  myinit(); 
  creationMenuBasique();
  setParametresOrthoBasique(-10.0,10.0,-10.0,10.0,-500.0,500.0);
  setManipulateurDistance(1.0F);
  glutReshapeFunc(reshapeOrthoBasique);
  glutKeyboardFunc(key);
  glutSpecialFunc(specialBasique);
  glutMotionFunc(motionBasique);
  glutMouseFunc(sourisBasique);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

Les modules utilitaires : Modules.zip

RETOUR