// Revo.cpp // CSC 480/580 Fall 2004 - Kirby // --------------------------------------------------------------------- // Draws a wireframe surface of revolution for a function f(x). // Assumes 0 #include #include #include using namespace std ; const double PI= 3.1415926535897 ; double chalice( double x ) // A nice outline of a chalice. { return 0.5 + 0.12 * ( sin( 6*x ) + cos( 8*x - 1 ) ) ; } void surfaceOfRevolution( double xStart, double xStop, int nIntervalsX, int nIntervalsTheta, double (*f)(double) ) // Draw a surface of revolution for f(x) from x=xStart to xStop. // Assumes f(x)>0. // Each slice is divided into nIntervalsTheta angular intervals. // The number of slices is nIntervalsX. { assert( nIntervalsX > 0 ) ; assert( nIntervalsTheta > 0 ) ; assert( xStart >= -1 ) ; assert( xStop <= 1 ) ; assert( xStart < xStop ) ; const double DX= ( xStop - xStart ) / nIntervalsX ; // step size along x const double DTHETA = 2*PI / nIntervalsTheta ; // step size around circle of revolution // Initialize values - first slice. double x= xStart ; double r= f( xStart ) ; assert( r > 0 ) ; for ( int ix=0 ; ix < nIntervalsX ; ++ix ) { double xNext= x + DX ; double rNext= f( xNext ) ; assert( rNext > 0 ) ; glBegin( GL_QUAD_STRIP ) ; { for ( int ia=0 ; ia <= nIntervalsTheta ; ++ia ) { // Update the angle as we move around the circle. double theta= ia * DTHETA ; double c= cos( theta ) ; double s= sin( theta ) ; // Get the points on the circle at x and xNext. double y= r * c ; double z= r * s ; double yNext= rNext * c ; double zNext= rNext * s ; // Add edge at this angle from x to xNext (one boundary of quad strip). glVertex3d( x, y, z ) ; glVertex3d( xNext, yNext, zNext ) ; } // Prepare for next pass through the x loop x= xNext ; r= rNext ; } glEnd() ; } } void display() // Display a yellow wireframe object. { // Set rotation angle based on elapsed time. const double SECONDS_PER_ROT= 8 ; double degrees= glutGet( GLUT_ELAPSED_TIME ) * 0.001 * 360 / SECONDS_PER_ROT ; glLoadIdentity() ; glRotated( degrees, 1, 1, 1 ) ; // Draw. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ; glColor3d( 1.0, 1.0, 0.0 ) ; // yellow surfaceOfRevolution( -0.45, 0.45, 40, 30, chalice ) ; glutSwapBuffers() ; } void animate() // One frame of animation. { glutPostRedisplay() ; } int main( int argc, char** argv ) { // Initialize OpenGL. glutInit( &argc, argv ) ; glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH ) ; // Window position and caption. glutInitWindowSize( 500, 500 ) ; glutInitWindowPosition( 100, 100 ) ; glutCreateWindow( "Revolution!" ) ; // Polygons will be wireframe, rather than solid. glPolygonMode( GL_FRONT, GL_LINE ) ; glPolygonMode( GL_BACK, GL_LINE ) ; // Main display loop. glutDisplayFunc( display ) ; glutIdleFunc( animate ) ; glutMainLoop() ; return 0 ; }