PDA

View Full Version : Help: 3d line plot troubles

balboa0123
06-23-2011, 10:29 PM
Hi all,

I am a physics student working on some particle trajectories in electromagnetic fields. I have the trajectories working well, and can ably plot them in gnuplot, although I am unhappy with the lack of scaling and slowness due to being cpu-based.

So, I've made a 3d freeGLUT plotter. I used freeGLUT over GLUT simply for mouse wheel functionality. My plotter works well for a simple helical graph, where the points

(0.1*i,10*sin(0.1*i),10*cos(0.1*i))

are graphed.

The dimensions of this plot are scaled isometrically. However, data from my trajectory varies over many orders of magnitude. So much so that I only see a line segment going off into the dark.

I figure there's some option that decides how far out to render. I need to set the render depth out far enough that I can see my whole 3d line, and not just a tiny segment of its beginning. I can't figure it out because googling 'glut depth' is spammed with depth_buffer info, which doesn't apply much to me since I'm only drawing line segments with no shading.

Here is my freeGLUT code:

If you wish to run this,

<div class="ubbcode-block"><div class="ubbcode-header">Click to reveal.. <input type="button" class="form-button" value="Show me!" onclick="toggle_spoiler(this, 'Yikes, my eyes!', 'Show me!')" />]<div style="display: none;">

//this code is linked to a header with all the
//appropriate libraries, especially freeGLUT.

//the plot output comes from a vectorized struct.
//it's just x,y,z data though...

float zoom = 15.0f;
float rotx = 0;
float roty = 0.001f;
float rotz = 0;
float tx = 0;
float ty = 0;
float tz = 0;
int lastx=0;
int lasty=0;
unsigned char Buttons[3] = {0};

void Display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glTranslatef(0,0,-zoom);
glTranslatef(tx,ty,tz);
glRotatef(rotx,1,0,0);
glRotatef(roty,0,1,0);
glRotatef(rotz,0,0,1);

double dt=0.1;
glBegin (GL_LINE_STRIP);
for(unsigned int i=0; i<Data.x.size();i++)
{
glVertex3d(Data.x[i],Data.y[i],Data.z[i]);
}
glEnd();

glutSwapBuffers();
}

void Reshape(int w, int h)
{
if(h==0) {h=1;}
float rat = (float)w/(float)h;
glMatrixMode(GL_PROJECTION);
glViewport(0, 0, w, h);
gluPerspective(45,rat,1,1000);
glMatrixMode(GL_MODELVIEW);
}

void Mouse(int b,int s,int x,int y)
{
lastx=x;
lasty=y;
switch(b)
{
case GLUT_LEFT_BUTTON:
Buttons[0] = ((GLUT_DOWN==s)?1:0);
break;
case GLUT_MIDDLE_BUTTON:
Buttons[1] = ((GLUT_DOWN==s)?1:0);
break;
case GLUT_RIGHT_BUTTON:
Buttons[2] = ((GLUT_DOWN==s)?1:0);
break;
default:
break;
}
glutPostRedisplay();
}

void Keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case '+':
zoom -= (float)0.25*zoom;
glutPostRedisplay ();
break;
case '-':
zoom += (float)0.25*zoom;
glutPostRedisplay ();
break;
case 'q':
exit(0);
case 27:
exit(0);
}
}

void Special(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_UP:
tz++;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
tz--;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT:
tx--;
glutPostRedisplay();
break;
case GLUT_KEY_LEFT:
tx++;
glutPostRedisplay();
break;
case GLUT_KEY_PAGE_UP:
ty--;
glutPostRedisplay();
break;
case GLUT_KEY_PAGE_DOWN:
ty++;
glutPostRedisplay();
break;
}
}

void MouseWheel(int button, int dir, int x, int y)
{
if (dir > 0)
{
zoom -= (float)0.25*zoom;
glutPostRedisplay ();
}
else if(dir<0)
{
zoom += (float)0.25*zoom;
glutPostRedisplay ();
}

return;
}
void Motion(int x,int y)
{
int diffx=x-lastx;
int diffy=y-lasty;
lastx=x;
lasty=y;

if( Buttons[0])
{
rotx += (float) 0.5f * diffy;
roty += (float) 0.5f * diffx;
glutPostRedisplay();
}
// else if( Buttons[1] )
// {
// roty += (float) 0.5f * diffy;
// rotz += (float) 0.5f * diffx;
// glutPostRedisplay();
// }
// else if( Buttons[2] )
// {
// rotx += (float) 0.5f * diffx;
// rotz += (float) 0.5f * diffy;
// glutPostRedisplay();
// }

}

void Init()
{
//glEnable(GL_DEPTH_TEST);
}
void EB3dPlot(int argc,char** argv)
{
// __________________________________gives visible helix.
//for(unsigned int i=0; i<1000;i++)
// {
// Data.x.push_back(.1*i);
// Data.y.push_back(10*sin(.1*i));
// Data.z.push_back(10*cos(.1*i));
// }

glutInit(&amp;argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA/*|GLUT_DEPTH*/);
glutInitWindowSize(800,600);
glutInitWindowPosition(0,0);
glutCreateWindow("3D Line Plot");

glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Keyboard);
glutSpecialFunc(Special);
glutMouseFunc(Mouse);
glutMouseWheelFunc(MouseWheel);
glutMotionFunc(Motion);
Init();
glutMainLoop();
}
[/QUOTE]</div>

balboa0123
06-23-2011, 10:40 PM
Whoops! accidentally submitted this in the midst of editing. Well, if you want to run it in a working state:

include cmath, windows.h, GL/freeglut.h with freeglut properly linked

look at following lines in Display():

for(unsigned int i=0; i<Data.x.size();i++)
{
glVertex3d(Data.x[i],Data.y[i],Data.z[i]);
}

change them to:

for(unsigned int i=0; i<10000; i++)
{
glVertex3d(0.1*i,10*sin(0.1*i),10*cos(0.1*i));
}

(the Data struct comes from other code and won't work; to get the working helix, switch the code to this.)

To be clear: I just need to see all the points in my line; as things are I see a straight line that cuts off.
I know that it's part of a curve, but the scale is off.
Zooming out doesn't help because it doesn't change the cutoff.

The helix works; my data goes from ~1 to ~10^6 or so, while the helix goes from 0<100 or less. Herein lies the problem, methinks.

ZbuffeR
06-24-2011, 01:22 AM
Please please use [ code ] (without spaces) tags around your code !
If you can edit your posts this way, please do so !

Can't you scale your data so that it fits in the 1-1000 range you specified in you projection ? It is more complex with a perspective projection compared to a glOrtho proj, but still doable.

balboa0123
06-24-2011, 02:54 AM
ZbuffeR: Thanks for the reply.
I used spoilers because that's all I saw to use;
The 2nd post is because I f'd up the first one, but I could post a working code if you like, though it requires freeglut links.

More importantly:

You speak of a 1-1000 range.
It must have to do with gluPerspective(45,rat,1,1000);
Is this what's specifying my render range?

Sorry, that was probably obvious....

My program doesn't know the plot range beforehand...
It could range from 10^-10 to 10^+10 or so...

So, is there a solution that will scale to any plot?

I have (x,y,z) of the points in my line aka trajectory.
The values are doubles (more accurate floats).
The trajectory start at the origin...
Should I rescale my plot manually to fit 1-1000,
or should I use gluPerspective(45,rat,1,x*x*+y*y+z*z),
where x*x*+y*y+z*z is the furthest point?!?

Thanks for any response, I will most likely try messing with gluPerspective in the morning...
Will post info if it gets fixed

balboa0123
06-24-2011, 03:05 AM
Sorry, I meant:

"or should I use gluPerspective(45,rat,1,sqrt(x*x*+y*y+z*z)),
where (x,y,z) is the furthest point?"