PDA

View Full Version : [help] Noobie on Isosurface



johncsl82
07-02-2005, 11:05 AM
greetings great ones,

Where can i find actual coding implemnetation for isosurface or object generation base on formula such as sphere with the formula of

R^2 = X^2 + Y^2 + Z^2

because I noticed that isosurface is an object with a surface of equal values. And I really got problem in generating object with mathematical equations (don't know how to and where to start). Correct me if I'm wrong and Thanks You in Advance =)

best is the coding example are in c++ format...

Thanks

Overmind
07-02-2005, 03:12 PM
The problem with implicit surfaces or isosurfaces is that you can't draw them directly. You have to find some parametric representation for them.

For example the parametric representation for a sphere is:
x = r * cos u * cos v
y = r * sin u * cos v
z = r * sin v
with u running from 0 to 2 pi and v running from -pi/2 to pi/2

Once you have found that representation, you can just use two nested loops to iterate over u and v in some arbitrary stepsize to get all surface vertices.

The problem is that there is no general rule for finding these representations, let alone an algorithm that can run automatically.

Another possibility is the marching cubes algorithm. I can't really give you a coding example because while it's really a simple algorithm, its implementation is rather complex:

Basically you split the region into a regular sized 3d grid of cubes. Then, for each cube, you evaluate the function at the corners of the cube and look if the result is above or below the target value. From this you can determine how the surface runs through this cube, there are only a few possibilities, search the web to find a list of them. The exact location of the vertices can be determined by extrapolation...

I'm sure google will find many websites with the details of the algorithm. But for simple surfaces you should really try to find a parametric equation, because this will always be faster and more accurate.

johncsl82
07-03-2005, 12:11 AM
Originally posted by Overmind:
For example the parametric representation for a sphere is:
x = r * cos u * cos v
y = r * sin u * cos v
z = r * sin v
with u running from 0 to 2 pi and v running from -pi/2 to pi/2

hi there overmind,

Do you mind giving more example the best is that give me some coding example cause implementing mathematical function is not like writing and calculating using our brain, and I hope you understand =). Thanks You.

Overmind
07-04-2005, 06:35 AM
Ok, here you go:


// increase/decrease these for more quality/performance
#define STEPS_U 20
#define STEPS_V 20

double v0, v1 = - M_PI / 2;
for(int j = 1; j <= STEPS_V; j++) {
v0 = v1;
// j is running from 0 to STEPS_V
// v should be running from -pi/2 to pi/2
v1 = (double)(j+1) * M_PI / STEPS_V - M_PI / 2;

glBegin(GL_TRIANGLE_STRIP);
for(int i = 0; i <= STEPS_V; i++) {
// i is running from 0 to STEPS_U
// u should be running from 0 to 2pi
double u = (double)i * 2 * M_PI / STEPS_U;

glVertex3f(r * cos(u) * cos(v0),
r * sin(u) * cos(v0),
r * sin(v0));
glVertex3f(r * cos(u) * cos(v1),
r * sin(u) * cos(v1),
r * sin(v1));
}
glEnd();
} If you look at this code, you see that the outer loop iterates over v and the inner loop iterates over u. It draws a triangle strip between the (j-1)th row and the jth row,

Basically you can use this loop with any formula you like, not just with a sphere.

In a real program it's not good to write it exactly like this, it would be better to run these loops only once at load time and store the result somewhere, for example in a vertex array or display list.

johncsl82
07-04-2005, 11:09 AM
hi there overmind,

I've tried out the source code you given me... it is sad to said that the code is not working cause nothing seems to appear on the screen, and I hope you can fix it asap. Thanks you very much

07-04-2005, 11:12 AM
Let's see the code you have. you've probably made a silly mistake somewhere...

Hlz

johncsl82
07-04-2005, 11:22 AM
sure and here it is
</font><blockquote><font size="1" face="Verdana, Arial">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#include <iostream>
using namespace std;

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

#define STEPS_U 20
#define STEPS_V 20

#define M_PI 3.14159265358979323846

GLint width = 500, height = 500;


void DisplayFunc(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
double v0, v1 = - M_PI / 2;
float r = 1.0;
for(int j = 1; j <= STEPS_V; j++) {
v0 = v1;
// j is running from 0 to STEPS_V
// v should be running from -pi/2 to pi/2
v1 = (double)(j+1) * M_PI / STEPS_V - M_PI / 2;

glBegin(GL_TRIANGLE_STRIP);
for(int i = 0; i <= STEPS_V; i++) {
// i is running from 0 to STEPS_U
// u should be running from 0 to 2pi
double u = (double)i * 2 * M_PI / STEPS_U;

glVertex3f((GLfloat)r * cos(u) * cos(v0),
(GLfloat)r * sin(u) * cos(v0),
(GLfloat)r * sin(v0));
glVertex3f((GLfloat)r * cos(u) * cos(v1),
(GLfloat)r * sin(u) * cos(v1),
(GLfloat)r * sin(v1));
}
glVertex3f(0.0, 250.0, 0.0);
glVertex3f(250.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);

glEnd();

glVertex3f(0.0, 250.0, 0.0);
glVertex3f(250.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);

glutSwapBuffers();
}
}

void ReshapeFunc(GLsizei w, GLsizei h) {
if(width != w

07-04-2005, 11:26 AM
Hint: don't use c/c++ boolean or operators in your posted code. The forum software doesn't like 'em.

Hlz

johncsl82
07-04-2005, 11:30 AM
#include <iostream>
using namespace std;

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

#define STEPS_U 20
#define STEPS_V 20

#define M_PI 3.14159265358979323846

GLint width = 500, height = 500;


void DisplayFunc(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
double v0, v1 = - M_PI / 2;
float r = 1.0;
for(int j = 1; j <= STEPS_V; j++) {
v0 = v1;
// j is running from 0 to STEPS_V
// v should be running from -pi/2 to pi/2
v1 = (double)(j+1) * M_PI / STEPS_V - M_PI / 2;

glBegin(GL_LINE_LOOP);
for(int i = 0; i <= STEPS_V; i++) {
// i is running from 0 to STEPS_U
// u should be running from 0 to 2pi
double u = (double)i * 2 * M_PI / STEPS_U;

glVertex3f((GLfloat)r * cos(u) * cos(v0),
(GLfloat)r * sin(u) * cos(v0),
(GLfloat)r * sin(v0));
glVertex3f((GLfloat)r * cos(u) * cos(v1),
(GLfloat)r * sin(u) * cos(v1),
(GLfloat)r * sin(v1));
}
glVertex3f(0.0, 250.0, 0.0);
glVertex3f(250.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);

glEnd();

glVertex3f(0.0, 250.0, 0.0);
glVertex3f(250.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);

glutSwapBuffers();
}
}

void ReshapeFunc(GLsizei w, GLsizei h) {
if(width != w or height != h) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble) width, 0.0, (GLdouble) height, -100.0, 300.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
DisplayFunc();
}
}

void Init(void) {
glClearColor(1.0, 1.0, 1.0, 0.0);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble) width, 0.0, (GLdouble) height, 0.0, 300);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int main (int argv, char** argc) {
glutInit(&amp;argv, argc);
glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGBA);
glutInitWindowSize(width, height);
glutCreateWindow("IsoSurface Testing");
Init();
glutReshapeFunc(ReshapeFunc);
glutDisplayFunc(DisplayFunc);
glutMainLoop();
return 0;
}

07-04-2005, 11:50 AM
A few typos, improper scaling, and this and that. I commented most the stuff I changed.


#include <math.h>
#include <iostream>
using namespace std;
#include "glut.h"

#define STEPS_U 20
#define STEPS_V 20
#define M_PI 3.14159265358979323846

GLint width = 500, height = 500;

void DisplayFunc(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glColor3f(1.0, 0.0, 0.0);
double v0, v1 = - M_PI / 2;
float r = 100.0; // Make sure radius (scale) makes sense with view volume

// Use this if you want wire frame view
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE /* or GL_FILL */ );

for(int j = 1; j <= STEPS_V; j++)
{
v0 = v1;
// j is running from 0 to STEPS_V
// v should be running from -pi/2 to pi/2
v1 = (double)(j+1) * M_PI / STEPS_V - M_PI / 2;

glBegin(GL_TRIANGLE_STRIP);
for(int i = 0; i <= STEPS_U; i++)
{
// i is running from 0 to STEPS_U
// u should be running from 0 to 2pi
double u = (double)i * 2 * M_PI / STEPS_U;

glVertex3f((GLfloat)r * cos(u) * cos(v0),
(GLfloat)r * sin(u) * cos(v0),
(GLfloat)r * sin(v0));
glVertex3f((GLfloat)r * cos(u) * cos(v1),
(GLfloat)r * sin(u) * cos(v1),
(GLfloat)r * sin(v1));
}
glEnd();
}

glutSwapBuffers();

// Call this to animate
glutPostRedisplay();
}

void ReshapeFunc(GLsizei w, GLsizei h)
{
width=w; height=h;
glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(
-w/2.0, w/2.0,
-h/2.0, h/2.0,
-300.0, 300.0
);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void Init(void)
{
glClearColor(0, 0, 0, 0.0);
}

int main (int argv, char** argc)
{
glutInit(&amp;argv, argc);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutCreateWindow("IsoSurface Testing");
Init();
glutReshapeFunc(ReshapeFunc);
glutDisplayFunc(DisplayFunc);
glutMainLoop();
return 0;
}

johncsl82
07-04-2005, 12:55 PM
Thanks you a lot =) and the code works just fine

07-05-2005, 09:23 AM
You're welcome. I'm happy to be of some use.