PDA

View Full Version : draw 3d points in space freely



Tiago
02-21-2012, 03:25 PM
Hi,

i recently implemented a trackball and it is nice to visualize any object.

Now i am trying to plot 3d points in space. when the application starts I can plot and visualize my points in the screen (640 x 480), but when I rotate the modelview matrix and plot new points they remain being render in the same place.

my problem (i guess) is to find a way to setup the Z coordinate of my 3d point to it can be ploted on the right place.

i let the main code and auxiliary below:



main file:
---------------------------------------------------------------
#include <math.h>
#include <stdlib.h>
#include "Point.h"
#include <vector>

GLfloat mouseX_, mouseY_; //posicao inicial do cursor
bool rotationing = true;
GLfloat matrix [] = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};

std::vector<Point> points;
bool mousePlot = true;

void display(void)
{
/* display callback, clear frame buffer and z buffer,
plot points and draw references, swap buffers */

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glutWireTeapot(100);

for(int i = 0; i < points.size(); i++){

glBegin(GL_POINTS);
glColor3f(1.0,0.0,0.1);
glPointSize(100);
glVertex3f(points.at(i).x, points.at(i).y, points.at(i).z);
glEnd();
}

glFlush();
glutSwapBuffers();

}

void mouse(int btn, int state, int x, int y)
{

if(btn == GLUT_LEFT_BUTTON &amp;&amp; mousePlot){
float x_ = (float) x - glutGet(GLUT_WINDOW_WIDTH)/2;
float y_ = (float) -(y - glutGet(GLUT_WINDOW_HEIGHT)/2);
float z = 0.0;

Point *p = new Point(x_,y_,z);

points.push_back(*p);
}

if(btn == GLUT_RIGHT_BUTTON){
mousePlot = !mousePlot;
}

}

void myReshape(int w, int h)
{
float nRange = w/2;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-w/2, w/2, -h/2, h/2, -nRange, nRange);
glMatrixMode(GL_MODELVIEW);
}

void trackball(int PX, int PY){

//mouse = anterior position
//P = position in use

if (rotationing &amp;&amp; !mousePlot){
GLint W = glutGet(GLUT_WINDOW_WIDTH);
GLint H = glutGet(GLUT_WINDOW_HEIGHT);

GLfloat ray; //for while, i needn't take the sqrt for the ray.
if (W>H) ray=W*W/2;
else ray=H*H/2;

mouseX_ -= W/2; //
GLfloat px = PX - W/2; // this part is to use the center
mouseY_ = H/2 - mouseY_; // of the screen as the origin
GLfloat py = H/2 - PY; //
//the idea is to find the Z coordinate of the two points in sphere's surface centered in the origin
GLfloat mouseX_Y2 = mouseX_*mouseX_ + mouseY_*mouseY_;
GLfloat pXY2 = px*px+py*py;

if (mouseX_Y2 < ray &amp;&amp; pXY2 < ray){ //this trackball only works for points inside the sphere

GLfloat mouseZ = sqrt(ray - mouseX_Y2);

GLfloat pz = sqrt(ray - pXY2);

GLfloat axisRotation[3]; //vector product "mouse X P"
axisRotation[0] = -mouseZ*py + mouseY_*pz;
axisRotation[1] = mouseZ*px - mouseX_*pz;
axisRotation[2] = -mouseY_*px + mouseX_*py;

GLfloat anguloRotacao = atan(sqrt(axisRotation[0]*axisRotation[0] + axisRotation[1]*axisRotation[1] + axisRotation[2]*axisRotation[2]));

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glRotatef(anguloRotacao,axisRotation[0],axisRotation[1],axisRotation[2]);
glMultMatrixf(matrix);
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
}
}
mouseX_ = PX;
mouseY_ = PY;
glutPostRedisplay();

}

void main(int argc, char **argv)
{
glutInit(&amp;argc, argv);
/* need both double buffering and z buffer */
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("draw :)");
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(trackball);
glEnable(GL_DEPTH_TEST); /* Enable hidden--surface--removal */
glutMainLoop();
}
---------------------------------------------------------------
point.h:

#ifndef POINT_H
#define POINT_H

#include <iostream>
#include <OpenGL/gl/glut.h>

class Point {

public:

Point(void);

Point(float &amp;x, float &amp;y, float &amp;z);

~Point(){

this->x = 0.0;
this->y = 0.0;
this->z = 0.0;

}

Point &amp;getPoint(){ return *this;}

void setPoint(float &amp;x, float &amp;y, float &amp;z);

void setPoint(float x, float y, float z);

void coordinates();

public:

float x, y, z;

};

#endif

point.cpp
---------------------------------------------------------------
#include "Point.h";

Point::Point(void)
{

}

Point::Point(float &amp;x, float &amp;y, float &amp;z)
{
this-> x = x;
this-> y = y;
this-> z = z;
}

void Point::setPoint(float &amp;x, float &amp;y, float &amp;z)
{
this-> x = x;
this-> y = y;
this-> z = z;
}

void Point::setPoint(float x, float y, float z)
{
this-> x = x;
this-> y = y;
this-> z = z;
}

void Point::coordinates()
{
std::cout << "x = " << this->x;
std::cout << "y = " << this->y;
std::cout << "z = " << this->z;
}

carsten neumann
02-22-2012, 01:12 PM
my problem (i guess) is to find a way to setup the Z coordinate of my 3d point to it can be ploted on the right place.


I guess so, but unless you describe what "the right place" means in your case, it is difficult to make suggestions ;)

Tiago
02-22-2012, 02:48 PM
of course, sorry.

the right place is always in the front of the camera (the screen plane) as showed in takeo igarashi's tec. paper in figure 16 (http://www-ui.is.s.u-tokyo.ac.jp/~takeo/papers/siggraph99.pdf).

i trying to make those kind of stroke, but when i move the camera i can't make new strokes in the plane screen again.

thanks.

carsten neumann
02-22-2012, 03:20 PM
You need to store the point positions in world space (currently you are storing their eye space position, which for you initial camera position happens to be the same as world space - more or less). In other words you need to multiply your points' position with the inverse view matrix before storing them.