PDA

View Full Version : what is wrong with my menger sponge?



openglbeginner
09-19-2010, 12:20 PM
Hi, first post. Have a question about my code, I have been working on this forever and it draws a cube without subdividing it how it should. There is some evidence that it is subdividing something because 1 face of the cube is divided into 9 squares for n=1 in divideCube(). the cube that is drawn doesn't look too much like a cube either. I used sierpinski gasket code to model it after (tetrahedron instead of cube) and tried to make it similar. My divideCube() function seems correct and follows the model. I am figuring that I am either passing parameters incorrectly to drawCube() or even a recursive divideCube() inside the divideCube() function. Thanks for looking, I just need some insight into solving the problem I have as I am an opengl beginner lol. There isn't too much code to read, just the drawCube() and divideCube() functions. Just posted whole code if anyone needs it.

I also posted the correct code for a sierpinski gasket. At the bottom of this post for reference.

this is the menger sponge code:


#include "SpongeOSX.h"
#include <stdlib.h>
#include <GLUT/Glut.h>
#include <stdio.h>
GLfloat vertices[][3]={{0.0,0.0,0.0},{1.0,0.0,0.0},
{1.0,1.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},
{1.0,0.0,1.0},{1.0,1.0,1.0},{0.0,1.0,1.0}};


static int unit = 1; //cube size


//GLfloat colors[][3]={{0.737255,0.560784,0.560784},{0.737255,0.560784, 0.560784},{0.737255,0.560784,0.560784},{0.737255,0 .560784,0.560784},{0.737255,0.560784,0.560784},
//{0.737255,0.560784,0.560784},{0.737255,0.560784,0. 560784},{0.737255,0.560784,0.560784}};
GLfloat colors[][3]={{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{0.0,0 .0,0.0},{0.0,0.0,1.0},
{1.0,0.0,1.0},{1.0,1.0,1.0},{0.0,1.0,1.0}};//make last black
float theta=0;

void polygon(GLfloat *a, GLfloat *b,GLfloat *c, GLfloat *d)
{

glColor3fv(colors[0]);
glVertex3fv(a);
glColor3fv(colors[1]);
glVertex3fv(b);
glColor3fv(colors[2]);
glVertex3fv(c);
glColor3fv(colors[3]);
glVertex3fv(d);


}

void drawCube(GLfloat *a,GLfloat *b,GLfloat *c,GLfloat *d, GLfloat *e,GLfloat *f, GLfloat *g, GLfloat *h)
{

polygon(a,d,c,b);
polygon(c,d,h,g);
polygon(a,e,h,d);
polygon(b,c,g,f);
polygon(e,f,g,h);
polygon(a,b,f,e);
}
void divideCube(GLfloat *a,GLfloat *b, GLfloat *c, GLfloat *d, GLfloat *e, GLfloat *f, GLfloat *g, GLfloat *h, int n)
{
GLfloat cubePoints[64][3];
int i,j;
int stride = 16;

/*

order i did the first face in
|------->--|
| |
^ ^ |
| |(0,0) V
|--------<--
*/
if(n > 0)
{
//bottom left corner, point 1
for(i=0; i < 3 ;i++)
cubePoints[0][i]=a[i];
//front left
//row, column -> 0,0 = a, point 2
for(i = 0; i < 3; i++)// row 2 column 0
cubePoints[1][i]=(a[i]+d[i])/3;

for(i = 0; i < 3; i++)//row 1 column 0, point 3
cubePoints[2][i]=2*(a[i]+d[i])/3;
//front top left,
for(i=0; i < 3; i++)//row 0 col 0
cubePoints[3][i]=d[i];
//front top
for(i = 0; i < 3; i++)//row 0, column 1, point 4
{
//if i !=1 because you dont want to change the y coordinate
if( i!=1)
cubePoints[4][i]=(c[i]+d[i])/3;
else cubePoints[4][i]=d[i];
}
for(i = 0; i < 3; i++)//row 0, column 2, point 5
{
if(i!=1)
cubePoints[5][i]=2*(c[i]+d[i])/3;
else cubePoints[5][i]=d[i];
}
//front right top
for(i=0; i < 3; i++)//row 0, col 3, point 6
cubePoints[6][i]=c[i];


for(i = 0; i < 3; i++)//row 2, column 3, point 7, was point 8
{
if(i!=0)
cubePoints[7][i]=2*(b[i]+c[i])/3;
else cubePoints[7][i]=c[i];
}
for(i = 0; i < 3; i++)//row 1, column 3, point 8, was point 7
{
if(i!=0)
cubePoints[8][i]=(b[i]+c[i])/3;
else cubePoints[8][i]=c[i];
}
//front bottom right, point 9, row 3 column 3
for(i=0; i < 3; i++)
cubePoints[9][i]=b[i];

for(i = 0; i < 3; i++)//row 3, column 2
cubePoints[10][i]=2*(a[i]+b[i])/3;
for(i = 0; i < 3; i++)//row 3, column 1
cubePoints[11][i]=(a[i]+b[i])/3;



for(i = 0; i < 3; i++)//row 2, column 1, point 12
{
//printf("cubepoints 11[i]: %f, cubepoints 4[i]: %f\n", cubePoints[11][i], cubePoints[4][i]);
if(i!=0)
cubePoints[12][i]=(cubePoints[11][i]+cubePoints[4][i])/3;
else cubePoints[12][i]=cubePoints[11][i];
}
for(i = 0; i < 3; i++)//row 1, column 1, point 13
{
if(i!=0)
cubePoints[13][i]=2*(cubePoints[11][i]+cubePoints[4][i])/3;
else cubePoints[13][i]=cubePoints[11][i];
}

for(i=0; i < 3; i++)//row 2, column 2
{
if(i!=0)
cubePoints[14][i]=(cubePoints[10][i]+cubePoints[5][i])/3;
else cubePoints[14][i]=cubePoints[10][i];
}
for(i=0; i < 3; i++)//row 1 column 2
{
if(i!=0)
cubePoints[15][i]=2*(cubePoints[10][i]+cubePoints[5][i])/3;
else cubePoints[15][i]=cubePoints[10][i];
}

for(i =0;i < 16;i++)
{
printf("point %d\n",i);
int j;
for(j=0; j < 3; j++)
{
printf("%f\n",cubePoints[i][j]);
}
printf("\n");
}


for(i=16;i<32;i++)
for(j = 0; j < 3; j++)
{
if(j<2)
cubePoints[i][j]=cubePoints[i-16][j];
else cubePoints[i][j]=unit/3;
}
for(i=32;i<48;i++)
for(j = 0; j < 3; j++)
{
if(j<2)
cubePoints[i][j]=cubePoints[i-32][j];
else cubePoints[i][j]=2*(unit/3);
}
for(i=48;i<64;i++)
for(j = 0; j < 3; j++)
{
if(j<2)
cubePoints[i][j]=cubePoints[i-48][j];
else cubePoints[i][j]=unit;
}
unit/=3;
/*********Front of the cube************/
//create 27 cubes by subdivision
//order: bottom left front->bottom right front->top right front -> top left front
//front 8 cubes
//bottom, left, front cube ******** left column of front
divideCube(cubePoints[0],cubePoints[11],cubePoints[12],cubePoints[1],cubePoints[stride],cubePoints[stride+11],
cubePoints[stride+12],cubePoints[stride+1],n-1);
divideCube(cubePoints[1],cubePoints[12],cubePoints[13],cubePoints[2],cubePoints[stride+1],cubePoints[stride+12],
cubePoints[stride+13],cubePoints[stride+2],n-1);//make sure 13 is correct
divideCube(cubePoints[2],cubePoints[13],cubePoints[4],cubePoints[3],cubePoints[stride+2],cubePoints[stride+13],
cubePoints[stride+4],cubePoints[stride+3],n-1);
//middle column of front of cube
divideCube(cubePoints[11],cubePoints[10],cubePoints[14],cubePoints[12],cubePoints[stride+11],cubePoints[stride+10],
cubePoints[stride+14],cubePoints[stride+12],n-1);
divideCube(cubePoints[13],cubePoints[15],cubePoints[5],cubePoints[4],cubePoints[13+stride],cubePoints[15+stride],
cubePoints[5+stride],cubePoints[4+stride],n-1);
//right column of front of cube
divideCube(cubePoints[10],cubePoints[9],cubePoints[7],cubePoints[14],cubePoints[10+stride],cubePoints[9+stride],
cubePoints[7+stride],cubePoints[14+stride],n-1);
divideCube(cubePoints[14],cubePoints[7],cubePoints[8],cubePoints[15],cubePoints[stride+14],cubePoints[stride+7],
cubePoints[stride+8],cubePoints[stride+15],n-1);
divideCube(cubePoints[15],cubePoints[8],cubePoints[6],cubePoints[5],cubePoints[stride+15],cubePoints[stride+8],
cubePoints[stride+6],cubePoints[stride+5],n-1);

//bottom and top middle left
divideCube(cubePoints[stride],cubePoints[stride+11],cubePoints[stride+12],cubePoints[stride+1],cubePoints[2*stride],cubePoints[2*stride+11],
cubePoints[2*stride+12],cubePoints[2*stride+1],n-1);
divideCube(cubePoints[2+stride],cubePoints[13+stride],cubePoints[4+stride],cubePoints[3+stride],cubePoints[2*stride+2],cubePoints[2*stride+13],
cubePoints[2*stride+4],cubePoints[2*stride+3],n-1);

//bottom and top middle right
divideCube(cubePoints[10+stride],cubePoints[9+stride],cubePoints[7+stride],cubePoints[14+stride],cubePoints[10+stride*2],cubePoints[9+stride*2],
cubePoints[7+stride*2],cubePoints[14+stride*2],n-1);
divideCube(cubePoints[15+stride],cubePoints[8+stride],cubePoints[6+stride],cubePoints[5+stride],cubePoints[stride*2+15],cubePoints[stride*2+8],
cubePoints[stride*2+6],cubePoints[stride*2+5],n-1);

//left column of back of cube
divideCube(cubePoints[0 + stride*2],cubePoints[11+stride*2],cubePoints[12+stride*2],cubePoints[1+stride*2],cubePoints[stride*3],cubePoints[stride*3+11],
cubePoints[stride*3+12],cubePoints[stride*3+1],n-1);
divideCube(cubePoints[1+stride*2],cubePoints[12+stride*2],cubePoints[13+stride*2],cubePoints[2+stride*2],cubePoints[stride*3+1],cubePoints[stride*3+12],
cubePoints[stride*3+13],cubePoints[stride*3+2],n-1);//make sure 13 is correct
divideCube(cubePoints[2+stride*2],cubePoints[13+stride*2],cubePoints[4+stride*2],cubePoints[3+stride*2],cubePoints[stride*3+2],cubePoints[stride*3+13],
cubePoints[stride*3+4],cubePoints[stride*3+3],n-1);
//middle column of back of cube
divideCube(cubePoints[11+stride*2],cubePoints[10+stride*2],cubePoints[14+stride*2],cubePoints[12+stride*2],cubePoints[stride*3+11],cubePoints[stride*3+10],
cubePoints[stride*3+14],cubePoints[stride*3+12],n-1);
divideCube(cubePoints[13+stride*2],cubePoints[15+stride*2],cubePoints[5+stride*2],cubePoints[4+stride*2],cubePoints[13+stride*3],cubePoints[15+stride*3],
cubePoints[5+stride*3],cubePoints[4+stride*3],n-1);
//right column of back of cube
divideCube(cubePoints[10+stride*2],cubePoints[9+stride*2],cubePoints[7+stride*2],cubePoints[14+stride*2],cubePoints[10+stride*3],cubePoints[9+stride*3],
cubePoints[7+stride*3],cubePoints[14+stride*3],n-1);
divideCube(cubePoints[14+stride*2],cubePoints[7+stride*2],cubePoints[8+stride*2],cubePoints[15+stride*2],cubePoints[stride*3+14],cubePoints[stride*3+7],
cubePoints[stride*3+8],cubePoints[stride*3+15],n-1);
divideCube(cubePoints[15+stride*2],cubePoints[8+stride*2],cubePoints[6+stride*2],cubePoints[5+stride*2],cubePoints[stride*3+15],cubePoints[stride*3+8],
cubePoints[stride*3+6],cubePoints[stride*3+5],n-1);
}
{
drawCube(a,b,c,d,e,f,g,h);
}


}

void colorcube()
{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glPushMatrix();
glRotatef(theta, 1,1,1);
glBegin(GL_POLYGON);
//drawCube();
divideCube(vertices[0],vertices[1],vertices[2],vertices[3],vertices[4],vertices[5],vertices[6],vertices[7],1);
glPopMatrix();
glEnd();

glFlush();
glutPostRedisplay();//refresh the screen

}

void myReshape(int w, int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
glOrtho(-1.0,2.0,-1.0*(GLfloat) h / (GLfloat) w,
2.0*(GLfloat) h / (GLfloat) w, -10.0, 10.0);
else
glOrtho(-1.0*(GLfloat) w/(GLfloat) h, 2.0*(GLfloat) w / (GLfloat) h,-1.0,2.0,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
void init()
{
glClearColor (0.0, 0.0, 0.0, 1.0);

glColor3f(1.0, 0.0, 1.0);

glMatrixMode (GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
glLoadIdentity ();
glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
}
void idle()
{
theta+=.00005;
if(theta>360)theta=0;
}
int main(int argc, char**argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPT H);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);

glutCreateWindow("Cube");

init();
glutReshapeFunc(myReshape);
glutDisplayFunc(colorcube);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}

here is the example that i am following to create the cube, it is a tetrahedron, the sierpinski gasket


/* recursive subdivision of a tetrahedron to form 3D Sierpinski gasket */
/* number of recursive steps given on command line */

#include <stdlib.h>
//#include <glut.h> /* for windows */
#include <GL/glut.h>

/* initial tetrahedron */

GLfloat v[4][3]={{0.0, 0.0, 1.0}, {0.0, 0.942809, -0.33333},
{-0.816497, -0.471405, -0.333333}, {0.816497, -0.471405, -0.333333}};

GLfloat colors[4][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}, {0.0, 0.0, 0.0}};

int n;

void triangle(GLfloat *va, GLfloat *vb, GLfloat *vc) {
glVertex3fv(va);
glVertex3fv(vb);
glVertex3fv(vc);
}


void tetra(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d) {
glColor3fv(colors[0]);
triangle(a, b, c);
glColor3fv(colors[1]);
triangle(a, c, d);
glColor3fv(colors[2]);
triangle(a, d, b);
glColor3fv(colors[3]);
triangle(b, d, c);
}


void divide_tetra(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d, int m) {
GLfloat mid[6][3];
int j;
if( m > 0 ) {
// compute six midpoints...
for(j=0; j<3; j++) mid[0][j]=(a[j]+b[j])/2;
for(j=0; j<3; j++) mid[1][j]=(a[j]+c[j])/2;
for(j=0; j<3; j++) mid[2][j]=(a[j]+d[j])/2;
for(j=0; j<3; j++) mid[3][j]=(b[j]+c[j])/2;
for(j=0; j<3; j++) mid[4][j]=(c[j]+d[j])/2;
for(j=0; j<3; j++) mid[5][j]=(b[j]+d[j])/2;

// create 4 tetrahedrons by subdivision...
divide_tetra(a, mid[0], mid[1], mid[2], m-1);
divide_tetra(mid[0], b, mid[3], mid[5], m-1);
divide_tetra(mid[1], mid[3], c, mid[4], m-1);
divide_tetra(mid[2], mid[5], mid[4], d, m-1);

}
else {
// draw tetrahedron at end of recursion...
tetra(a,b,c,d);
}
}


void myDisplay() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
divide_tetra(v[0], v[1], v[2], v[3], n);
glEnd();
glFlush();
}


void myReshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w,
2.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0);
else
glOrtho(-2.0 * (GLfloat) w / (GLfloat) h,
2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}



void myInit() {
// Clear color...
glClearColor(0.0, 0.0, 0.0, 1.0);

// Fill color...
glColor3f(1.0, 0.0, 0.0);

// Enable double buffering...
glEnable(GL_DEPTH_TEST);

// Standard orthogonal view -- first refer to the projection
// matrix...
glMatrixMode(GL_PROJECTION);
// Load it to be an identity matrix...
glLoadIdentity();
// Set desired viewing/clipping rectangle...
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}




int main(int argc, char **argv) {
/* enter number of subdivision steps here */
if (argc > 1) {
n=atoi(argv[1]);
}
else n = 3;

glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);

glutCreateWindow("3D Gasket");
glutReshapeFunc(myReshape);
glutDisplayFunc(myDisplay);

myInit();
glutMainLoop();
}