From 496c1022dbe986dd5a14ab7de0e49e1d6e31b4be Mon Sep 17 00:00:00 2001 From: Joshua Coles Date: Thu, 9 Feb 2023 12:41:41 +0000 Subject: [PATCH] Format --- DLASystem.cpp | 411 +++++++++++++++++++++++++------------------------- DLASystem.h | 64 +++++--- Particle.h | 14 +- Window.cpp | 27 ++-- Window.h | 20 +-- mainDLA.cpp | 251 +++++++++++++++--------------- rnd.h | 45 +++--- 7 files changed, 428 insertions(+), 404 deletions(-) diff --git a/DLASystem.cpp b/DLASystem.cpp index c174371..0011eff 100644 --- a/DLASystem.cpp +++ b/DLASystem.cpp @@ -6,11 +6,11 @@ // colors namespace colours { - GLfloat blue[] = { 0.1, 0.3, 0.9, 1.0 }; // blue - GLfloat red[] = { 1.0, 0.2, 0.1, 0.2 }; // red - GLfloat green[] = { 0.3, 0.6, 0.3, 1.0 }; // green - GLfloat paleGrey[] = { 0.7, 0.7, 0.7, 1.0 }; // green - GLfloat darkGrey[] = { 0.2, 0.2, 0.2, 1.0 }; // green + GLfloat blue[] = {0.1, 0.3, 0.9, 1.0}; // blue + GLfloat red[] = {1.0, 0.2, 0.1, 0.2}; // red + GLfloat green[] = {0.3, 0.6, 0.3, 1.0}; // green + GLfloat paleGrey[] = {0.7, 0.7, 0.7, 1.0}; // green + GLfloat darkGrey[] = {0.2, 0.2, 0.2, 1.0}; // green } @@ -18,53 +18,53 @@ namespace colours { // if there is an active particle then it gets moved, // if not then add a particle void DLASystem::Update() { - if (lastParticleIsActive == 1) - moveLastParticle(); - else if (numParticles < endNum) { - addParticleOnAddCircle(); - setParticleActive(); - } - if (lastParticleIsActive == 0 || slowNotFast == 1) - glutPostRedisplay(); //Tell GLUT that the display has changed + if (lastParticleIsActive == 1) + moveLastParticle(); + else if (numParticles < endNum) { + addParticleOnAddCircle(); + setParticleActive(); + } + if (lastParticleIsActive == 0 || slowNotFast == 1) + glutPostRedisplay(); //Tell GLUT that the display has changed } void DLASystem::clearParticles() { - // delete particles and the particle list - for (int i = 0; i < numParticles; i++) { - delete particleList[i]; - } - particleList.clear(); - numParticles = 0; + // delete particles and the particle list + for (int i = 0; i < numParticles; i++) { + delete particleList[i]; + } + particleList.clear(); + numParticles = 0; } // remove any existing particles and setup initial condition void DLASystem::Reset() { - // stop running - running = 0; + // stop running + running = 0; - clearParticles(); + clearParticles(); - lastParticleIsActive = 0; + lastParticleIsActive = 0; - // set the grid to zero - for (int i = 0; i < gridSize; i++) { - for (int j = 0; j < gridSize; j++) { - grid[i][j] = 0; - } - } + // set the grid to zero + for (int i = 0; i < gridSize; i++) { + for (int j = 0; j < gridSize; j++) { + grid[i][j] = 0; + } + } - // setup initial condition and parameters - addCircle = 10; - killCircle = 2.0*addCircle; - clusterRadius = 0.0; - // add a single particle at the origin - double pos[] = { 0.0, 0.0 }; - addParticle(pos); + // setup initial condition and parameters + addCircle = 10; + killCircle = 2.0 * addCircle; + clusterRadius = 0.0; + // add a single particle at the origin + double pos[] = {0.0, 0.0}; + addParticle(pos); - // set the view - int InitialViewSize = 40; - setViewSize(InitialViewSize); + // set the view + int InitialViewSize = 40; + setViewSize(InitialViewSize); } @@ -72,248 +72,245 @@ void DLASystem::Reset() { // note the position has the initial particle at (0,0) // but this corresponds to the middle of the grid array ie grid[ halfGrid ][ halfGrid ] void DLASystem::setGrid(double pos[], int val) { - int halfGrid = gridSize / 2; - grid[(int)(pos[0] + halfGrid)][(int)(pos[1] + halfGrid)] = val; + int halfGrid = gridSize / 2; + grid[(int) (pos[0] + halfGrid)][(int) (pos[1] + halfGrid)] = val; } // read the grid cell for a given position int DLASystem::readGrid(double pos[]) { - int halfGrid = gridSize / 2; - return grid[(int)(pos[0] + halfGrid)][(int)(pos[1] + halfGrid)]; + int halfGrid = gridSize / 2; + return grid[(int) (pos[0] + halfGrid)][(int) (pos[1] + halfGrid)]; } // check if the cluster is big enough and we should stop: // to be safe, we need the killCircle to be at least 2 less than the edge of the grid int DLASystem::checkStop() { - if (killCircle + 2 >= gridSize / 2) { - pauseRunning(); - cout << "STOP" << endl; - glutPostRedisplay(); // update display - return 1; - } - else return 0; + if (killCircle + 2 >= gridSize / 2) { + pauseRunning(); + cout << "STOP" << endl; + glutPostRedisplay(); // update display + return 1; + } else return 0; } // add a particle to the system at a specific position void DLASystem::addParticle(double pos[]) { - // create a new particle - Particle * p = new Particle(pos); - // push_back means "add this to the end of the list" - particleList.push_back(p); - numParticles++; + // create a new particle + Particle *p = new Particle(pos); + // push_back means "add this to the end of the list" + particleList.push_back(p); + numParticles++; - // pos coordinates should be -gridSize/2 < x < gridSize/2 - setGrid(pos, 1); + // pos coordinates should be -gridSize/2 < x < gridSize/2 + setGrid(pos, 1); } // add a particle to the system at a random position on the addCircle // if we hit an occupied site then we do nothing except print a message // (this should never happen) void DLASystem::addParticleOnAddCircle() { - double pos[2]; - double theta = rgen.random01() * 2 * M_PI; - pos[0] = ceil(addCircle * cos(theta)); - pos[1] = ceil(addCircle * sin(theta)); - if (readGrid(pos) == 0) - addParticle(pos); - else - cout << "FAIL " << pos[0] << " " << pos[1] << endl; + double pos[2]; + double theta = rgen.random01() * 2 * M_PI; + pos[0] = ceil(addCircle * cos(theta)); + pos[1] = ceil(addCircle * sin(theta)); + if (readGrid(pos) == 0) + addParticle(pos); + else + cout << "FAIL " << pos[0] << " " << pos[1] << endl; } // send back the position of a neighbour of a given grid cell // NOTE: there is no check that the neighbour is inside the grid, // this has to be done separately... void DLASystem::setPosNeighbour(double setpos[], double pos[], int val) { - switch (val) { - case 0: - setpos[0] = pos[0] + 1.0; - setpos[1] = pos[1]; - break; - case 1: - setpos[0] = pos[0] - 1.0; - setpos[1] = pos[1]; - break; - case 2: - setpos[0] = pos[0]; - setpos[1] = pos[1] + 1.0; - break; - case 3: - setpos[0] = pos[0]; - setpos[1] = pos[1] - 1.0; - break; - } + switch (val) { + case 0: + setpos[0] = pos[0] + 1.0; + setpos[1] = pos[1]; + break; + case 1: + setpos[0] = pos[0] - 1.0; + setpos[1] = pos[1]; + break; + case 2: + setpos[0] = pos[0]; + setpos[1] = pos[1] + 1.0; + break; + case 3: + setpos[0] = pos[0]; + setpos[1] = pos[1] - 1.0; + break; + } } // if the view is smaller than the kill circle then increase the view area (zoom out) void DLASystem::updateViewSize() { - double mult = 1.2; - if (viewSize < 2.0*killCircle) { - setViewSize(viewSize * mult); - } + double mult = 1.2; + if (viewSize < 2.0 * killCircle) { + setViewSize(viewSize * mult); + } } // set the view to be the size of the add circle (ie zoom in on the cluster) void DLASystem::viewAddCircle() { - setViewSize(2.0*addCircle); // factor of 2 is to go from radius to diameter + setViewSize(2.0 * addCircle); // factor of 2 is to go from radius to diameter } // when we add a particle to the cluster, we should update the cluster radius // and the sizes of the addCircle and the killCircle void DLASystem::updateClusterRadius(double pos[]) { - double rr = distanceFromOrigin(pos); - if (rr > clusterRadius) { - clusterRadius = rr; - // this is how big addCircle is supposed to be: - // either 20% more than cluster radius, or at least 5 bigger. - double check = clusterRadius * addRatio; - if (check < clusterRadius + 5) - check = clusterRadius + 5; - // if it is smaller then update everything... - if (addCircle < check) { - addCircle = check; - killCircle = killRatio * addCircle; - updateViewSize(); - } - checkStop(); - } + double rr = distanceFromOrigin(pos); + if (rr > clusterRadius) { + clusterRadius = rr; + // this is how big addCircle is supposed to be: + // either 20% more than cluster radius, or at least 5 bigger. + double check = clusterRadius * addRatio; + if (check < clusterRadius + 5) + check = clusterRadius + 5; + // if it is smaller then update everything... + if (addCircle < check) { + addCircle = check; + killCircle = killRatio * addCircle; + updateViewSize(); + } + checkStop(); + } } // make a random move of the last particle in the particleList void DLASystem::moveLastParticle() { - int rr = rgen.randomInt(4); // pick a random number in the range 0-3, which direction do we hop? - double newpos[2]; + int rr = rgen.randomInt(4); // pick a random number in the range 0-3, which direction do we hop? + double newpos[2]; - Particle *lastP = particleList[numParticles - 1]; + Particle *lastP = particleList[numParticles - 1]; - setPosNeighbour(newpos, lastP->pos, rr); + setPosNeighbour(newpos, lastP->pos, rr); - if (distanceFromOrigin(newpos) > killCircle) { - //cout << "#deleting particle" << endl; - setGrid(lastP->pos, 0); - particleList.pop_back(); // remove particle from particleList - numParticles--; - setParticleInactive(); - } - // check if destination is empty - else if (readGrid(newpos) == 0) { - setGrid(lastP->pos, 0); // set the old grid site to empty - // update the position - particleList[numParticles - 1]->pos[0] = newpos[0]; - particleList[numParticles - 1]->pos[1] = newpos[1]; - setGrid(lastP->pos, 1); // set the new grid site to be occupied + if (distanceFromOrigin(newpos) > killCircle) { + //cout << "#deleting particle" << endl; + setGrid(lastP->pos, 0); + particleList.pop_back(); // remove particle from particleList + numParticles--; + setParticleInactive(); + } + // check if destination is empty + else if (readGrid(newpos) == 0) { + setGrid(lastP->pos, 0); // set the old grid site to empty + // update the position + particleList[numParticles - 1]->pos[0] = newpos[0]; + particleList[numParticles - 1]->pos[1] = newpos[1]; + setGrid(lastP->pos, 1); // set the new grid site to be occupied - // check if we stick - if (checkStick()) { - //cout << "stick" << endl; - setParticleInactive(); // make the particle inactive (stuck) - updateClusterRadius(lastP->pos); // update the cluster radius, addCircle, etc. + // check if we stick + if (checkStick()) { + //cout << "stick" << endl; + setParticleInactive(); // make the particle inactive (stuck) + updateClusterRadius(lastP->pos); // update the cluster radius, addCircle, etc. - if (numParticles % 100 == 0 && logfile.is_open()) { - logfile << numParticles << " " << clusterRadius << endl; - } - } - } - else { - // if we get to here then we are trying to move to an occupied site - // (this should never happen as long as the sticking probability is 1.0) - cout << "reject " << rr << endl; - cout << lastP->pos[0] << " " << lastP->pos[1] << endl; - //cout << newpos[0] << " " << newpos[1] << " " << (int)newpos[0] << endl; - //printOccupied(); - } + if (numParticles % 100 == 0 && logfile.is_open()) { + logfile << numParticles << " " << clusterRadius << endl; + } + } + } else { + // if we get to here then we are trying to move to an occupied site + // (this should never happen as long as the sticking probability is 1.0) + cout << "reject " << rr << endl; + cout << lastP->pos[0] << " " << lastP->pos[1] << endl; + //cout << newpos[0] << " " << newpos[1] << " " << (int)newpos[0] << endl; + //printOccupied(); + } } // check if the last particle should stick (to a neighbour) int DLASystem::checkStick() { - Particle *lastP = particleList[numParticles - 1]; - int result = 0; - // loop over neighbours - for (int i = 0; i < 4; i++) { - double checkpos[2]; - setPosNeighbour(checkpos, lastP->pos, i); - // if the neighbour is occupied... - if (readGrid(checkpos) == 1) - result = 1; - } - return result; + Particle *lastP = particleList[numParticles - 1]; + int result = 0; + // loop over neighbours + for (int i = 0; i < 4; i++) { + double checkpos[2]; + setPosNeighbour(checkpos, lastP->pos, i); + // if the neighbour is occupied... + if (readGrid(checkpos) == 1) + result = 1; + } + return result; } // constructor DLASystem::DLASystem(Window *set_win) { - cout << "creating system, gridSize " << gridSize << endl; - win = set_win; - numParticles = 0; - endNum = 1000; + cout << "creating system, gridSize " << gridSize << endl; + win = set_win; + numParticles = 0; + endNum = 1000; - // allocate memory for the grid, remember to free the memory in destructor - grid = new int*[gridSize]; - for (int i = 0; i < gridSize; i++) { - grid[i] = new int[gridSize]; - } - slowNotFast = 1; - // reset initial parameters - Reset(); + // allocate memory for the grid, remember to free the memory in destructor + grid = new int *[gridSize]; + for (int i = 0; i < gridSize; i++) { + grid[i] = new int[gridSize]; + } + slowNotFast = 1; + // reset initial parameters + Reset(); - addRatio = 1.2; // how much bigger the addCircle should be, compared to cluster radius - killRatio = 1.7; // how much bigger is the killCircle, compared to the addCircle + addRatio = 1.2; // how much bigger the addCircle should be, compared to cluster radius + killRatio = 1.7; // how much bigger is the killCircle, compared to the addCircle - // this opens a logfile, if we want to... - //logfile.open("opfile.txt"); + // this opens a logfile, if we want to... + //logfile.open("opfile.txt"); } // destructor DLASystem::~DLASystem() { - // strictly we should not print inside the destructor but never mind... - cout << "deleting system" << endl; - // delete the particles - clearParticles(); - // delete the grid - for (int i = 0; i < gridSize; i++) - delete[] grid[i]; - delete[] grid; + // strictly we should not print inside the destructor but never mind... + cout << "deleting system" << endl; + // delete the particles + clearParticles(); + // delete the grid + for (int i = 0; i < gridSize; i++) + delete[] grid[i]; + delete[] grid; - if (logfile.is_open()) - logfile.close(); + if (logfile.is_open()) + logfile.close(); } - // this draws the system void DLASystem::DrawSquares() { - // draw the particles - double halfSize = 0.5; - for (int p = 0; p < numParticles; p++) { - double *vec = particleList[p]->pos; - glPushMatrix(); - if (p == numParticles - 1 && lastParticleIsActive == 1) - glColor4fv(colours::red); - else if (p == 0) - glColor4fv(colours::green); - else - glColor4fv(colours::blue); - glRectd(drawScale*(vec[0] - halfSize), - drawScale*(vec[1] - halfSize), - drawScale*(vec[0] + halfSize), - drawScale*(vec[1] + halfSize)); - glPopMatrix(); - } + // draw the particles + double halfSize = 0.5; + for (int p = 0; p < numParticles; p++) { + double *vec = particleList[p]->pos; + glPushMatrix(); + if (p == numParticles - 1 && lastParticleIsActive == 1) + glColor4fv(colours::red); + else if (p == 0) + glColor4fv(colours::green); + else + glColor4fv(colours::blue); + glRectd(drawScale * (vec[0] - halfSize), + drawScale * (vec[1] - halfSize), + drawScale * (vec[0] + halfSize), + drawScale * (vec[1] + halfSize)); + glPopMatrix(); + } - // print some information (at top left) - // this ostringstream is a way to create a string with numbers and words (similar to cout << ... ) - ostringstream str; - str << "num " << numParticles << " size " << clusterRadius; + // print some information (at top left) + // this ostringstream is a way to create a string with numbers and words (similar to cout << ... ) + ostringstream str; + str << "num " << numParticles << " size " << clusterRadius; - // print the string - win->displayString(str, -0.9, 0.9, colours::red); + // print the string + win->displayString(str, -0.9, 0.9, colours::red); - // if we are paused then print this (at bottom left) - if (running == 0) { - ostringstream pauseStr; - pauseStr << "paused"; - win->displayString(pauseStr, -0.9, -0.9, colours::red); - } + // if we are paused then print this (at bottom left) + if (running == 0) { + ostringstream pauseStr; + pauseStr << "paused"; + win->displayString(pauseStr, -0.9, -0.9, colours::red); + } } diff --git a/DLASystem.h b/DLASystem.h index 4b05fe6..b0f5857 100644 --- a/DLASystem.h +++ b/DLASystem.h @@ -5,7 +5,9 @@ #include #include #include + #define _USE_MATH_DEFINES + #include #include #include @@ -19,13 +21,13 @@ using namespace std; class DLASystem { - private: - // these are private variables and functions that the user will not see - +private: + // these are private variables and functions that the user will not see + Window *win; // window in which the system is running - + // list of particles - vector particleList; + vector particleList; int numParticles; // delete particles and clear the particle list @@ -36,32 +38,32 @@ class DLASystem { // these are related to the DLA algorithm double addCircle; double killCircle; - + // size of grid static const int gridSize = 1600; int **grid; // this will be a 2d array that stores whether each site is occupied - + // the window draws only part of the grid, viewSize controls how much... double viewSize; double drawScale; - + // random number generator, class name is rnd, instance is rgen rnd rgen; - + // output file (not used at the moment) ofstream logfile; - + // number of particles at which the simulation will stop // (the value is set in constructor) int endNum; - + // the values of these variables are set in the constructor double addRatio; // how much bigger the addCircle should be, compared to cluster radius double killRatio; // how much bigger is the killCircle, compared to the addCircle - - public: - // these are public variables and functions + +public: + // these are public variables and functions // update the system: if there is an active particle then move it, // else create a new particle (on the adding circle) @@ -69,21 +71,22 @@ class DLASystem { // draw particles as squares void DrawSquares(); - + // is the simulation running (1) or paused (0) ? int running; - + // slowNotFast is +1 for slow running, 0 for fast int slowNotFast; // lastParticleIsActive is +1 if there is an active particle in the system, otherwise 0 int lastParticleIsActive; - + // constructor DLASystem(Window *set_win); + // destructor ~DLASystem(); - + // delete all particles and reset void Reset(); @@ -92,20 +95,27 @@ class DLASystem { // check whether we should stop (eg the cluster has reached the edge of the grid) int checkStop(); - + // stop/start the algorithm - void setRunning() { if ( checkStop()==0 ) running = 1; } + void setRunning() { if (checkStop() == 0) running = 1; } + void pauseRunning() { running = 0; } + // set whether it runs fast or slow void setSlow() { slowNotFast = 1; } + void setFast() { slowNotFast = 0; } + void setSuperFast() { slowNotFast = -1; } // set which part of the grid is visible on the screen // basically the screen shows co-ordinates -vv < x < vv // where vv is the input value - void setViewSize(double vv) { viewSize = vv; drawScale = 2.0/viewSize; } - + void setViewSize(double vv) { + viewSize = vv; + drawScale = 2.0 / viewSize; + } + // if the killcircle is almost as big as the view then increase the view void updateViewSize(); @@ -113,23 +123,26 @@ class DLASystem { void viewAddCircle(); // if pos is outside the cluster radius then set clusterRadius to be the distance to pos. - void updateClusterRadius( double pos[] ); + void updateClusterRadius(double pos[]); // set and read grid entries associated with a given position void setGrid(double pos[], int val); + int readGrid(double pos[]); // return the distance of a given point from the origin double distanceFromOrigin(double pos[]) { - return sqrt( pos[0]*pos[0] + pos[1]*pos[1] ); + return sqrt(pos[0] * pos[0] + pos[1] * pos[1]); } // set whether there is an active particle in the system or not - void setParticleActive() { lastParticleIsActive = 1; } + void setParticleActive() { lastParticleIsActive = 1; } + void setParticleInactive() { lastParticleIsActive = 0; } // add a particle at pos void addParticle(double pos[]); + // add a particle at a random point on the addCircle void addParticleOnAddCircle(); @@ -150,5 +163,6 @@ class DLASystem { // it would be better for an OOP philosophy to make these member functions for the Window class // but we are being a bit lazy here void setWinBackgroundWhite() { glClearColor(1.0, 1.0, 1.0, 1.0); } + void setWinBackgroundBlack() { glClearColor(0.0, 0.0, 0.0, 0.0); } }; diff --git a/Particle.h b/Particle.h index d3a3d21..ed7e7df 100644 --- a/Particle.h +++ b/Particle.h @@ -1,20 +1,22 @@ #pragma once class Particle { - public: +public: static const int dim = 2; // we are in two dimensions double *pos; // pointer to an array of size dim, to store the position - + // default constructor Particle() { - pos = new double[dim]; + pos = new double[dim]; } + // constructor, with a specified initial position Particle(double set_pos[]) { - pos = new double[dim]; - for (int d=0;d #include "DLASystem.h" -#include "Window.h" +#include "Window.h" using namespace std; // functions which are needed for openGL go into a namespace so that we can identify them namespace drawFuncs { - void handleKeypress(unsigned char key, int x, int y); - void display(void); - void update(int val); - void introMessage(); + void handleKeypress(unsigned char key, int x, int y); + + void display(void); + + void update(int val); + + void introMessage(); } // this is a global pointer, which is how we access the system itself DLASystem *sys; int main(int argc, char **argv) { - // turn on glut - glutInit(&argc, argv); + // turn on glut + glutInit(&argc, argv); - int window_size[] = { 480,480 }; - string window_title("simple DLA simulation"); + int window_size[] = {480, 480}; + string window_title("simple DLA simulation"); - // create a window - Window *win = new Window(window_size,window_title); + // create a window + Window *win = new Window(window_size, window_title); - // create the system - sys = new DLASystem(win); - - // this is the seed for the random numbers - int seed = 6; - cout << "setting seed " << seed << endl; - sys->setSeed(seed); - - // print the "help" message to the console - drawFuncs::introMessage(); - - // tell openGL how to redraw the screen and respond to the keyboard - glutDisplayFunc( drawFuncs::display ); - glutKeyboardFunc( drawFuncs::handleKeypress ); - - // tell openGL to do its first update after waiting 10ms - int wait = 10; - int val = 0; - glutTimerFunc(wait, drawFuncs::update, val); + // create the system + sys = new DLASystem(win); - // start the openGL stuff - glutMainLoop(); + // this is the seed for the random numbers + int seed = 6; + cout << "setting seed " << seed << endl; + sys->setSeed(seed); - return 0; + // print the "help" message to the console + drawFuncs::introMessage(); + + // tell openGL how to redraw the screen and respond to the keyboard + glutDisplayFunc(drawFuncs::display); + glutKeyboardFunc(drawFuncs::handleKeypress); + + // tell openGL to do its first update after waiting 10ms + int wait = 10; + int val = 0; + glutTimerFunc(wait, drawFuncs::update, val); + + // start the openGL stuff + glutMainLoop(); + + return 0; } // this is just a help message void drawFuncs::introMessage() { - cout << "Keys (while in graphics window):" << endl << " q or e to quit (or exit)" << endl; - cout << " h to print this message (help)" << endl; - cout << " u for a single update" << endl; - cout << " g to start running (go)" << endl; - cout << " p to pause running" << endl; - cout << " s to run in slow-mode" << endl; - cout << " f to run in fast-mode" << endl; - cout << " r to clear everything (reset)" << endl; - cout << " z to pause and zoom in" << endl; - cout << " w or b to change background colour to white or black" << endl; + cout << "Keys (while in graphics window):" << endl << " q or e to quit (or exit)" << endl; + cout << " h to print this message (help)" << endl; + cout << " u for a single update" << endl; + cout << " g to start running (go)" << endl; + cout << " p to pause running" << endl; + cout << " s to run in slow-mode" << endl; + cout << " f to run in fast-mode" << endl; + cout << " r to clear everything (reset)" << endl; + cout << " z to pause and zoom in" << endl; + cout << " w or b to change background colour to white or black" << endl; } // openGL function deals with the keyboard void drawFuncs::handleKeypress(unsigned char key, int x, int y) { - switch (key) { - case 'h': - drawFuncs::introMessage(); - break; - case 'q': - case 'e': - cout << "Exiting..." << endl; - // delete the system - delete sys; - exit(0); - break; - case 'p': - cout << "pause" << endl; - sys->pauseRunning(); - break; - case 'g': - cout << "go" << endl; - sys->setRunning(); - glutTimerFunc(0, drawFuncs::update, 0); - break; - case 's': - cout << "slow" << endl; - sys->setSlow(); - break; - case 'w': - cout << "white" << endl; - sys->setWinBackgroundWhite(); - break; - case 'b': - cout << "black" << endl; - sys->setWinBackgroundBlack(); - break; - case 'f': - cout << "fast" << endl; - sys->setFast(); - break; - case 'r': - cout << "reset" << endl; - sys->Reset(); - break; - case 'z': - cout << "zoom" << endl; - sys->pauseRunning(); - sys->viewAddCircle(); - break; - case 'u': - cout << "upd" << endl; - sys->Update(); - break; - } - // tell openGL to redraw the window - glutPostRedisplay(); + switch (key) { + case 'h': + drawFuncs::introMessage(); + break; + case 'q': + case 'e': + cout << "Exiting..." << endl; + // delete the system + delete sys; + exit(0); + break; + case 'p': + cout << "pause" << endl; + sys->pauseRunning(); + break; + case 'g': + cout << "go" << endl; + sys->setRunning(); + glutTimerFunc(0, drawFuncs::update, 0); + break; + case 's': + cout << "slow" << endl; + sys->setSlow(); + break; + case 'w': + cout << "white" << endl; + sys->setWinBackgroundWhite(); + break; + case 'b': + cout << "black" << endl; + sys->setWinBackgroundBlack(); + break; + case 'f': + cout << "fast" << endl; + sys->setFast(); + break; + case 'r': + cout << "reset" << endl; + sys->Reset(); + break; + case 'z': + cout << "zoom" << endl; + sys->pauseRunning(); + sys->viewAddCircle(); + break; + case 'u': + cout << "upd" << endl; + sys->Update(); + break; + } + // tell openGL to redraw the window + glutPostRedisplay(); } // this function gets called whenever the algorithm should do its update void drawFuncs::update(int val) { - int wait; // time to wait between updates (milliseconds) - - if ( sys->running ) { - if ( sys->slowNotFast == 1) - wait = 10; - else - wait = 0; - - sys->Update(); - - // tell openGL to call this funtion again after "wait" milliseconds - glutTimerFunc(wait, drawFuncs::update, 0); - } - + int wait; // time to wait between updates (milliseconds) + + if (sys->running) { + if (sys->slowNotFast == 1) + wait = 10; + else + wait = 0; + + sys->Update(); + + // tell openGL to call this funtion again after "wait" milliseconds + glutTimerFunc(wait, drawFuncs::update, 0); + } + } // this function redraws the window when necessary void drawFuncs::display() { - // Clear the window or more specifically the frame buffer... - // This happens by replacing all the contents of the frame - // buffer by the clear color (black in our case) - glClear(GL_COLOR_BUFFER_BIT); + // Clear the window or more specifically the frame buffer... + // This happens by replacing all the contents of the frame + // buffer by the clear color (black in our case) + glClear(GL_COLOR_BUFFER_BIT); - // this puts the camera at the origin (not sure why) with (I think) z axis out of page and y axis up - // there is also the question of the GL perspective which is not set up in any clear way at the moment - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt(0.0, 0.0, 1.0, /* camera position */ - 0.0, 0.0, -1.0, /* point to look at */ - 0.0, 1.0, 0.0); /* up direction */ + // this puts the camera at the origin (not sure why) with (I think) z axis out of page and y axis up + // there is also the question of the GL perspective which is not set up in any clear way at the moment + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0.0, 0.0, 1.0, /* camera position */ + 0.0, 0.0, -1.0, /* point to look at */ + 0.0, 1.0, 0.0); /* up direction */ - //sys->DrawSpheres(); - sys->DrawSquares(); + //sys->DrawSpheres(); + sys->DrawSquares(); - // Swap contents of backward and forward frame buffers - glutSwapBuffers(); + // Swap contents of backward and forward frame buffers + glutSwapBuffers(); } diff --git a/rnd.h b/rnd.h index 98e6c29..5ea3779 100644 --- a/rnd.h +++ b/rnd.h @@ -1,4 +1,5 @@ #pragma once + #include // ... don't worry how this all works @@ -8,26 +9,32 @@ class rnd { private: - // nuts and bolts.. should not need to touch this. - std::default_random_engine generator; - int genMax; - std::uniform_int_distribution *intmax; - std::uniform_real_distribution *real01; + // nuts and bolts.. should not need to touch this. + std::default_random_engine generator; + int genMax; + std::uniform_int_distribution *intmax; + std::uniform_real_distribution *real01; public: - // constructor - rnd() { - genMax = 0x7fffffff; - //cout << "genMax is " << generator.max() << endl; - intmax = new std::uniform_int_distribution(0, genMax); - real01 = new std::uniform_real_distribution(0.0, 1.0); - } - // destructor - ~rnd() { delete intmax; delete real01; } + // constructor + rnd() { + genMax = 0x7fffffff; + //cout << "genMax is " << generator.max() << endl; + intmax = new std::uniform_int_distribution(0, genMax); + real01 = new std::uniform_real_distribution(0.0, 1.0); + } - // set the random seed - void setSeed(int seed) { generator.seed(seed); } - // member functions for generating random double in [0,1] and random integer in [0,max-1] - double random01() { return (*real01)(generator); } - int randomInt(int max) { return (*intmax)(generator) % max; } + // destructor + ~rnd() { + delete intmax; + delete real01; + } + + // set the random seed + void setSeed(int seed) { generator.seed(seed); } + + // member functions for generating random double in [0,1] and random integer in [0,max-1] + double random01() { return (*real01)(generator); } + + int randomInt(int max) { return (*intmax)(generator) % max; } };