// Uses the keyboard x,X,y,Y,and z,Z to change //x,y,and z values for gluLookAt(). (See Point of View program from Angel) #include #include #include #include #include static GLfloat spin = 0.0; void drawCircle(GLfloat x, GLfloat y, GLfloat radius); void fillCircle(GLfloat x, GLfloat y, GLfloat radius); void drawSphere(GLfloat x, GLfloat y, GLfloat radius); void drawLine(GLfloat x, GLfloat y, GLfloat x2, GLfloat y2); class MyPoint { public: void draw(); void setXY(double x, double y); void setRadius(double r); void setColor(double r, double g, double b); double gety() {return y;} double gety0() {return y0;} double getploty(){return ploty;} double getx() {return x;} double getx0() {return x0;} double getxchange() {return xchange;} double getplotx() {return plotx;} double getm() {return m;} double getv() {return v;} double getv0() {return v0;} double geta() {return a;} double geta0() {return a0;} double getangle() {return angle;} double gettheta() {return theta;} void sety(double newy) { y = newy;} void sety0(double newy) { y0 = newy;} void setx(double newx) { x = newx;} void setx0(double newx) { x0 = newx;} void setxchange(double newx) { xchange = newx;} void setploty(double newy) { ploty = newy;} void setplotx(double newx) { plotx = newx;} void setAcc(double newa) { a = newa;} void setv0(double newv0) { v0 = newv0;} void setv(double newv) { v = newv;} void setangle(double newangle) {angle = newangle; theta=angle*3.14159/180.0;} void setvy(double newv) { vy = newv;} void setm(double newm) { m = newm;} void seta0(double newa) { a0 = newa;} void seta(double newa) { a = newa;} private: double x, x0, plotx, xchange; double y, y0, ploty; double a, a0, v ,v0,vy; double m; double angle, theta; double radius; double r, g, b; }; void MyPoint::draw() { glColor3f(r,g,b); drawSphere(x,y,radius); glColor3f(1.0,1.0,1.0); } void MyPoint::setXY(double newx, double newy) { plotx = newx; ploty = newy; x = newx; y = newy; x0 = newx; y0 = newy; } void MyPoint::setRadius(double newradius) { radius = newradius; } void MyPoint::setColor(double red, double green, double blue) { r =red; g = green; b = blue; } double k = 0.5; double m = 1.5; double y; double Y0 = 0.03, prevY=0.03; double a0=0.0, a, v0=0.0, v; double t=0.0; double dt=0.08; double alpha; double dstable = 12.0; double d = 10.0; double startingY=60.0; double g=.098; double angle=45.0; double theta; int zmotion=0; int printpointofview=1; int base; //For initializing strings static GLdouble viewer[]= {5.0, 5.0, 5.0}; /* initial viewer location */ MyPoint point[10]; void drawLine(GLfloat x, GLfloat y, GLfloat z, GLfloat x2, GLfloat y2, GLfloat z2) { glBegin(GL_LINES); glVertex3f(x, y, z); glVertex3f(x2, y2, z2); glEnd(); } void drawLine(GLfloat x, GLfloat y, GLfloat x2, GLfloat y2) { glBegin(GL_LINES); glVertex3f(x, y, 0.0); glVertex3f(x2, y2, 0.0); glEnd(); } void drawCircle(GLfloat x, GLfloat y, GLfloat radius) { GLUquadricObj *p; glPushMatrix(); p = gluNewQuadric(); glTranslatef(x, y, 0.0); gluQuadricDrawStyle(p, GLU_SILHOUETTE); gluDisk(p, 0, radius, 100,10); glPopMatrix(); glFlush(); } void drawSphere(GLfloat x, GLfloat y, GLfloat radius) { GLUquadricObj *p; glPushMatrix(); p = gluNewQuadric(); glTranslatef(x, y, 0.0); gluQuadricDrawStyle(p, GLU_FILL); //See p. 434, Woo gluSphere(p, radius, 100,10); glPopMatrix(); glFlush(); } void fillCircle(GLfloat x, GLfloat y, GLfloat radius) { GLUquadricObj *p; glPushMatrix(); p = gluNewQuadric(); glTranslatef(x, y, 0.0); gluQuadricDrawStyle(p, GLU_FILL); gluDisk(p, 0, radius, 100,1); glPopMatrix(); glFlush(); } void init_String() { int i; base = glGenLists(128); for(i=0;i<128;i++) { glNewList(base+i, GL_COMPILE); glutBitmapCharacter(GLUT_BITMAP_9_BY_15, i); glEndList(); } glListBase(base); } void writeString(char str[], GLfloat x, GLfloat y) { glRasterPos2f(x, y); glColor3f(1.0,1.0,1.0); glCallLists( strlen(str), GL_BYTE, str); } void writeValue(GLdouble val, GLfloat x, GLfloat y) { char str[25], temp[5]; sprintf(str,"%d",(int)val); if ((int) val != val) { strcat(str,"."); // itoa((int)(val*10) % 10, temp, 10); sprintf(temp, "%d", ((int)val*10) % 10); strcat(str, temp); } writeString(str, x, y); } void calcNewY(MyPoint& p) { double y0= p.gety0(); double v = p.getv(); double a0 = p.geta0(); double a = -9.8; double y = p.gety(); double m = p.getm(); double vy=sin(p.gettheta())*v; p.sety(y0 + vy*t + 0.5*a*t*t); //v = v0 + a*dt p.setploty(p.gety()); } void calcNewX(MyPoint& p) { double x0= p.getx0(); double vx = cos(p.gettheta())*p.getv(); double m = p.getm(); p.setx(x0 + vx*t + 0.5*0.0*t*t); //y = y0 + v*dt p.setplotx(p.getx()); } void display(void) { int i; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(viewer[0],viewer[1],viewer[2],0,0,0,0,1,0); if (printpointofview) printf("X:%.1f Y:%.1f Z:%.1f\n",viewer[0],viewer[1],viewer[2]); writeString("Use left mouse", 95, 125); writeString("button for menu...", 95, 115); drawLine(0,0,0,150); drawLine(0,0,150,0); drawLine(0,0,0,0,0,150); point[0].draw(); point[1].draw(); writeString("Ball #1 Angle: ", 10, -20); writeValue((int)point[0].getangle(),75,-20); writeString("Velocity: ", 100,-20); writeValue((int)point[0].getv(),145,-20); glFlush(); glutSwapBuffers(); } void spinDisplay(void) { int i; printpointofview=0; if (point[0].gety() >= 0) { calcNewX(point[0]); calcNewY(point[0]); } if (point[1].gety() >= 0) { calcNewX(point[1]); calcNewY(point[1]); } t = t + dt; glutPostRedisplay(); } void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT); } void reshape(int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-75.0, 125.0, -90.0, 145.0, -100.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void mouse(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(spinDisplay); break; default: break; } } void keys(unsigned char key, int x, int y) { printpointofview=1; /* Use x, X, y, Y, z, and Z keys to move viewer */ if(key == 'x') viewer[0]+= 1.0; if(key == 'X') viewer[0]-= 1.0; if(key == 'y') viewer[1]+= 1.0; if(key == 'Y') viewer[1]-= 1.0; if(key == 'z') viewer[2]+= 1.0; if(key == 'Z') viewer[2]-= 1.0; display(); } void adjust_menu(int id) { if (id == 1) { point[0].setXY(0, 0); point[1].setXY(5, 0); t= 0.0; glutIdleFunc(spinDisplay); } else if (id == 8) exit(0); } void angle_menu(int id) { if (id == 1) { double angle = point[0].getangle(); point[0].setangle(angle * 1.1); } } void velocity_menu(int id) { if (id == 1) { double v = point[0].getv(); point[0].setv(v * 1.1); } } int main(int argc, char** argv) { int angle_sub_menu, velocity_sub_menu, time_sub_menu; a0 = .98; k = 2.0; m = 350; g= -9.8; a = a0 + -1*(k*Y0)/m; v = v0 + a*t; dt = .05; t = 0.0; angle=45.0; theta = angle*3.14159/180.0; point[0].setXY(0,0); point[0].setRadius(2); point[0].setColor(0.3, 0.3, 0.8); point[0].setv(30.0); point[0].setangle(angle); point[1].setXY(5, 0); point[1].setRadius(2); point[1].setColor(0.8, 0.3, 0.3); point[1].setm(1.5); point[1].setv(30.0); point[1].setangle(angle); glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB |GLUT_DEPTH); glutInitWindowSize (400, 400); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); angle_sub_menu = glutCreateMenu(angle_menu); glutAddMenuEntry("Increase Ball #1",1); glutAddMenuEntry("Increase Ball #2",2); glutAddMenuEntry("Increase Both Balls",3); glutAddMenuEntry("Decrease Ball #1",4); glutAddMenuEntry("Decrease Ball #2",5); glutAddMenuEntry("Decrease Both Balls",6); velocity_sub_menu = glutCreateMenu(velocity_menu); glutAddMenuEntry("Increase Ball #1",1); glutAddMenuEntry("Increase Ball #2",2); glutAddMenuEntry("Increase Both Balls",3); glutAddMenuEntry("Decrease Ball #1",4); glutAddMenuEntry("Decrease Ball #2",5); glutAddMenuEntry("Decrease Both Balls",6); glutCreateMenu(adjust_menu); glutAddMenuEntry("Start Demo",1); glutAddSubMenu("Adjust angle", angle_sub_menu); glutAddSubMenu("Adjust velocity", velocity_sub_menu); glutAddMenuEntry("Quit",8); glutAttachMenu(GLUT_LEFT_BUTTON); init (); init_String(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse); //glutMotionFunc(motion); glutKeyboardFunc(keys); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }