ProjectionParalleleOrthographique.h

/* Mathematiques de l'informatique graphique    */
/* Transformation de visualisation              */
/* en projection parallele orthographique       */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Octobre 2011                                 */

#ifndef ____PROJECTIONPARALLELEORTHOGRAPHIQUE____
#define ____PROJECTIONPARALLELEORTHOGRAPHIQUE____

class Position3D;

#include "TransformationGeometrique.h"

class ProjectionParalleleOrthographique : public TransformationGeometrique {

  public :
    ProjectionParalleleOrthographique(Position3D *po,Position3D *pv);
    ~ProjectionParalleleOrthographique(void);
};

#endif

ProjectionParalleleOrthographique.cpp

/* Mathematiques de l'informatique graphique    */
/* Transformation de visualisation              */
/* en projection parallele orthographique       */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Octobre 2011                                 */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "TransformationGeometrique.h"
#include "ProjectionParalleleOrthographique.h"
#include "Position3D.h"
#include "Direction3D.h"

ProjectionParalleleOrthographique::ProjectionParalleleOrthographique(Position3D *po,Position3D *pv):TransformationGeometrique() {
  Direction3D n(po,pv);
  n.normalisation();
  double a = 1.0/sqrt(1.0-n.c[1]*n.c[1]);
  c[0][0] = -a*n.c[2];
  c[0][1] = 0.0;
  c[0][2] = a*n.c[0];
  c[0][3] = a*(po->c[0]*n.c[2]-po->c[2]*n.c[0]);
  c[1][0] = -a*n.c[0]*n.c[1];
  c[1][1] = 1.0/a;
  c[1][2] = -a*n.c[1]*n.c[2];
  c[1][3] = a*n.c[1]*(po->c[0]*n.c[0]+po->c[2]*n.c[2])-po->c[1]/a;
  c[2][0] = -n.c[0];
  c[2][1] = -n.c[1];
  c[2][2] = -n.c[2];
  c[2][3] = po->c[0]*n.c[0]+po->c[1]*n.c[1]+po->c[2]*n.c[2];
}

ProjectionParalleleOrthographique::~ProjectionParalleleOrthographique(void) {
}

ProjectionPerspective.h

/* Mathematiques de l'informatique graphique    */
/* Transformation de visualisation              */
/* en perspective                               */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Octobre 2011                                 */

#ifndef ____PROJECTIONPERSPECTIVE____
#define ____PROJECTIONPERSPECTIVE____

class Position3D;

#include "TransformationGeometrique.h"

class ProjectionPerspective : public TransformationGeometrique {

  public :
    ProjectionPerspective(Position3D *po,Position3D *pv,double d);
    ~ProjectionPerspective(void);
    virtual void transforme(CoordonneesHomogenes *ch);
};

#endif

ProjectionPerspective.cpp

/* Mathematiques de l'informatique graphique    */
/* Transformation de visualisation              */
/* en perspective                               */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Octobre 2011                                 */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "TransformationGeometrique.h"
#include "ProjectionPerspective.h"
#include "Position3D.h"
#include "Direction3D.h"

ProjectionPerspective::ProjectionPerspective(Position3D *po,Position3D *pv,double d):TransformationGeometrique() {
  Direction3D n(po,pv);
  n.normalisation();
  double a = 1.0/sqrt(1.0-n.c[1]*n.c[1]);
  c[0][0] = -a*n.c[2];
  c[0][1] = 0.0;
  c[0][2] = a*n.c[0];
  c[0][3] = a*(po->c[0]*n.c[2]-po->c[2]*n.c[0]);
  c[1][0] = -a*n.c[0]*n.c[1];
  c[1][1] = 1.0/a;
  c[1][2] = -a*n.c[1]*n.c[2];
  c[1][3] = a*n.c[1]*(po->c[0]*n.c[0]+po->c[2]*n.c[2])-po->c[1]/a;
  c[2][0] = -n.c[0];
  c[2][1] = -n.c[1];
  c[2][2] = -n.c[2];
  c[2][3] = po->c[0]*n.c[0]+po->c[1]*n.c[1]+po->c[2]*n.c[2];
  c[3][0] = c[2][0]/d;
  c[3][1] = c[2][1]/d;
  c[3][2] = c[2][2]/d;
  c[3][3] = c[2][3]/d;
}

ProjectionPerspective::~ProjectionPerspective(void) {
}

void ProjectionPerspective::transforme(CoordonneesHomogenes *ch) {
  TransformationGeometrique::transforme(ch);
  ch->c[0] /= ch->c[3];
  ch->c[1] /= ch->c[3];
}

MathematiquesVisualisation.cpp

/* Implantation mathematique             */
/* des transformations geometriques      */
/* de visualisation                      */
/*                                       */
/* Auteur: Nicolas JANEY                 */
/* nicolas.janey@univ-fcomte.fr          */
/* Octobre 2011                          */

#include <stdio.h>
#include <stdlib.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include "Position3D.h"
#include "Rotation.h"
#include "Scale.h"
#include "ProjectionParalleleOrthographique.h"
#include "ProjectionPerspective.h"

/* Variables et constantes globales             */
/* pour les angles et les couleurs utilises     */

static int f1;
static int aff = 0;

static float rx = 0.0F;
static float ry = 0.0F;
static float rz = 0.0F;

static Position3D po1(3.0,0.8,9.0);
static Position3D po2(2.0,0.8,3.0);
static Position3D pv(1.0,0.0,1.0);
static double ouvertureVerticaleOrtho = 2.0;
static double positionEcranPerspective = -5.0;

/* Fonction de dessin les axes                  */

void axes(TransformationGeometrique *tv) {
  float crd[4][3] = { {  0.0F, 0.0F, 0.0F },
                      {  1.0F, 0.0F, 0.0F },
                      {  0.0F, 1.0F, 0.0F },
                      {  0.0F, 0.0F, 1.0F } };
  double zoom = 1.0/ouvertureVerticaleOrtho;
  Position3D pts[4];
  for ( int i = 0 ; i < 4 ; i++ ) {
    pts[i].c[0] = crd[i][0];
    pts[i].c[1] = crd[i][1];
    pts[i].c[2] = crd[i][2];
    pts[i].c[3] = 1.0F;
    tv->transforme(&pts[i]); }
  glBegin(GL_LINES);
  glColor3f(1.0F,1.0F,0.0F);
  glVertex3dv((double *) &pts[0]);
  glVertex3dv((double *) &pts[1]);
  glColor3f(0.0F,1.0F,1.0F);
  glVertex3dv((double *) &pts[0]);
  glVertex3dv((double *) &pts[2]);
  glColor3f(1.0F,0.0F,1.0F);
  glVertex3dv((double *) &pts[0]);
  glVertex3dv((double *) &pts[3]);
  glEnd();
}

/* Fonction de dessin dun cube en fil de fer    */

void cube(TransformationGeometrique *tv) {
  float crd[8][3] = { {  1.0F, 1.0F, 1.0F },
                      {  1.0F,-1.0F, 1.0F },
                      { -1.0F,-1.0F, 1.0F },
                      { -1.0F, 1.0F, 1.0F },
                      {  1.0F, 1.0F,-1.0F },
                      {  1.0F,-1.0F,-1.0F },
                      { -1.0F,-1.0F,-1.0F },
                      { -1.0F, 1.0F,-1.0F } };
  Position3D pts[8];
  for ( int i = 0 ; i < 8 ; i++ ) {
    pts[i].c[0] = crd[i][0];
    pts[i].c[1] = crd[i][1];
    pts[i].c[2] = crd[i][2];
    pts[i].c[3] = 1.0F;
    tv->transforme(&pts[i]); }
  glColor3f(1.0F,1.0F,1.0F);
  glBegin(GL_LINES);
  glVertex3dv((double *) &pts[0]);
  glVertex3dv((double *) &pts[1]);
  glVertex3dv((double *) &pts[1]);
  glVertex3dv((double *) &pts[2]);
  glVertex3dv((double *) &pts[2]);
  glVertex3dv((double *) &pts[3]);
  glVertex3dv((double *) &pts[3]);
  glVertex3dv((double *) &pts[0]);
  glVertex3dv((double *) &pts[4]);
  glVertex3dv((double *) &pts[5]);
  glVertex3dv((double *) &pts[5]);
  glVertex3dv((double *) &pts[6]);
  glVertex3dv((double *) &pts[6]);
  glVertex3dv((double *) &pts[7]);
  glVertex3dv((double *) &pts[7]);
  glVertex3dv((double *) &pts[4]);
  glVertex3dv((double *) &pts[0]);
  glVertex3dv((double *) &pts[4]);
  glVertex3dv((double *) &pts[1]);
  glVertex3dv((double *) &pts[5]);
  glVertex3dv((double *) &pts[2]);
  glVertex3dv((double *) &pts[6]);
  glVertex3dv((double *) &pts[3]);
  glVertex3dv((double *) &pts[7]);
  glEnd();
}

static void postRedisplay(void) {
  glutPostWindowRedisplay(f1);
}

/* Fonction executee lors d'un changement       */
/* de la taille de la fenetre (1)               */

void reshape(int w,int h) {
  glViewport(0,0,w,h); 
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-1.0F,1.0,(float) -h/w,(float) h/w,-50.0,50.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin (1)                  */

void display() {
  glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  glPushMatrix();
  Rotation rtx(rx,1.0,0.0,0.0);
  Rotation rty(ry,0.0,1.0,0.0);
  Rotation rtz(rz,0.0,0.0,1.0);
  rtx.produit(&rty,&rtx);
  rtx.produit(&rtz,&rtx);
  Position3D pointVise(&pv);
  rtx.transforme(&pointVise);
  TransformationGeometrique *tv;
  switch (aff) {
    case 0 :
      { Position3D observateur(&po1);
        rtx.transforme(&observateur);
        observateur.print();
        ProjectionParalleleOrthographique *ppo;
        ppo = new ProjectionParalleleOrthographique(&observateur,
                                                    &pointVise);
        { double zoom = 1.0/ouvertureVerticaleOrtho;
          Scale sc(zoom,zoom,1.0);
          ppo->produit(&sc,ppo); }
        tv = ppo; }
      break;
    case 1 :
      { Position3D observateur(&po1);
        rtx.transforme(&observateur);
        observateur.print();
        ProjectionPerspective *pp;
        pp = new ProjectionPerspective(&observateur,
                                       &pointVise,
                                       positionEcranPerspective);
        tv = pp; }
      break;
    case 2 :
      { Position3D observateur(&po2);
        rtx.transforme(&observateur);
        observateur.print();
        ProjectionPerspective *pp;
        pp = new ProjectionPerspective(&observateur,
                                       &pointVise,
                                       positionEcranPerspective/3.0);
        tv = pp; }
      break; }
  cube(tv) ;
  axes(tv) ;
  delete(tv);
  glPopMatrix();
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Erreur OpenGL: %d\n",error);
  printf(" - ");
  pointVise.print();
  printf("\n");
}

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

/* Fonction executee lors de la frappe          */
/* d'une touche special du clavier:             */
/* - touches de curseur                         */
/* - touches de fonction                        */
/* - ...                                        */

void special(int code,int x,int y) {
  switch ( code ) {
    case GLUT_KEY_UP :
      rx += 1.0F;
      postRedisplay(); 
      break;
    case GLUT_KEY_DOWN :
      rx -= 1.0F;
      postRedisplay(); 
      break;
    case GLUT_KEY_RIGHT :
      ry += 1.0F;
      postRedisplay(); 
      break;
    case GLUT_KEY_LEFT :
      ry -= 1.0F;
      postRedisplay(); 
      break;
    case GLUT_KEY_PAGE_UP :
      rz += 1.0F;
      postRedisplay(); 
      break;
    case GLUT_KEY_PAGE_DOWN :
      rz -= 1.0F;
      postRedisplay(); 
      break; }
}

/* Fonction executee lorsqu'aucun evenement     */
/* n'est en file d'attente                      */

void idle(void) {
  rx += 0.03355F;
  ry += 0.06117F;
  rz += 0.04174F;
  postRedisplay();
}

/* Fonction executee lors de l'appui            */
/* d'une touche alphanumerique du clavier       */

void keyboard(unsigned char key,int x,int y) {
  switch (key) {
    case 'r' :
      rx = 0.0F;
      ry = 0.0F;
      rz = 0.0F;
      postRedisplay();
      break;
    case 0x20 :
      aff = (aff+1)%3;
      postRedisplay();
      break;
    case 0x0D :
      { static int anim = 0;
        anim = !anim;
        glutIdleFunc(( anim ) ? idle : NULL); }
      break;
    case 0x1B :
      exit(0);
      break; }
}

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitWindowSize(300,300);
  glutInitWindowPosition(50,50);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  f1 = glutCreateWindow("Mathematiques pour la visualisation");
  myinit();
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutKeyboardFunc(keyboard);
  glutSpecialFunc(special);
  glutMainLoop();
  return(0);
}

TD n°6 pour les classes CoordonneesHomogenes, Position3D et Direction3D

TD n°7 pour les classes TransformationGeometrique, Translation et Rotation

Scale.h

Scale.cpp

RETOUR