/** * Robert Krzyzanowski * Buffon's Needle * MTH341 Enrichment */ #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef vector needle; vector needles; void main(int, char**); void display(void); void drawField(void); void dropNeedle(void); void drawNeedles(void); void displayInfo(void); bool needleOnLine(needle n); // Pre-defined colors enum colorDefs {PBLACK, PWHITE, PRED, PBLUE, PGREEN, PCYAN, PMAGENTA, PYELLOW, PGRAY}; float colors[9][3] = {{0.0f,0.0f,0.0f}, {1.0f,1.0f,1.0f}, {1.0f,0.0f,0.0f}, {0.0f,0.0f,0.5f}, {0.0f,0.5f,0.0f}, {0.0f, 0.8f, 0.8f}, {0.4f, 0.0f, 0.4f}, {1.0f, 1.0f, 0.0f}, {0.5f, 0.5f, 0.5f}}; // Graphical variables. int scrWidth = 800, scrHeight = 800; // Screen width and height. int scrX = 250, scrY = 100; //Screen X and Y. char* winTitle = "Buffon's Needles by Robert Krzyzanowski"; // Window title. float D = 100; float L = 0; int C = 5; int lastClock = 0; int needlesOnD = 0; void main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowSize(scrWidth, scrHeight); glutInitWindowPosition(scrX,scrY); glutCreateWindow(winTitle); glutDisplayFunc(display); glutIdleFunc(display); glClearColor(1.0, 1.0, 1.0, 1.0); glColor3f(0.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (float)scrWidth, 0.0, (float)scrHeight); glMatrixMode(GL_MODELVIEW); srand(time(NULL)); for(int i =0;i<100;i++)rand(); if (argc >= 2) D = atof(argv[1]); if (argc >= 3) L = atof(argv[1]); if (argc >= 4) C = atoi(argv[1]); if (C <= 0) C = 5; if (D<=0)D=100;if(L<=0)L=((float)rand()/RAND_MAX)*D; glutMainLoop(); cout << "\n\nPress enter to end.\n"; while (getch()!='\r'); } void display(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3fv(colors[PWHITE]); glBegin(GL_QUADS); glVertex2f(0.0f, 0.0f); glVertex2f(0.0f, scrHeight); glVertex2f(scrWidth, scrHeight); glVertex2f(scrWidth, 0.0f); glEnd(); if (clock() - lastClock > C) { lastClock = clock(); dropNeedle(); } drawField(); drawNeedles(); } void drawField() { glColor3fv(colors[PBLACK]); glBegin(GL_LINES); for(int i = 1; i*D < scrHeight; i++) { glVertex2f(0.0f, i*D); glVertex2f(scrWidth, i*D); } glEnd(); } void dropNeedle() { needle n; n.push_back(((float)rand()/RAND_MAX)*scrWidth); n.push_back(((float)rand()/RAND_MAX)*scrHeight); n.push_back(((float)rand()/RAND_MAX)*3.14159); needles.push_back(n); if (needleOnLine(n)) needlesOnD++; displayInfo(); } void drawNeedles() { glBegin(GL_LINES); for(int i = 0; i < needles.size(); i++) { needle n = needles[i]; if ( needleOnLine(n) ) { glColor3fv(colors[PRED]); } else { glColor3fv(colors[PBLACK]); } glVertex2f(n[0] + L/2 * sin(n[2]), n[1] - L/2 * cos(n[2])); glVertex2f(n[0] - L/2 * sin(n[2]), n[1] + L/2 * cos(n[2])); } glEnd(); } double absf(float f) { return (f>0?f:-f); } void displayInfo() { system("cls"); float ratio = (float)needlesOnD / needles.size() ; float Tratio = 2*L/(3.14159*D); double pi_est = 1/((double)needlesOnD / needles.size())*2*L/D; cout << "Buffon's Needle by Robert Krzyzanowski\n"; cout << "**************************************\n"; cout << "D: " << setprecision(2) << fixed << D << "\tL: " << setprecision(2) << fixed << L << endl; cout << "Needles dropped: " << needles.size() << endl; cout << "Needles on a line: " << needlesOnD << endl; cout << "Needles not on a line: " << (needles.size() - needlesOnD) << endl; cout << "Ratio: " << setprecision(3) << ratio << endl; cout << "Theoretical estimate: 2L/pi*D = " << Tratio << endl; cout << "Error: " << setprecision(2) <<(ratio>0?((float)absf(ratio-Tratio)/ratio*100):999) << "%" << endl; cout << "Estimate of pi: " << pi_est << endl; } bool needleOnLine(needle n) { return (abs(floor((n[1] + L/2 * cos(n[2]))/D) - floor((n[1] - L/2 * cos(n[2]))/D)) > 0); }