PDA

View Full Version : 3D Function Plotting

gr00vy
08-18-2005, 10:11 AM
Hello, this is my very first post here.

Im posting because im a little lost on a proyect im trying to develop. Its a function plotting software.

Im having problems to view the plot as a whole, i tried settin gluPerspective but its like the same thing.

What im trying to do is to draw 3 axes and locate the plot there. Then view the plot something like this.

z
|
|_____ x
/
/ PLOT (x^2 + y^2)
y

Here it is the source code, its for unix*

i hope you can point me in the right direction.

Thank you very much.

PS: You need to press '-' a lot to see the plot

#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <stdio.h>

typedef struct
{
double beg;
double end;
} axis;

axis dx, dy, dz;
int width = 400, length = 400;

double
xscale (axis x, double p)
{
//return (p - x.beg) * length / (x.end - x.beg);
return (p) * (x.end - x.beg)/length;
}

double
yscale (axis y, double p)
{
//return (p - y.beg) * width / (y.end - y.beg);
return (p)*(y.end - y.beg) / width ;
}

double
zscale (axis z, double p)
{
return (p - z.beg) * 5 / (z.end - z.beg);
}

void
reshape(int x, int y)
{
width = x, length =y;

glViewport(0, 0, x, y);

glMatrixMode(GL_PROJECTION);

//glOrtho(dx.beg, dx.end, dy.beg, dy.end, -700,700);
//glOrtho(dx.beg, dx.end, dy.beg, dy.end, dz.beg,dz.end);
//glOrtho(-x/2, x/2, -y/2, y/2, -500,500);
glOrtho(0, x, 0, y, -500,500);
//gluPerspective(45.0, (float)x/y , 0.1, 32.0);

glMatrixMode(GL_MODELVIEW);

gluLookAt(1,1,1, 0,0,0, 0,1,0);

glutPostRedisplay();
}
void
keyboard(unsigned char key, int x, int y)
{
double stepx = (dx.end - dx.beg)/10;
double stepy = (dy.end - dy.beg)/10;
double stepz = (dz.end - dz.beg)/10;

switch (key)
{
case '+':
dx.beg += stepx;
dx.end -= stepx;
dy.beg += stepy;
dy.end -= stepy;
dz.beg += stepz;
dz.end -= stepz;
puts("FUCK");
break;
case '-':
dx.beg -= stepx;
dx.end += stepx;
dy.beg -= stepy;
dy.end += stepy;
dz.beg -= stepz;
dz.end += stepz;
break;
}

glutPostRedisplay ();
}

double max = 0;
static double angulo = 0;
#define POINTS 400

void
lines(void)
{
int i, j, k;
double table[POINTS][POINTS];

for(i = 0; i < POINTS; i+=4)
{
for(j = 0; j < POINTS; j+=4)
{
table[i][j] = i*i + j*j;
}
}

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3d (1, 1, 1);

glBegin(GL_LINES);
glVertex3d(0,0,0);
glVertex3d(0,0,400);
glVertex3d(0,0,0);
glVertex3d(0,400,0);
glVertex3d(0,0,0);
glVertex3d(400,0,0);
glEnd();

for(k = 0; k < 2; k++)
{
glBegin (GL_POINTS);
for(i = 0; i < POINTS; i+=4)
{
for(j = 0; j < POINTS; j+=4)
{
k == 0 ? glVertex3d(xscale(dx, i), yscale(dy, j), zscale(dz, table[i][j])) : glVertex3d(xscale(dx, j), yscale(dy, i), zscale(dz, table[j][i]));
}
}
glEnd();
}

glutSwapBuffers();

}

int
main(int argc, char **argv)
{
dx.beg = 0;
dx.end = 2;
dy.beg = 0;
dy.end = 2;
dz.beg = 0;
dz.end = 5;

glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);

glutInitWindowSize(width, length);
glutCreateWindow("3D GRAPH");

glClearColor(0,0,0,0);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_COLOR_MATERIAL);

glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);

glutDisplayFunc(lines);
glutIdleFunc(lines);
//glutDisplayFunc(lorenzAttractor);
//glutIdleFunc(lorenzAttractor);

glutMainLoop();

}

Hlz
08-20-2005, 12:28 PM
Well, for starters, you seem to have simple problems with the flow of your code. I'd take the modelview stuff out of the reshape callback and move it into your render function (you're loading an identity on top of your lookat call, making it pointless).

gr00vy
08-21-2005, 12:04 AM
Hi, thank you for your reply. You were terribly right about that. I changed it an things changed.

Now the "plane" displays correct in screen. I have to do some adjustments , for example, draw less points, draw a mesh instead of points.

One thing i have got to ask is, how can i draw a suface, with all the points i calculate? now i cannot think on a easy way to do it.

Here it is the code working (i hope you find it usefull):

#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <stdio.h>

typedef struct
{
double beg;
double end;
} axis;

axis dx, dy, dz;
int width = 640, length = 480;

double
xscale (axis x, double p)
{
//return (p - x.beg) * length / (x.end - x.beg);
return (p) * (x.end - x.beg)/length;
}

double
yscale (axis y, double p)
{
//return (p - y.beg) * width / (y.end - y.beg);
return (p)*(y.end - y.beg) / width ;
}

double
zscale (axis z, double p)
{
return (p)*(z.end - z.beg) / 320000 ;
//return (p - z.beg) * width / (z.end - z.beg);
}

void
reshape(int x, int y)
{
width = x, length =y;

glViewport(0, 0, x, y);

glMatrixMode(GL_PROJECTION);

gluPerspective(45.0f, (float)x/(float)y , 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}

void
keyboard(unsigned char key, int x, int y)
{
double stepx = (dx.end - dx.beg)/10;
double stepy = (dy.end - dy.beg)/10;
double stepz = (dz.end - dz.beg)/10;

switch (key)
{
case '+':
dx.beg += stepx;
dx.end -= stepx;
dy.beg += stepy;
dy.end -= stepy;
dz.beg += stepz;
dz.end -= stepz;
puts("FUCK");

printf("dx.beg %f dx.end %f\n", dx.beg,dx.end);
printf("dy.beg %f dy.end %f\n", dy.beg,dy.end);
break;
case '-':
dx.beg -= stepx;
dx.end += stepx;
dy.beg -= stepy;
dy.end += stepy;
dz.beg -= stepz;
dz.end += stepz;
printf("dx.beg %f dx.end %f\n", dx.beg,dx.end);
printf("dy.beg %f dy.end %f\n", dy.beg,dy.end);

break;
}

glutPostRedisplay ();
}

double max = 0;
static double angulo = 0;

#define POINTS 400

void
lines(void)
{
int i, j, k;
double table[POINTS][POINTS];

for(i = 0; i < POINTS; i+=4)
{
for(j = 0; j < POINTS; j+=4)
{
table[i][j] = i*i + j*j;
}
}

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//gluLookAt(0,0,0, 0,0,0, 0,1,0);

glColor3d (1, 1, 1);
glTranslatef(0.0f,0.0f,-6.0f);

glBegin(GL_LINES);
glVertex3d(0,0,0);
glVertex3d(0,0,400);
glVertex3d(0,0,0);
glVertex3d(0,400,0);
glVertex3d(0,0,0);
glVertex3d(400,0,0);
glEnd();

glTranslatef(0.0f,0.0f,-6.0f);

if(angulo > 360)
angulo = 0;

glRotatef(angulo++, 0.0,1.0,0.0);

for(k = 0; k < 2; k++)
{
glBegin (GL_POINTS);
for(i = 0; i < POINTS; i+=4)
{
for(j = 0; j < POINTS; j+=4)
{
if(k == 0)
glVertex3d(xscale(dx, i), yscale(dy, j), zscale(dz,table[i][j]));
else
glVertex3d(xscale(dx, j), yscale(dy, i), zscale(dz,table[j][i]));
}
}
glEnd();
}

//glutSolidTeapot(1);
glutSwapBuffers();
}

int
main(int argc, char **argv)
{
dx.beg = 0;
dx.end = 1.5;
dy.beg = 0;
dy.end = 1.5;
dz.beg = 0;
dz.end = 1.5;

glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowSize(width, length);
glutInitWindowPosition(0, 0);
glutCreateWindow("3D GRAPH");

glutDisplayFunc(lines);
glutIdleFunc(lines);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_COLOR_MATERIAL);

glMatrixMode(GL_PROJECTION);
gluPerspective(45.0f,(GLfloat)width/(GLfloat)length,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);

glutMainLoop();

return 0;
}

Hlz
08-21-2005, 09:35 AM
http://www.rush3d.com/reference/opengl-redbook-1.1/chapter02.html

For a surface, think of tri-lists or tri-strips (better). To generate either, think of your surface as z = f(x,y). Then, for a tri-strip, you have (x,y,f(x,y)), (x,y+dy,f(x,y+dy)) repeated in a zigzag pattern across the grid in the x, for each strip, like the rows of a terrain.

Look at glScalef on the modelview for your scaling. Look at glPushMatrix and glPopMatrix to preserve the current matrix while you fiddle with a particular model's transforms.

PS. What is up with these margins? I need a wide-screen mode to view this stuff ;)