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

Soyez le premier à donner votre avis sur cette source.

Snippet vu 9 689 fois - Téléchargée 31 fois

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

Ajouter un commentaire

Commentaire

luhtor
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
4 -
Quand je revois mon code, je me rend compte qu'il faudrait apporter quelques corrections.
Deja, le constructeur de copie de la class point_list est correct, mais dangeureux, donc faudrait mieux le supprimer et le mettre en private.

Pour ton utilisation a toi, comme tu ne déplaces pas les points pendant le programme, tu pourrais remplacer le vector par vector et rétablir le constructeur de copie. Mais moi j'avais besoin qu'un point soit dans un objet point_list et cat_curve. Donc si tu faisais cette modification, il faudrait supprimer ce qu'il y a dans le constructeur, ce qui d'ailleurs était très moyen :) La classe supprime en effet des objets qu'elle n'a pas créé.
Mais tout ca reste de l'ordre de la suggestion :)

Bye.

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.