CoordonneesHomogenes.h - CoordonneesHomogenes.cpp - Position3D.h - Position3D.cpp
/* Implantation mathematique */
/* du calcul d'une courbe de Bezier */
/* */
/* Auteur: Nicolas JANEY */
/* nicolas.janey@univ-fcomte.fr */
/* Novembre 2011 */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "Position3D.h"
/* Variables et constantes globales */
/* pour les angles et les couleurs utilises */
static int f1;
static int aff = 1;
static int n = 20;
static int m = 500;
static float rx = 10.0F;
static float ry = 30.0F;
static float rz = 10.0F;
static Position3D *ptCtrl1[21] = {
new Position3D( 5.0, -10.0, 5.0),
new Position3D(-5.0, -9.1, 5.0),
new Position3D(-5.0, -7.8, -5.0),
new Position3D( 5.0, -7.2, -5.0),
new Position3D( 5.0, -5.8, 5.0),
new Position3D(-5.0, -5.1, 5.0),
new Position3D(-5.0, -4.0, -5.0),
new Position3D( 5.0, -3.2, -5.0),
new Position3D( 5.0, -1.7, 5.0),
new Position3D(-5.0, -1.4, 5.0),
new Position3D(-5.0, 0.0, -5.0),
new Position3D( 5.0, 1.2, -5.0),
new Position3D( 5.0, 2.0, 5.0),
new Position3D(-5.0, 3.1, 5.0),
new Position3D(-5.0, 4.3, -5.0),
new Position3D( 5.0, 4.7, -5.0),
new Position3D( 5.0, 6.2, 5.0),
new Position3D(-5.0, 7.1, 5.0),
new Position3D(-5.0, 8.1, -5.0),
new Position3D( 5.0, 9.3, -5.0),
new Position3D( 5.0, 10.0, 5.0) };
static Position3D *ptCtrl2[21] = {
new Position3D( 5.0, -10.0, 5.0),
new Position3D(-5.0, -9.1, 5.0),
new Position3D(-5.0, -7.2,-15.0),
new Position3D( 5.0, -7.8,-15.0),
new Position3D(15.0, -5.1, 5.0),
new Position3D(-5.0, -5.8, 5.0),
new Position3D(-5.0, -4.0, -5.0),
new Position3D( 5.0, -3.2, -5.0),
new Position3D( 5.0, -1.7, 15.0),
new Position3D(-5.0, -1.4, 5.0),
new Position3D(-5.0, 0.0, -5.0),
new Position3D( 5.0, 1.2, -5.0),
new Position3D(15.0, 2.0, 15.0),
new Position3D(-5.0, 4.1, 5.0),
new Position3D(-5.0, 3.3,-15.0),
new Position3D( 5.0, 4.7, -5.0),
new Position3D(15.0, 7.2, 5.0),
new Position3D(-5.0, 6.1, 15.0),
new Position3D(-5.0, 8.1, -5.0),
new Position3D( 5.0, 9.3, -5.0),
new Position3D( 5.0, 10.0, 5.0) };
static Position3D **ptCtrl = ptCtrl1;
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(-14.0F,14.0,(float) h/w*-14.0,(float) h/w*14.0,-50.0,50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin (1) */
long long factoriel(int n) {
if ( n == 0 )
return(1L);
else
return(n*factoriel(n-1));
}
long long c(int i,int n) {
return(factoriel(n)/factoriel(i)/factoriel(n-i));
}
double power(double x,double y) {
if ( ( x == 0.0 ) && ( y == 0 ) )
return(1.0);
else
return(pow(x,y));
}
void bezier(Position3D **ptCtrl,int n,int m,Position3D **b) {
for ( int j = 0 ; j < m ; j++ ) {
double t =(double) j/(m-1);
b[j]->c[0] = b[j]->c[1] = b[j]->c[2] = 0.0;
b[j]->c[3] = 1.0;
for ( int i = 0 ; i <= n ; i++ ) {
long long v = c(i,n);
double v1 = power(t,i);
double v2 = power(1.0-t,n-i);
b[j]->c[0] += v*v1*v2*ptCtrl[i]->c[0];
b[j]->c[1] += v*v1*v2*ptCtrl[i]->c[1];
b[j]->c[2] += v*v1*v2*ptCtrl[i]->c[2]; } }
}
void display() {
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(rz,0.0F,0.0F,1.0F);
glRotatef(ry,0.0F,1.0F,0.0F);
glRotatef(rx,1.0F,0.0F,0.0F);
glColor3f(1.0F,0.0F,0.0F);
glPointSize(3.0F);
glBegin(GL_LINE_STRIP);
for ( int i = 0 ; i <= n ; i++ )
glVertex3d(ptCtrl[i]->c[0],ptCtrl[i]->c[1],ptCtrl[i]->c[2]);
glEnd();
Position3D **b =(Position3D **) calloc(m,sizeof(Position3D *));
for ( int i = 0 ; i < m ; i++ )
b[i] = new Position3D();
bezier(ptCtrl,n,m,b);
glColor3f(1.0F,1.0F,0.0F);
glPointSize(1.0F);
glBegin(GL_POINTS);
for ( int i = 0 ; i < m ; i++ )
glVertex3d(b[i]->c[0],b[i]->c[1],b[i]->c[2]);
glEnd();
for ( int i = 0 ; i < m ; i++ )
delete(b[i]);
free(b);
glPopMatrix();
glutSwapBuffers();
int error = glGetError();
if ( error != GL_NO_ERROR )
printf("Erreur OpenGL: %d\n",error);
}
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.13355F;
ry += 0.06117F;
rz += 0.24174F;
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)%2;
if ( aff )
ptCtrl = ptCtrl1;
else
ptCtrl = ptCtrl2;
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(400,400);
glutInitWindowPosition(50,50);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
f1 = glutCreateWindow("Courbe de Bezier");
myinit();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutMainLoop();
return(0);
}