#include #include #include #include #include #include #include "SolidObjects.h" #ifndef M_PI #define M_PI 3.14159 #endif char **tokenizer(char *s,int *n) { *n = 0; int nb = strlen(s); int i; for ( i = 0 ; i < nb ; i++ ) if ( s[i] == '|' ) (*n)++; (*n)++; char **ts =(char **) calloc(*n,sizeof(char *)); int pi = -1 ; int pf = 0; i = 0; for ( ; i < (*n)-1 ; i++ ) { while ( s[pf] != '|' ) pf++; ts[i] =(char *) calloc(pf-pi+1,sizeof(char)); for ( int j = pi+1 ; j < pf ; j++ ) ts[i][j-pi-1] = s[j]; ts[i][j-pi-1] = 0x00; pi = pf; pf++; } pf = nb; ts[i] =(char *) calloc(pf-pi+1,sizeof(char)); for ( int j = pi+1 ; j < pf ; j++ ) ts[i][j-pi-1] = s[j]; ts[i][j-pi-1] = 0x00; return(ts); } void solidCone(float r,float h,int n,char *p) { int np; char **ts = tokenizer(p,&np); int parts = 0x00; int i; for ( i = 0 ; i < np ; i++ ) { if ( !strcmp(ts[i],"ALL") ) { parts |= 0x03; continue; } if ( !strcmp(ts[i],"BOTTOM") ) { parts |= 0x02; continue; } if ( !strcmp(ts[i],"SIDES") ) { parts |= 0x01; continue; } } float *cs =(float *) calloc(n,sizeof(float)); float *sn =(float *) calloc(n,sizeof(float)); for ( i = 0 ; i < n ; i++ ) { float a = (2*M_PI*i)/n; sn[i] = sin(a); cs[i] = cos(a); } glPushMatrix(); if ( parts | 0x01 ) { float f = 1.0F/pow(r*r+h*h,0.5); for ( int j = 0 ; j < n ; j++ ) { glBegin(GL_QUAD_STRIP); for ( i = 0 ; i <= n ; i++ ) { float x = r*cs[i%n]; float z = -r*sn[i%n]; glNormal3f(cs[i%n]*f*h,r*f,-sn[i%n]*f*h); glVertex3f(j*x/n,h/2-j*h/n,j*z/n); glVertex3f((j+1)*x/n,h/2-(j+1)*h/n,(j+1)*z/n); } glEnd(); } } if ( parts | 0x02 ) { glBegin(GL_POLYGON); glNormal3f(0.0F,-1.0F,0.0F); for ( i = 0 ; i < n ; i++ ) { float si = sn[i]; float ci = cs[i]; glVertex3f(r*ci,-h/2,r*si); } glEnd(); } free(cs); free(sn); glPopMatrix(); } void solidCylindre(float r,float h,int n,char *p) { int np; char **ts = tokenizer(p,&np); int parts = 0x00; int i; for ( i = 0 ; i < np ; i++ ) { if ( !strcmp(ts[i],"ALL") ) { parts |= 0x07; continue; } if ( !strcmp(ts[i],"TOP") ) { parts |= 0x04; continue; } if ( !strcmp(ts[i],"BOTTOM") ) { parts |= 0x02; continue; } if ( !strcmp(ts[i],"SIDES") ) { parts |= 0x01; continue; } } float *cs =(float *) calloc(n,sizeof(float)); float *sn =(float *) calloc(n,sizeof(float)); for( i = 0 ; i < n ; i++ ){ float a = (2*M_PI*i)/n; sn[i] = sin(a); cs[i] = cos(a); } glPushMatrix(); if ( parts | 0x01 ) for ( int j = 0 ; j < n ; j++ ) { float hi = h/2-(j*h/n); float hf = h/2-((j+1)*h/n); glBegin(GL_QUAD_STRIP); for ( i = 0 ; i <= n ; i++ ){ float x = r*cs[i%n]; float z = -r*sn[i%n]; glNormal3f(cs[i%n],0.0F,-sn[i%n]); glVertex3f(x,hi,z); glVertex3f(x,hf,z); } glEnd(); } if ( parts | 0x04 ) { glBegin(GL_POLYGON); glNormal3f(0.0F,1.0F,0.0F); for ( i = 0 ; i < n ; i++ ){ float si = -sn[i]; float ci = cs[i]; glVertex3f(r*ci,h/2,r*si); } glEnd(); } if ( parts | 0x02 ) { glBegin(GL_POLYGON); glNormal3f(0.0F,-1.0F,0.0F); for ( i = 0 ; i < n ; i++ ){ float si = sn[i]; float ci = cs[i]; glVertex3f(r*ci,-h/2,r*si); } glEnd(); } free(cs); free(sn); glPopMatrix(); } static void face(float *p00,float *p01,float *p11,float *p10,int n) { for ( int i = 0 ; i < n ; i++ ) { float p1ix = p00[0]+i*(p01[0]-p00[0])/n; float p1iy = p00[1]+i*(p01[1]-p00[1])/n; float p1iz = p00[2]+i*(p01[2]-p00[2])/n; float p1fx = p00[0]+(i+1)*(p01[0]-p00[0])/n; float p1fy = p00[1]+(i+1)*(p01[1]-p00[1])/n; float p1fz = p00[2]+(i+1)*(p01[2]-p00[2])/n; float p2ix = p10[0]+i*(p11[0]-p10[0])/n; float p2iy = p10[1]+i*(p11[1]-p10[1])/n; float p2iz = p10[2]+i*(p11[2]-p10[2])/n; float p2fx = p10[0]+(i+1)*(p11[0]-p10[0])/n; float p2fy = p10[1]+(i+1)*(p11[1]-p10[1])/n; float p2fz = p10[2]+(i+1)*(p11[2]-p10[2])/n; glBegin(GL_QUAD_STRIP); for ( int j = 0 ; j <= n ; j++ ) { float p1x = p1ix+j*(p2ix-p1ix)/n; float p1y = p1iy+j*(p2iy-p1iy)/n; float p1z = p1iz+j*(p2iz-p1iz)/n; float p2x = p1fx+j*(p2fx-p1fx)/n; float p2y = p1fy+j*(p2fy-p1fy)/n; float p2z = p1fz+j*(p2fz-p1fz)/n; glVertex3f(p1x,p1y,p1z); glVertex3f(p2x,p2y,p2z); } glEnd(); } } static void cube(float w,float h,float d,int n){ w /= 2.0F; h /= 2.0F; d /= 2.0F; static GLfloat vdata[8][3] = { { w, h,-d},{ w,-h,-d}, {-w,-h,-d},{-w, h,-d}, { w, h, d},{ w,-h, d}, {-w,-h, d},{-w, h, d}} ; static GLint t[6][4] = { {0,1,2,3}, {7,6,5,4}, {5,6,2,1}, {0,3,7,4}, {6,7,3,2}, {4,5,1,0}} ; static GLfloat ndata[6][3] = { { 0.0, 0.0,-1.0}, { 0.0, 0.0, 1.0}, { 0.0,-1.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}} ; for ( int i = 0 ; i < 6 ; i++ ) { glNormal3fv(&ndata[i][0]); face(vdata[t[i][0]],vdata[t[i][1]],vdata[t[i][2]],vdata[t[i][3]],n); } } void solidSphere(float r,int n) { float *cs =(float *) calloc(n,sizeof(float)); float *sn =(float *) calloc(n,sizeof(float)); int i; for( i = 0 ; i < n ; i++ ){ float a = (2*M_PI*i)/n; sn[i] = sin(a); cs[i] = cos(a); } for ( i = 0 ; i < n ; i++ ) { float a1 = -M_PI/2.0F + i*M_PI/n ; float a2 = a1 + M_PI/n ; float cs1 = r*cos(a1); float cs2 = r*cos(a2); float sn1 = r*sin(a1); float sn2 = r*sin(a2); glBegin(GL_QUAD_STRIP); for ( int j = 0 ; j <= n ; j++ ) { float x1 = cs1*cs[j%n]; float y1 = cs1*sn[j%n]; float x2 = cs2*cs[j%n]; float y2 = cs2*sn[j%n]; glNormal3f(x2,y2,sn2); glVertex3f(x2,y2,sn2); glNormal3f(x1,y1,sn1); glVertex3f(x1,y1,sn1); } glEnd(); } free(cs); free(sn); }