/* Using stacks and affine transformations to construct a mobile. Written by Caroline Geiersbach and Scott D. Anderson scott.anderson@acm.org Summer 2003 */ #include #include #include //bounding box dimensions GLfloat width = 60; GLfloat height = 60; GLfloat length = 60; //bar lengths GLfloat bLength1=35; // length of first bar from top GLfloat bLength2=20; // length of second bar GLfloat bLength3=15; // length of third bar GLfloat bLength4=8; // length of fourth bar //string lengths GLfloat sLength1=10; // length of first string from top GLfloat sLength2=7; // length of second string GLfloat sLength3=15; // length of third string GLfloat sLength4=15; // length of fourth string //draws a "bar" of uniform height and width; takes length as a parameter void drawBar(GLfloat length) { glPushMatrix(); twColorName(TW_GRAY); glScalef(length,1,1); glutSolidCube(1); glPopMatrix(); } //draws a red string of length len and moves coordinate system to //the end of the string void drawString(GLfloat len) { twColorName(TW_RED); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(0,-len,0); glEnd(); glTranslatef(0,-len,0); } //resizes twDrawBarn, translated so that barn is drawn from the center //(x and z directions) and from the top (y direction). void drawBarn() { glPushMatrix(); glRotatef(75,0,1,0); //turn so sides of barn can be seen glTranslatef(-2,-6,3); //center barn at end of string glScalef(4,6,6); twTriple side = {0.2,0.2,0.9}; //color of sides twTriple roof = {0.3,0.3,0.3}; //color of roof twTriple ends = {0.3,0.3,0.9}; //color of ends twSolidBarn(ends,side,roof); glPopMatrix(); } void drawRightSide() { glPushMatrix(); glTranslatef((bLength1)/2,0,0); //translate to right end of first bar drawString(sLength1); //draw top right string // glTranslatef(0,-sLength1,0); //translate to bottom of first string drawBar(bLength2); glPushMatrix(); //stores location after second bar is drawn glTranslatef((bLength2)/2,0,0); //translate to right end of second bar drawString(sLength2); //glTranslatef(0,-sLength2,0); //translate to bottom of second string drawBar(bLength3); glPushMatrix(); //stores location after third bar is drawn glTranslatef((bLength3)/2,0,0); //translate to right end of third bar drawString(sLength3); // glTranslatef(0,-sLength3,0); //translate to bottom of third string drawBar(bLength4); glPushMatrix(); //stores location after fourth bar is drawn glTranslatef((bLength4)/2,0,0); //translate to right end of fourth bar drawString(sLength4); // glTranslatef(0,-sLength4,0); //translate to bottom of fourth string twTriple lightRed = {0.2,0.2,1}; twColor(lightRed,0,0); //set color for teapot glutSolidTeapot(1.5); glPopMatrix(); //return to middle of fourth bar glTranslatef((-bLength4)/2,0,0); drawString(sLength4); //glTranslatef(0,-sLength4,0); twColorName(TW_CYAN); glScalef(2,2,2); glutSolidOctahedron(); /* OCTAHEDRON */ glPopMatrix(); //return to middle of third bar glTranslatef((-bLength3)/2,0,0); drawString(sLength3); // glTranslatef(0,-sLength3,0); twTriple darkGreen = {0.5,0.1,0.1}; twColor(darkGreen,0,0); glScalef(10,10,10); twTeddyBear(); /* BEAR */ glPopMatrix(); // return to middle of second bar glTranslatef((-bLength2)/2,0,0); drawString(sLength2); //glTranslatef(0,-sLength2,0); twTriple darkYellow = {0.8, 0.8, 0.0}; twColor(darkYellow,0,0); glTranslatef(0,-3,0); //translate down the size of the torus's outer radius glutSolidTorus(1,3,10,10); /* TORUS */ glPopMatrix(); } void drawLeftSide() { glPushMatrix(); glTranslatef((-bLength1)/2,0,0); //translate to left end of first bar drawString(sLength1); //draw top left string //glTranslatef(0,-sLength1,0); //translate to bottom of first string drawBar(bLength2); glPushMatrix(); //stores location after second bar is drawn glTranslatef((-bLength2)/2,0,0); //translate to left end of second bar drawString(sLength2); //glTranslatef(0,-sLength2,0); //translate to bottom of second string drawBar(bLength3); glPushMatrix(); //stores location after third bar is drawn glTranslatef((-bLength3)/2,0,0); //translate to left end of third bar drawString(sLength3); //glTranslatef(0,-sLength3,0); //translate to bottom of third string drawBar(bLength4); glPushMatrix(); //stores location after fourth bar is drawn glTranslatef((-bLength4)/2,0,0); //translate to left end of fourth bar drawString(sLength4); //glTranslatef(0,-sLength4,0); //translate to bottom of fourth string twTriple greenish = {0.2, 0.8, 0.2}; twColor(greenish,0,0); //set color for icosahedron glScalef(2,2,2); glutSolidIcosahedron(); glPopMatrix(); //return to middle of fourth bar glTranslatef((bLength4)/2,0,0); //translate to right end of fourth bar drawString(sLength4); //glTranslatef(0,-sLength4,0); twTriple darkPink = {0.5, 0, 0.5}; twColor(darkPink, 0, 0); //set color for tetrahedron glScalef(2,2,2); glutSolidTetrahedron(); glPopMatrix(); //return to middle of third bar glTranslatef((bLength3)/2,0,0); //translate to right end of third bar drawString(sLength3); // glTranslatef(0,-sLength3,0); twTriple darkCyan = {0, 0.5, 0.5}; twColor(darkCyan,0,0); glTranslatef(0,-2,0); //translate down the size of the radius of the sphere glutSolidSphere(3,20,20); glPopMatrix(); // return to middle of second bar glTranslatef((bLength2)/2,0,0); //translate to right end of second bar drawString(sLength2); //glTranslatef(0,-sLength2,0); drawBarn(); /* BARN */ glPopMatrix(); } void display(void) { twDisplayInit(); twCamera(); //sets up camera based on bounding box coords. glPushMatrix(); glTranslatef(width/2,height,length); drawString(10); //top middle string //glTranslatef(0,-10,0); drawBar(bLength1); //draw top bar drawRightSide(); drawLeftSide(); glPopMatrix(); glFlush(); glutSwapBuffers(); //necessary for animation } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); twInitWindowSize(600,600); glutCreateWindow(argv[0]); glutDisplayFunc(display); twBoundingBox(0,width,0,height,0,length); twMainInit(); glutMainLoop(); return 0; }