Affichage graphique de courbes [g++][linux]

Contenu du snippet

A partir d'un fichier contenant le nombre de courbes à afficher et les coordonnées des points, le programme affiche les courbes avec une régression de type Callmut Rom.

Source / Exemple :


#include <iostream>
#include <GL/glut.h>

#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

#include <cmath>
#include <list>
#include <vector>

#define BUFFER_SIZE 128

#define SCR_X 640
#define SCR_Y 480

struct point
{
  float x;
  float y;
     
  point(float _x = 0, float _y = 0): x(_x), y(_y) { }
  point(const point & _which)
  {
    x = _which.x;
    y = _which.y;
  }
  ~point() {}

  point & operator = (const point & _which)
  {
    x = _which.x;
    y = _which.y;
    return *this;
  }
};

//==================================================================================================

class point_list
{
public:
  point_list() {}
  point_list(const point_list & _which)
  {
    list = _which.list;
  }
  ~point_list()
  {
    for (unsigned int i = 0; i<list.size(); i++) delete list[i];
  }

  point & get_point(int which)
  {
    std::vector<point*>::iterator _it = list.begin();
    for (int i = 0; i < which; i++) _it++;
    return **_it;
  }    

  void add_point(point * _which)
  {
    list.push_back(_which);
  }
  
  std::vector<point*> list;
};

//==================================================================================================

// COURBE Catmul-rom 

//P est un point du plan. Et Px le point de controle d'indice x.
//P(t) = 1/2 * [ t^3,t^2,t,1 ] * [ -1  3 -3  1  ] * [ Pi-3 ]
//                               [  2 -5  4 -1  ]   [ Pi-2 ]
//                               [ -1  0  1  0  ]   [ Pi-1 ]
//                               [  0  2  0  0  ]   [ Pi   ]

class cat_curve
{
public:
  cat_curve(const point_list & _which)
  {
    plist = new point_list(_which);
    curve_point = NULL;
    nb_curve_point = 0;
    nb_point = plist->list.size();
    precision = 100;
    //draw_number = true;
  }
  cat_curve(const cat_curve & _which) // non testé
  {
    plist = new point_list(*_which.plist);
    nb_curve_point = _which.nb_curve_point;
    nb_point = _which.nb_point;
    precision = _which.precision;
    if (_which.curve_point != NULL)
      {
	curve_point = new point[_which.nb_curve_point];
	for (int i=0; i<_which.nb_curve_point ; i++) curve_point[i] = _which.curve_point[i];
      }
    else curve_point = NULL;
  }
  ~cat_curve()
  {
    if (curve_point != NULL) delete[] curve_point;
  }

  void compute()
  {
    if (curve_point != NULL) delete[] curve_point;
    curve_point = new point[precision+1];
    nb_curve_point = precision+1;

    float t=1, p = (float)(nb_point-3)/(float)precision;

    int i;
    float ti;
    for(int k=0; k<nb_curve_point; k++)
      {
	i = (int)floor(t);
	ti = (float)i;
	if (i!= nb_point-2)
	  {
	    curve_point[k].x = (3*plist->list[i]->x-3*plist->list[i+1]->x+plist->list[i+2]->x-plist->list[i-1]->x)*pow(t-ti,3)/2+( 2*plist->list[i-1]->x - 5*plist->list[i]->x + 4*plist->list[i+1]->x - plist->list[i+2]->x)*pow(t-ti,2)/2+ ( plist->list[i+1]->x - plist->list[i-1]->x ) *(t-ti)/2 + plist->list[i]->x;

	    curve_point[k].y = (3*plist->list[i]->y-3*plist->list[i+1]->y+plist->list[i+2]->y-plist->list[i-1]->y)*pow(t-ti,3)/2+( 2*plist->list[i-1]->y - 5*plist->list[i]->y + 4*plist->list[i+1]->y - plist->list[i+2]->y)*pow(t-ti,2)/2+( plist->list[i+1]->y - plist->list[i-1]->y ) *(t-ti)/2 + plist->list[i]->y;
	  }
	else
	  {
	    curve_point[k].x = plist->list[i]->x;
	    curve_point[k].y = plist->list[i]->y;
	  }

	t += p;
      }
  }

  void draw() const
  {
    glColor3f(1,0,0);
    glBegin(GL_LINE_STRIP);
    for (int i=0 ; i<nb_curve_point ; i++)
      glVertex2f(curve_point[i].x, curve_point[i].y);
      glEnd();

  }

  point * curve_point;
  int nb_curve_point;
  
  point_list * plist;
  int nb_point;

  int precision;
};

//==============================================================================

// Déclaration des variables globales
// Avec Glut, on a pas trop le choix
int nb_iso;

point_list pt_list[100];

cat_curve * c_curve[100];

bool show_cat = true;

void reshape(int w, int h)
{
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
     glMatrixMode(GL_MODELVIEW);
}

void display()
{
     glClear(GL_COLOR_BUFFER_BIT);

	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glBegin(GL_POLYGON);
	glColor3f(0,0,0);
	glVertex2f(20,90);
	glColor3f(0,0,0);
	glVertex2f(620,90);
	glColor3f(0,0,0);
	glVertex2f(620,390);
	glColor3f(0,0,0);
	glVertex2f(20,390);
	glEnd();

     if (show_cat)
     {
     	int i=0;
     	for(i=0;i<nb_iso;i++)
	{
		c_curve[i]->draw();
	}
      }

     GLint viewport[4];

     glGetIntegerv(GL_VIEWPORT, viewport);

     glutSwapBuffers();
     glFlush();
}

void Idle()
{
  // pour éviter d'avoir un CPU 100%, on limite le fps à 50
#ifdef WIN32
  Sleep(20);
#else
  usleep(20000);
#endif
}

int main(int argc, char *argv[])
{
		FILE *Fichier;
		Fichier=fopen("Temp.txt", "r");
		if(Fichier==NULL)
		{
			std::cout <<"Erreur, pas de fichier ouvert\n";
		}
		else
		{
			fscanf(Fichier, "%d", &nb_iso);
		}
		fclose(Fichier);
		
	int i=0, c, j=0, nb_pt;

	nb_pt=0;
	
	FILE * fic;
	fic=fopen("Temp.txt", "r");
	
	while(!feof(fic))
	{
		c=fgetc(fic);
		if(c=='\n')
		{
			++nb_pt;
		}
	}
	fclose(fic);
	nb_pt=nb_pt+1;
		
		float d=0;
		float T[nb_pt][2*nb_iso];
		FILE *MonFichier;
		MonFichier=fopen("Temp.txt", "r");
		if(MonFichier==NULL)
		{
			std::cout <<"Erreur, pas de fichier ouvert\n";
		}
		else
		{
			fscanf(MonFichier, "%f", &d);
			for (i=1;i<nb_pt-1;i++)
			{
				for(j=0;j<2*nb_iso;j++)
				{
					fscanf(MonFichier, "%f", &d);
					T[i][j]=d;
				}
			}
		}
		fclose(MonFichier);
		
		for(i=1;i<nb_pt-1;i++)
		{
			for(j=0;j<nb_iso;j++)
			{
				T[i][2*j]=600*T[i][2*j]+20;
				T[i][2*j+1]=600*T[i][2*j+1]+90;
			}
		}
		
		for(j=0;j<nb_iso;j++)
		{
			T[0][2*j]=T[1][2*j];
			T[0][2*j+1]=0;
			T[nb_pt-1][2*j]=T[nb_pt-2][2*j];
			T[nb_pt-1][2*j+1]=480;
		}

			for(j=0;j<nb_iso;j++)
			{
				for(i=0;i<nb_pt;i++)
				{		
					pt_list[j].add_point(new point(T[i][2*j],T[i][2*j+1]));
				}

	    			c_curve[j] = new cat_curve(pt_list[j]);
				c_curve[j]->compute();
			}

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(SCR_X,SCR_Y);
    glutInitWindowPosition(100,100);
    glutCreateWindow("Isothermes");
    
    // initialisation d'openGL

    glClearColor(1.0, 1.0, 1.0, 0.0);
    
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND);
    glEnable(GL_COLOR);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glPointSize(4.0);
    
    // fonction callback de GLUT

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(Idle);

    glutMainLoop();
    
    return 0;
}

Conclusion :


Merci à luthor, j'ai juste modifié son code.

Ce bout de code fait parti d'un projet qui sera sur code source d'ici deux mois je pense.

Si il y a des modif intéressantes à faire, mettez des commentaires. J'ai mis ce code ici avant la fin du projet pour ça! Merci!

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.