Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

1. write a chtlopenGL program simulating the double pendulum of strings of unit

ID: 2327130 • Letter: 1

Question

1. write a chtlopenGL program simulating the double pendulum of strings of unit length and unit masses.

Explanation / Answer

#define OSX #ifdef MAC #include "glut.h" #endif #ifdef OSX #include #endif #ifdef UNIX #include #endif #ifdef PC #include #endif #include #include #include // Global variables. int main_window; // The mainframe window. int pendulum_window; // The pendulum window. double pi; // pi double g; // The acceleration due to gravity. double length; // The length of the pendulum string. double theta_max[2]; // The maximum angle of swing (rad). double theta; // The current angle (rad). double omega; // The current angular speed (rad/sec). double alpha; // The current angular acceleration (rad/sec^2). double x; // The x position of the bob. double y; // The y position of the bob. clock_t t; // The time of last display. double period; // The period of the pendulum. int frame; // Frame counter. int frame_rate; // Frame rate (frames per second). clock_t frame_t; // Time used to calculate display frame rate. bool pendulum_adjust; // User is currently adjusting bob position. bool gravity_adjust; // User is currently adjusting gravity. // Function prototypes. int min(int a, int b); void printString_8x13(double x, double y, double z, char *s); void printString_9x15(double x, double y, double z, char *s); void printString_TimesRoman24(double x, double y, double z, char *s); void init(void); void main_display(void); void main_reshape(int width, int height); void main_mouseButton(int button, int state, int x, int y); void main_mouseMotion(int x, int y); void pendulum_display(void); void pendulum_reshape(int width, int height); void pendulum_mouseButton(int button, int state, int x, int y); void pendulum_mouseMotion(int x, int y); void idle(void); void integrate_motion(double & theta, double & omega, double & alpha, double length, double g, double delta_t); void integrate_period(double & period, double theta_max, double length, double g); int min(int a, int b) { if (b = 554 && x = 260 && y = 1.0) { frame_t = clock(); frame_rate = frame; frame = 0; } glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_LIGHTING); // The pendulum support block. glColor3f(0.8, 0.8, 0.8); glBegin(GL_QUADS); glNormal3f( 0.0, 0.0, 1.0); glVertex3d(-0.3, 0.0, 0.0); glVertex3d( 0.3, 0.0, 0.0); glVertex3d( 0.3, 0.3, 0.0); glVertex3d(-0.3, 0.3, 0.0); glEnd(); // The pendulum line. glColor3f(0.8, 0.8, 0.8); glBegin(GL_LINES); glVertex3d(0.0, 0.0, 0.0); glVertex3d(x, y, 0.0); glEnd(); // The pendulum bob. glColor3f(0.2, 0.65, 0.9); glPushMatrix(); glTranslated(x, y, 0.0); glutSolidSphere(0.32, 30, 30); glPopMatrix(); glDisable(GL_LIGHTING); // Status messages: glColor3f(0.9, 0.9, 0.9); // Print theta max, theta, omega, and alpha. sprintf(status, "THETA MAX %7.2f degrees", theta_max[0]*180.0/pi); printString_8x13(-3.8, 3.70, 0, status); sprintf(status, "THETA %7.2f degrees", theta*180.0/pi); printString_8x13(-3.8, 3.45, 0, status); sprintf(status, "OMEGA %10.2f degrees/s", omega*180.0/pi); printString_8x13(-3.8, 3.20, 0, status); sprintf(status, "ALPHA %10.2f degrees/s^2", alpha*180.0/pi); printString_8x13(-3.8, 2.95, 0, status); // Print length, acceleration due to gravity, period, and frame rate. sprintf(status, "LENGTH %7.2f meters", length); printString_8x13(0.6, 3.70, 0, status); sprintf(status, "GRAVITY %7.2f m/s^2", g); printString_8x13(0.6, 3.45, 0, status); sprintf(status, "PERIOD %7.2f seconds", period); printString_8x13(0.6, 3.20, 0, status); sprintf(status, "FRAME RATE %4d fps", frame_rate); printString_8x13(0.6, 2.95, 0, status); // Print instructions. sprintf(status, "Use the mouse to position the pendulum bob."); printString_9x15(-3.8, -3.85, 0, status); glutSwapBuffers(); } void pendulum_reshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Scale projection view when window is resized. if (width pi) theta = theta - 2*pi; else if (theta < -pi) theta = theta + 2*pi; // Measure theta_max for each swing direction and calculate period. if (theta == fabs(theta) && omega == fabs(omega) && theta > theta_max[1]) { theta_max[1] = theta; } else if (theta == -fabs(theta) && omega == -fabs(omega) && theta = 0.0) { k1 = h * omega; k2 = h * (omega + h/2.0); k3 = h * (omega + h/2.0); k4 = h * (omega + h); theta += (k1 + 2.0*k2 + 2.0*k3 + k4) / 6.0; k1 = h * (-g/length * sin(theta)); k2 = h * (-g/length * sin(theta + h/2.0)); k3 = h * (-g/length * sin(theta + h/2.0)); k4 = h * (-g/length * sin(theta + h)); omega += (k1 + 2.0*k2 + 2.0*k3 + k4) / 6.0; delta_t -= h; } // Calculate angular acceleration. alpha = -g/length * sin(theta); } void integrate_period(double & period, double theta_max, double length, double g) { double pi; double m; // Period equation parameter for elliptic integral. double M, L, R; // Midpoint, left, and right evaluation terms. double theta; double delta_theta; period = 0.0; pi = 4.0 * atan(1.0); m = sin(0.5*theta_max); // Evaluating at 100 points between 0 and pi/2. delta_theta = (pi/2.0)/100.0; for (theta = delta_theta; theta