Home | | Syllabus | | Assignments | | Documentation

    Solution to Assignment 4, Problem 1c


    /*
    CSCI 384 Assignment 4.
    Problem 1c:  Approximation to a cylinder.
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <GL/glut.h>
    
    #define PI 3.14159
    typedef GLfloat point3[3];
    GLfloat spin[3] = {0.0, 0.0, 0.0};
    
    void myinit(void)
    {
    	glClearColor(1.0, 1.0, 1.0, 1.0);
    	glColor3f(1.0, 0.0, 0.0);
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	glOrtho(-250, 250, -250, 250, -250, 250); /*Note, not ortho2D*/
    	glMatrixMode(GL_MODELVIEW);
    }
    
    /*Set length of vector to 50*sqrt(2) */
    void normalize(GLfloat *verts){
    	int i;
    	GLfloat normalFactor;
    	
    	normalFactor = sqrt(verts[0]*verts[0] + verts[2]*verts[2]);
    	verts[0] = 50.0 * sqrt(2.0)*verts[0]/normalFactor;
    	verts[2] = 50.0 * sqrt(2.0)*verts[2]/normalFactor;
    }
    
    /*Draw Quad faces*/
    void rectangleFace(point3 p1, point3 p2, point3 p3, point3 p4){
    	
    	/*Draw the quadrilateral*/
    	glBegin(GL_QUADS);
    		glVertex3fv(p1);
    		glVertex3fv(p2);
    		glVertex3fv(p3);
    		glVertex3fv(p4);
    	glEnd();
    }
    
    /*Recursively divide trangular faces to approximate cylinder*/
    void divideQuad(point3 a, point3 b, point3 c, point3 d, int m){
    	point3 midpoint1, midpoint2;
    	
    	if (m > 0) {
    		/*Calculate midpoint of top and bottom edges of quad*/
    		midpoint1[0] = (a[0] + b[0])/2.0;
    		midpoint1[1] = (a[1] + b[1])/2.0;
    		midpoint1[2] = (a[2] + b[2])/2.0;
    		
    		midpoint2[0] = (c[0] + d[0])/2.0;
    		midpoint2[1] = (c[1] + d[1])/2.0;
    		midpoint2[2] = (c[2] + d[2])/2.0;
    		
    		/*Move those points to distance of 50.0*sqrt(2.0) from the center*/
    		normalize(midpoint2);
    		normalize(midpoint1);
    		
    		/*Divide up the new quadralateral faces generated*/
    		glColor3f(1.0, 0.0, 0.0);
    		divideQuad(a, midpoint1, midpoint2, d, m-1);
    		glColor3f(0.0, 0.0, 1.0);
    		divideQuad(midpoint1, b, c, midpoint2, m-1);
    	} else {
    		/*We're done with recursion, draw rectangle*/
    		rectangleFace(a, b, c, d);
    	}
    }
    
    
    	
    void display(void){
    	/*Note 3D points here.  Set up array of 3D vertices*/
    	
    	point3 vertices[8] = { {-50.0, 50.0, 50.0}, {-50.0, 50.0, -50.0}, {50.0, 50.0, -50.0}, {50.0, 50.0, 50.0}, 
    							{-50.0, -50.0, 50.0}, {-50.0, -50.0, -50.0}, {50.0, -50.0, -50.0}, {50.0, -50.0, 50.0} };
    	int i;
    	int m = 1;
    	
    	/*Make sure all vertices are equidistant from origin*/
    	for(i = 0; i < 8; i++){
    		normalize(vertices[i]);
    	}
    	
    	/*Note use of Depth buffer bit for hidden surface removal*/
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	
    	glLoadIdentity();
    	glRotatef(spin[0], 1.0, 0.0, 0.0); /*Rotate box*/
    	glRotatef(spin[1], 0.0, 1.0, 0.0);
    	glRotatef(spin[2], 0.0, 0.0, 1.0);
    	
    	/*Start dividing the faces*/
    	glColor3f(1, 0, 0);
    	divideQuad(vertices[0], vertices[1], vertices[5],  vertices[4], m);
    	glColor3f(0, 0, 1);
    	divideQuad(vertices[1], vertices[2], vertices[6],  vertices[5], m);
    	glColor3f(1, 0, 0);
    	divideQuad(vertices[2], vertices[3], vertices[7],  vertices[6], m);
    	glColor3f(0, 0, 1);
    	divideQuad(vertices[3], vertices[0], vertices[4],  vertices[7], m);
    	
    	glFlush();
    	glutSwapBuffers(); /*Display next buffer*/
    }
    
    /*User interface for spinning the cylinder*/
    void keys(unsigned char key, int x, int y){
    	int axis;
    	if(key == 'f') {
    		axis = 0;
    		spin[axis] += 2.0;
    		if (spin[axis] > 360.0)
    			spin[axis] = spin[axis] - 360.0;
    	}
    	else if(key == 'j'){
    		axis = 1;
    		spin[axis] += 2.0;
    		if (spin[axis] > 360.0)
    			spin[axis] = spin[axis] - 360.0;
    	}
    	else if(key == 'k'){
    		axis = 2;
    		spin[axis] += 2.0;
    		if (spin[axis] > 360.0)
    			spin[axis] = spin[axis] - 360.0;
    	}
    	
    	
    	
    	glutPostRedisplay();
    }
    
    
    int main(int argc, char** argv)
    {	
    	glutInit(&argc, argv);
    	/*Note the GLUT_DOUBLE and GLUT_DEPTH here*/
    	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    	myinit();
    	glutInitWindowSize(500,500);
    	glutInitWindowPosition(50,50);
    	glutCreateWindow("Spinning Quads"); 
    	glutDisplayFunc(display);
    	glutKeyboardFunc(keys);
    	glEnable(GL_DEPTH_TEST); /*For hidden surface removal*/
    	myinit();
    	glutMainLoop();
    	
    	return 0;
    }
    	
    	
    
    

    Home | | Syllabus | | Assignments | | Documentation


    Constance Royden--croyden@mathcs.holycross.edu
    Computer Science 384
    Date Created: August 17, 1999
    Last Modified: October 28, 2003
    Page Expires: August 17, 2004