DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Grafos En 3d

09.22.2006
| 4752 views |
  • submit to reddit
        Implementacion con opengl de la visualizacion de grafos, donde los vertices son resortes uniendo los nodos, y los nodos se rechazan entre ellos, y existe una fuerza en el origen que los acerca a todos.

Makefile para compilarlo:


INCLUDE = -I/usr/include/ 
LIBDIR  = -L/usr/X11R6/lib

CC = gcc
CCFLAGS = -g ${INCLUDE}
LIBRARY = -lX11 -lXi -lXmu -lglut -lGL -lGLU -lm

all :ejemplo1.o
	${CC} ${CCFLAGS} -o ejemplo1 ejemplo1.o ${LIBDIR} ${LIBRARY}

clean :
	rm -rf ejemplo1 ejemplo1.o



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

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

#define MAXNODOS 100

typedef struct _point{
	float x,y,z;
} point;

typedef struct _force{
	float fx,fy,fz;
} force;

typedef struct _sisi{
	point p;
	force f;
} sisi;

typedef struct _grafo{
	int nnodos;
	sisi nodos[100];
	int enlaces[100][100];
	point max,min;	
} grafo;

float angulo=0.0;
grafo grafo_global;

void calcularfuerzas(grafo *g){
	int i,j;
	float distancia;
	for (i=0;i<g->nnodos;i++){
		g->nodos[i].f.fx = 0.0f;
		g->nodos[i].f.fy = 0.0f;
		g->nodos[i].f.fz = 0.0f;
		
		for (j=0;j<g->nnodos;j++){
			if (i!=j && g->enlaces[i][j]==1){
				distancia = sqrt(powf(g->nodos[i].p.x - g->nodos[j].p.x,2.0f) + powf(g->nodos[i].p.y - g->nodos[j].p.y,2.0f) + powf(g->nodos[i].p.z - g->nodos[j].p.z,2.0f));
				if ( distancia > 0.001f ){
					g->nodos[i].f.fx += (g->nodos[i].p.x - g->nodos[j].p.x) / powf(distancia,3.0f);
					g->nodos[i].f.fy += (g->nodos[i].p.y - g->nodos[j].p.y) / powf(distancia,3.0f);
					g->nodos[i].f.fz += (g->nodos[i].p.z - g->nodos[j].p.z) / powf(distancia,3.0f);
				}
			}
		}
//		Nene

		distancia = sqrt(powf(g->nodos[i].p.x,2.0f)+powf(g->nodos[i].p.y,2.0f)+powf(g->nodos[i].p.z,2.0f));

		if (distancia>(float)g->nnodos){
			g->nodos[i].f.fx -= g->nnodos*g->nodos[i].p.x/powf(distancia,3.0f);
			g->nodos[i].f.fy -= g->nnodos*g->nodos[i].p.y/powf(distancia,3.0f);
			g->nodos[i].f.fz -= g->nnodos*g->nodos[i].p.z/powf(distancia,3.0f);				
		}

	}
	
	grafo_global.max.x=-1000;
	grafo_global.max.y=-1000;
	grafo_global.max.z=-1000;
	grafo_global.min.x=1000;
	grafo_global.min.y=1000;
	grafo_global.min.z=1000;		

	for (i=0;i<g->nnodos;i++){	
//		Movimiento
		g->nodos[i].p.x+=g->nodos[i].f.fx;
		g->nodos[i].p.y+=g->nodos[i].f.fy;
		g->nodos[i].p.z+=g->nodos[i].f.fz;		

		if (grafo_global.max.x<grafo_global.nodos[i].p.x)
			grafo_global.max.x=grafo_global.nodos[i].p.x;	

		if (grafo_global.max.y<grafo_global.nodos[i].p.y)
			grafo_global.max.y=grafo_global.nodos[i].p.y;	

		if (grafo_global.max.z<grafo_global.nodos[i].p.z)
			grafo_global.max.z=grafo_global.nodos[i].p.z;	

		if (grafo_global.min.x>grafo_global.nodos[i].p.x)
			grafo_global.min.x=grafo_global.nodos[i].p.x;	

		if (grafo_global.min.y>grafo_global.nodos[i].p.y)
			grafo_global.min.y=grafo_global.nodos[i].p.y;	

		if (grafo_global.min.z>grafo_global.nodos[i].p.z)
			grafo_global.min.z=grafo_global.nodos[i].p.z;	
	}
	
}

void init_grafo(void){
	int i,j;
	grafo_global.nnodos=30;

	for (i=0;i<grafo_global.nnodos;i++){
		for (j=0;j<grafo_global.nnodos;j++){
			grafo_global.enlaces[i][j]=1;
		}
		grafo_global.nodos[i].p.x=rand()%10;
		grafo_global.nodos[i].p.y=rand()%10;
		grafo_global.nodos[i].p.z=rand()%10;

	}

//	grafo_global.enlaces[0][1]=0;
//	grafo_global.enlaces[1][0]=0;

	grafo_global.nodos[0].p.x=5;
	grafo_global.nodos[0].p.y=1;
	grafo_global.nodos[0].p.z=5;		

	grafo_global.nodos[1].p.x=2;
	grafo_global.nodos[1].p.y=2;
	grafo_global.nodos[1].p.z=2;		

	grafo_global.nodos[2].p.x=2;
	grafo_global.nodos[2].p.y=2;
	grafo_global.nodos[2].p.z=3;		

	grafo_global.nodos[3].p.x=3;
	grafo_global.nodos[3].p.y=6;
	grafo_global.nodos[3].p.z=6;		


	grafo_global.nodos[4].p.x=5;
	grafo_global.nodos[4].p.y=-5;
	grafo_global.nodos[4].p.z=5;		

	grafo_global.nodos[5].p.x=-2;
	grafo_global.nodos[5].p.y=2;
	grafo_global.nodos[5].p.z=2;		

	grafo_global.nodos[6].p.x=2;
	grafo_global.nodos[6].p.y=2;
	grafo_global.nodos[6].p.z=-3;		

	grafo_global.nodos[7].p.x=3;
	grafo_global.nodos[7].p.y=8;
	grafo_global.nodos[7].p.z=6;		


	grafo_global.max.x=grafo_global.nodos[0].p.x;
	grafo_global.max.y=grafo_global.nodos[0].p.y;
	grafo_global.max.z=grafo_global.nodos[0].p.z;
	grafo_global.min.x=grafo_global.nodos[0].p.x;
	grafo_global.min.y=grafo_global.nodos[0].p.y;
	grafo_global.min.z=grafo_global.nodos[0].p.z;		


}

void init(void) 
{
   glClearColor (1.0, 1.0, 1.0, 0.0);
   glShadeModel (GL_FLAT);
}

void display(void)
{
   glClear (GL_COLOR_BUFFER_BIT);
   glColor3f (0, 0, 0);
   glLoadIdentity();
   gluLookAt (0.0, 0.0, 15.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
   glRotatef(angulo,0,1.0,0);

	float dx,dy,dz;
	
	dx = grafo_global.max.x - grafo_global.min.x;
	dy = grafo_global.max.y - grafo_global.min.y;
	dz = grafo_global.max.z - grafo_global.min.z;	
	
//   glutWireCube (1.0);
//   glScalef (10.0/dx, 10.0/dy, 10.0/dz);
	if (dx>dy && dx >dz){

		glScalef(10.0/dx,10.0/dx,10.0/dx);
		glutWireCube (dx);
//	glTranslatef(dx/2.0f,dx/2.0f,dx/2.0f);
	} else if (dy>dx && dy >dz){

		glScalef(10.0/dy,10.0/dy,10.0/dy);
		glutWireCube (dy);
//			glTranslatef(dy/2.0f,dy/2.0f,dy/2.0f);
	} else if (dz>dx && dz >dy){

		glScalef(10.0/dz,10.0/dz,10.0/dz);		
		glutWireCube (dz);
//			glTranslatef(dz/2.0f,dz/2.0f,dz/2.0f);
	}

	
	int cont,cont2;
	for (cont=0;cont<grafo_global.nnodos;cont++){
		glPushMatrix();
		glTranslatef(grafo_global.nodos[cont].p.x, grafo_global.nodos[cont].p.y, grafo_global.nodos[cont].p.z);
		glutSolidSphere(.2, 32, 32);
		glPopMatrix();
		for (cont2=cont;cont2<grafo_global.nnodos;cont2++){
			if (grafo_global.enlaces[cont][cont2]){
				glBegin(GL_LINES);
				glVertex3f(grafo_global.nodos[cont].p.x,grafo_global.nodos[cont].p.y,grafo_global.nodos[cont].p.z);
				glVertex3f(grafo_global.nodos[cont2].p.x,grafo_global.nodos[cont2].p.y,grafo_global.nodos[cont2].p.z);				
				glEnd();				
			}
		}
	}



   glFlush ();
   glutSwapBuffers();
}

void reshape(int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 25.0);
   glMatrixMode (GL_MODELVIEW); 
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
   }
}

void idle(void){

	static int timelast=0;
	int time;
	time = glutGet(GLUT_ELAPSED_TIME);
	if (time-timelast>10){
		timelast=time;
	if (angulo<360){
		angulo+=0.1;
	} else {
		angulo=0.0;
	}
	
	}
	calcularfuerzas(&grafo_global);

	
	glutPostRedisplay();	
}

int main(int argc, char** argv)
{
	
	/*
	 * Inicializando OpenGL
	 * */
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize (500, 500); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutIdleFunc(idle);

   /*
    * Inicializando Entrada del Grafo
    * */
   init_grafo();

	/*
	 * Entrando en el ciclo
	 * */

   glutMainLoop();
   
   return 0;
}