ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi all,
I am working on a project in c++ which involves generating the 2D positions of a number of small disks (or points) over a period of time. The coordinates of the disks are stored in a simple array:
r[2][400]
The 2 corresponds to the x and y coordinates and the 400 represents the number of disks. Throughout the program the coordinates are modified numerous times. What I am trying to produce is a visual window which can display the movement of the disks as line trajectories. .i.e a straight line is drawn from the previous position to the new one for each of the 400 disks throughout the program. I've looked at Xlib and it all seems beyond my experience and I am currently pulling my hair out with QT.
Does anyone know the most simplistic way to go about this or could they even post a sample of code. I do not need buttons, text boxes etc. just a window drawing lines which can be updated during the program. Ideally I require a function that accepts the r[2][400] array and updates the window with the new values.
Many thanks in advance
Sat
here's an old project i did in college that's kinda like what you're doing.
the particles generated are connected by lines. they are also random,
but you can make it more structured. you need to create the keyboard input for updating the display. it's unix friendly and compiles using gcc 2.96
Code:
#include <iostream>
//#include <windows.h>
#include <cstdlib>
#include <string>
#include <sstream>
#include <math.h>
#include <exception>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
using namespace std;
#define WIN_SZ_WID 500
#define WIN_SZ_SIZE 500
#define WIN_POS_X 100
#define WIN_POS_Y 100
#define NUM_PARTICLES 1000
#define MAX_NEW 20
#define MIN_NEW 5 //needs to be greater than 0
//or no points will be activated
#define MAX_AGE 100
#define CYL_HIEGHT 4.0
#define CYL_BASE_WID 4.0
#define CYL_TOP_WID 1.0
#define QUAD_SLICE 100
#define QUAD_STACK 2
#define D_RING 12
#define D_IN_RAD 0.0
#define LINE_WID 2.0
#define PI 3.14159265
//instantiate quadric
GLUquadricObj *my_cyl;
GLUquadricObj *cyl_top_disk;
GLdouble cyl_base; //base radius
GLdouble cyl_top; //top radius
float scaling, rotz, rotx, roty; //for viewing
int new_particles;
typedef struct particle
{
float pos[3];
float prev_pos[3];
float vel[3];
float age;
} Particle;
Particle particles[NUM_PARTICLES];
float accel[] = {0.0,0.0,-0.1};
//function prototypes
void instructions ();
void initParticles ();
void initCylinder ();
void moveAndDrawParticles ();
void drawCylinder ();
void init ();
void reshape (int w, int h);
void display ();
void keyboard (unsigned char key, int x, int y);
//start program
int main (int argc, char* argv[])
{
try
{
instructions ();
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
glutInitWindowSize (WIN_SZ_WID, WIN_SZ_SIZE);
glutInitWindowPosition (WIN_POS_X, WIN_POS_Y);
glutCreateWindow ("PARTICLES BY MEGASPAZ");
init ();
initCylinder ();
initParticles ();
glutDisplayFunc (display);
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutIdleFunc (display);
glutMainLoop ();
return 0;
}
catch (exception& e)
{
cout <<"Error: " <<e.what () <<endl;
return 1;
}
catch (...)
{
cout <<"An Unknown Error Occurred...Exiting" <<endl;
return 1;
}
}
void initParticles ()
{
int i,j;
for (i = 0; i < NUM_PARTICLES; i++)
{
for (j = 0; j < 3; j++)
{
particles[i].pos [j] = 0.0;
particles[i].vel [j] = 0.0;
}
particles[i].age = -1; //inactive
}
}
void initCylinder ()
{
cyl_base = CYL_BASE_WID;
cyl_top = CYL_TOP_WID;
//init the cylinder
my_cyl = gluNewQuadric ();
gluQuadricDrawStyle (my_cyl,GLU_FILL);
//init cylinder's top - disk
cyl_top_disk = gluNewQuadric ();
gluQuadricDrawStyle (cyl_top_disk, GLU_FILL);
}
void moveAndDrawParticles ()
{
int i,j,numToActivate;
//retire old particles
for (i = 0; i < NUM_PARTICLES; i++)
{
if (particles[i].age > MAX_AGE)
{
particles[i].age = -1;
}
}
//activate some new ones
numToActivate = new_particles;
for (i = 0; i < NUM_PARTICLES; i++)
{
float r_num, x, y, angle;
//generate random numbers for angle, x and y coordinates
r_num = (rand()%1000) / (1000.0 - 0.5) * cyl_top;
angle = (rand()%1000) / 1000.0 * 2 * PI;
x = r_num * cos (angle);
y = r_num * sin (angle);
if (-1 == particles[i].age)
{
particles[i].age = 0;
particles[i].pos [0] = x;
particles[i].pos [1] = y;
particles[i].pos [2] = CYL_HIEGHT;
particles[i].vel [0] = (rand()%1000) / 1000.0 - 0.5;
particles[i].vel [1] = (rand()%1000) / 1000.0 - 0.5;
particles[i].vel [2] = 2.0 + (rand()%1000) / 1000.0;
if (--numToActivate == 0)
{
break;
}
}
}
//move and age the active ones
for (i = 0; i < NUM_PARTICLES; i++)
{
if (particles[i].age != -1)
{
particles[i].age += 1;
for (j = 0; j < 3; j++)
{
//get previous position
particles[i].prev_pos [j] = particles[i].pos [j];
//assign new position
particles[i].pos [j] += particles[i].vel [j];
particles[i].vel [j] += accel[j];
}
}
}
//deactivate lighting
glDisable (GL_LIGHTING);
//draw active ones
glLineWidth (LINE_WID); //set line width in pixels
glBegin( GL_LINES ); //begin drawing lines
for (i = 0; i < NUM_PARTICLES; i++)
{
if (particles[i].age != -1)
{
//change color of line based on particle age
if (particles[i].age < MAX_AGE * 0.25)
{
glColor3f (1.0, 1.0, 1.0); //white
}
else if (particles[i].age >= MAX_AGE * 0.25 && particles[i].age < MAX_AGE * 0.5)
{
glColor3f (1.0, 1.0, 0.0); //yellow
}
else
{
glColor3f (1.0, 0.2, 0.0); //orange
}
glVertex3fv (particles[i].prev_pos); //start point
glVertex3fv (particles[i].pos); //end point
}
}
glEnd ();
//reactivate lighting
glEnable (GL_LIGHTING);
}
void drawCylinder ()
{
gluCylinder (my_cyl, cyl_base, cyl_top, CYL_HIEGHT, QUAD_SLICE, QUAD_STACK);
//push matrix on stack
glPushMatrix ();
//set color for disk
glColor3f (0.2, 0.0, 0.4); //purple-ish
//translate disk to cylinder hieght
glTranslatef (0.0, 0.0, CYL_HIEGHT);
//draw top of cylinder
gluDisk (cyl_top_disk, D_IN_RAD, cyl_top, QUAD_SLICE, D_RING);
//pop matrix
glPopMatrix ();
}
void init ()
{
new_particles = MIN_NEW;
GLfloat lightPos[] = { 1.0, 0.0, 1.0, 0.0 };
GLfloat lightPos2[] = { 1.0, 0.0, -1.0, 0.0 };
GLfloat lt_color[] = { 0.0, 0.0, 1.0, 0.0}; //blue
GLfloat amb_color[] = { 0.0, 0.0, 0.0, 0.0 }; //black
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
glLightfv (GL_LIGHT0, GL_POSITION, lightPos );
glLightfv (GL_LIGHT1, GL_POSITION, lightPos2 );
glLightfv (GL_LIGHT0, GL_DIFFUSE, lt_color );
glLightfv (GL_LIGHT1, GL_DIFFUSE, lt_color );
glLightfv (GL_LIGHT0, GL_AMBIENT, amb_color );
glLightfv (GL_LIGHT1, GL_AMBIENT, amb_color );
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_LIGHT1);
glEnable (GL_DEPTH_TEST);
scaling = 1.0;
rotz = rotx = roty = 0.0;
}
void reshape (int w, int h)
{
glViewport (0,0,(GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (90.0, (GLfloat) w / (GLfloat) h, 1.0, 1000.0);
glMatrixMode (GL_MODELVIEW);
}
void display ()
{
static float frame = 0;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix ();
glLoadIdentity ();
//viewing transfromation
gluLookAt (0.0,0.0,10.0, 0.0,0.0,0.0, 0.0,1.0,0.0);
glScalef (scaling,scaling,scaling);
glRotatef (roty,0.0,1.0,0.0);
glRotatef (rotx,1.0,0.0,0.0);
glRotatef (rotz, 0.0,0.0,1.0);
drawCylinder ();
moveAndDrawParticles ();
glPopMatrix ();
glutSwapBuffers ();
}
void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case 'F':
case 'f':
scaling *= 1.1;
break;
case 'B':
case 'b':
scaling *= 0.9;
break;
case 'U':
case 'u':
rotx -= 2;
break;
case 'D':
case 'd':
rotx += 2;
break;
case 'R':
case 'r':
roty -= 2;
break;
case 'L':
case 'l':
roty += 2;
break;
case 'A':
case 'a':
rotz -= 2;
break;
case 'Z':
case 'z':
rotz += 2;
break;
case 'W':
case 'w':
cyl_base += 1.0;
cyl_top += 1.0;
break;
case 'E':
case 'e':
if (cyl_base > CYL_BASE_WID && cyl_top > CYL_TOP_WID)
{
cyl_base -= 1.0;
cyl_top -= 1.0;
}
else
{
cyl_base = CYL_BASE_WID;
cyl_top = CYL_TOP_WID;
}
break;
case 'P':
case 'p':
if (new_particles < MAX_NEW)
{
new_particles += 1;
}
else
{
new_particles = MAX_NEW;
}
break;
case 'O':
case 'o':
if (new_particles > MIN_NEW)
{
new_particles -= 1;
}
else
{
new_particles = MIN_NEW;
}
break;
case 'Q':
case 'q':
exit (0);
break;
}
glutPostRedisplay();
}
void instructions ()
{
string input;
cout <<endl <<endl;
cout <<"Keyboard Commands" <<endl;
cout <<"-----------------" <<endl;
cout <<endl;
cout <<"f - Zoom In" <<endl;
cout <<"b - Zoom Out" <<endl;
cout <<"u - Rotate up X Axis" <<endl;
cout <<"d - Rotate Down X Axis" <<endl;
cout <<"r - Rotate Down Y Axis" <<endl;
cout <<"l - Rotate Up Y Axis" <<endl;
cout <<"a - Rotate Down Z Axis" <<endl;
cout <<"z - Rotate Up Z Axis" <<endl;
cout <<"w - Increase Cylinder Radius" <<endl;
cout <<"e - Decrease Cylinder Radius" <<endl;
cout <<"p - Increase New Particle Amount" <<endl;
cout <<"o - Decrease New Particle Amount" <<endl;
cout <<"q - Quit" <<endl;
cout <<endl;
//Microsoft STL getline has bug where you have press enter twice
//need to ignore buffer after getline as cin will leave garbage.
//but using ignore will exaserbates the double return problem as all
//input-ed strings need double return for getline to get the string.
//But string is as it was input-ed
cout <<"Enter Any Key To Continue - \"q\" To Quit: ";
cout <<endl;
getline (cin,input); //bad implementation to a good idea
//uncomment cin.ignore if compiling on Unix or Linux
//cin.ignore (); //wouldn't be unnecessary if Microsoft didn't screw up std::getline
cout <<endl;
if (input == "Q" || input == "q")
{
exit (0);
}
Thanks for the code. I'm having problems compiling with the command you suggest:
g++ -o particles.exe parti.cpp /usr/lib/libglut.so.3.7
I have glut 3.7 installed and the .so file present in the /usr/lib path??
Cheers
Sat
I still get the same compilation errors:
parti.cpp:10:21: GL/glut.h: No such file or directory
parti.cpp: In function `int main(int, char**)':
parti.cpp:69: `glutInit' undeclared (first use this function)
parti.cpp:69: (Each undeclared identifier is reported only once for each
function it appears in.)
parti.cpp:70: `GLUT_DOUBLE' undeclared (first use this function)
parti.cpp:70: `GLUT_RGB' undeclared (first use this function)
parti.cpp:70: `GLUT_DEPTH' undeclared (first use this function)
parti.cpp:70: `glutInitDisplayMode' undeclared (first use this function)
parti.cpp:71: `glutInitWindowSize' undeclared (first use this function)
parti.cpp:72: `glutInitWindowPosition' undeclared (first use this function)
parti.cpp:73: `glutCreateWindow' undeclared (first use this function)
parti.cpp:79: `glutDisplayFunc' undeclared (first use this function)
parti.cpp:80: `glutReshapeFunc' undeclared (first use this function)
parti.cpp:81: `glutKeyboardFunc' undeclared (first use this function)
parti.cpp:82: `glutIdleFunc' undeclared (first use this function)
parti.cpp:83: `glutMainLoop' undeclared (first use this function)
parti.cpp: In function `void display()':
parti.cpp:278: `glutSwapBuffers' undeclared (first use this function)
parti.cpp: In function `void keyboard(unsigned char, int, int)':
parti.cpp:362: `glutPostRedisplay' undeclared (first use this function)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.