Compare commits

..

6 Commits

9 changed files with 195 additions and 524 deletions

1
.gitignore vendored
View File

@ -6,3 +6,4 @@
# Data files # Data files
*.csv *.csv
*.o

View File

@ -4,316 +4,241 @@
#include "DLASystem.h" #include "DLASystem.h"
// 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
}
// this function gets called every step, // this function gets called every step,
// if there is an active particle then it gets moved, // if there is an active particle then it gets moved,
// if not then add a particle // if not then add a particle
void DLASystem::Update() { void DLASystem::update() {
if (lastParticleIsActive == 1) if (lastParticleIsActive == 1) {
moveLastParticle(); moveLastParticle();
else if (numParticles < endNum) { } else if (numParticles < endNum) {
addParticleOnAddCircle(); addParticleOnAddCircle();
setParticleActive(); setParticleActive();
} } else {
if (lastParticleIsActive == 0 || slowNotFast == 1) this->running = false;
glutPostRedisplay(); //Tell GLUT that the display has changed }
} }
void DLASystem::clearParticles() { void DLASystem::clearParticles() {
// delete particles and the particle list // delete particles and the particle list
for (int i = 0; i < numParticles; i++) { for (int i = 0; i < numParticles; i++) {
delete particleList[i]; delete particleList[i];
} }
particleList.clear(); particleList.clear();
numParticles = 0; numParticles = 0;
} }
// remove any existing particles and setup initial condition // remove any existing particles and setup initial condition
void DLASystem::Reset() { void DLASystem::Reset() {
// stop running // stop running
running = 0; this->running = false;
clearParticles(); clearParticles();
lastParticleIsActive = 0; lastParticleIsActive = 0;
// set the grid to zero // set the grid to zero
for (int i = 0; i < gridSize; i++) { for (int i = 0; i < gridSize; i++) {
for (int j = 0; j < gridSize; j++) { for (int j = 0; j < gridSize; j++) {
grid[i][j] = 0; 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);
// set the view
int InitialViewSize = 40;
setViewSize(InitialViewSize);
// 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 value of a grid cell for a particular position // set the value of a grid cell for a particular position
// note the position has the initial particle at (0,0) // note the position has the initial particle at (0,0)
// but this corresponds to the middle of the grid array ie grid[ halfGrid ][ halfGrid ] // but this corresponds to the middle of the grid array ie grid[ halfGrid ][ halfGrid ]
void DLASystem::setGrid(double pos[], int val) { void DLASystem::setGrid(double pos[], int val) {
int halfGrid = gridSize / 2; int halfGrid = gridSize / 2;
grid[(int)(pos[0] + halfGrid)][(int)(pos[1] + halfGrid)] = val; grid[(int) (pos[0] + halfGrid)][(int) (pos[1] + halfGrid)] = val;
} }
// read the grid cell for a given position // read the grid cell for a given position
int DLASystem::readGrid(double pos[]) { int DLASystem::readGrid(double pos[]) {
int halfGrid = gridSize / 2; int halfGrid = gridSize / 2;
return grid[(int)(pos[0] + halfGrid)][(int)(pos[1] + halfGrid)]; return grid[(int) (pos[0] + halfGrid)][(int) (pos[1] + halfGrid)];
} }
// check if the cluster is big enough and we should stop: // 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 // to be safe, we need the killCircle to be at least 2 less than the edge of the grid
int DLASystem::checkStop() { int DLASystem::checkStop() {
if (killCircle + 2 >= gridSize / 2) { if (killCircle + 2 >= gridSize / 2) {
pauseRunning(); this->running = false;
cout << "STOP" << endl; cerr << "STOP" << endl;
glutPostRedisplay(); // update display return 1;
return 1; } else return 0;
}
else return 0;
} }
// add a particle to the system at a specific position // add a particle to the system at a specific position
void DLASystem::addParticle(double pos[]) { void DLASystem::addParticle(double pos[]) {
// create a new particle // create a new particle
Particle * p = new Particle(pos); Particle *p = new Particle(pos);
// push_back means "add this to the end of the list" // push_back means "add this to the end of the list"
particleList.push_back(p); particleList.push_back(p);
numParticles++; numParticles++;
// pos coordinates should be -gridSize/2 < x < gridSize/2 // pos coordinates should be -gridSize/2 < x < gridSize/2
setGrid(pos, 1); setGrid(pos, 1);
} }
// add a particle to the system at a random position on the addCircle // 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 // if we hit an occupied site then we do nothing except print a message
// (this should never happen) // (this should never happen)
void DLASystem::addParticleOnAddCircle() { void DLASystem::addParticleOnAddCircle() {
double pos[2]; double pos[2];
double theta = rgen.random01() * 2 * M_PI; double theta = rgen.random01() * 2 * M_PI;
pos[0] = ceil(addCircle * cos(theta)); pos[0] = ceil(addCircle * cos(theta));
pos[1] = ceil(addCircle * sin(theta)); pos[1] = ceil(addCircle * sin(theta));
if (readGrid(pos) == 0) if (readGrid(pos) == 0)
addParticle(pos); addParticle(pos);
else else
cout << "FAIL " << pos[0] << " " << pos[1] << endl; cerr << "FAIL " << pos[0] << " " << pos[1] << endl;
} }
// send back the position of a neighbour of a given grid cell // send back the position of a neighbour of a given grid cell
// NOTE: there is no check that the neighbour is inside the grid, // NOTE: there is no check that the neighbour is inside the grid,
// this has to be done separately... // this has to be done separately...
void DLASystem::setPosNeighbour(double setpos[], double pos[], int val) { void DLASystem::setPosNeighbour(double setpos[], double pos[], int val) {
switch (val) { switch (val) {
case 0: case 0:
setpos[0] = pos[0] + 1.0; setpos[0] = pos[0] + 1.0;
setpos[1] = pos[1]; setpos[1] = pos[1];
break; break;
case 1: case 1:
setpos[0] = pos[0] - 1.0; setpos[0] = pos[0] - 1.0;
setpos[1] = pos[1]; setpos[1] = pos[1];
break; break;
case 2: case 2:
setpos[0] = pos[0]; setpos[0] = pos[0];
setpos[1] = pos[1] + 1.0; setpos[1] = pos[1] + 1.0;
break; break;
case 3: case 3:
setpos[0] = pos[0]; setpos[0] = pos[0];
setpos[1] = pos[1] - 1.0; setpos[1] = pos[1] - 1.0;
break; 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);
}
}
// 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
} }
// when we add a particle to the cluster, we should update the cluster radius // when we add a particle to the cluster, we should update the cluster radius
// and the sizes of the addCircle and the killCircle // and the sizes of the addCircle and the killCircle
void DLASystem::updateClusterRadius(double pos[]) { void DLASystem::updateClusterRadius(double pos[]) {
double rr = distanceFromOrigin(pos); double rr = distanceFromOrigin(pos);
if (rr > clusterRadius) { if (rr > clusterRadius) {
clusterRadius = rr; clusterRadius = rr;
// this is how big addCircle is supposed to be: // this is how big addCircle is supposed to be:
// either 20% more than cluster radius, or at least 5 bigger. // either 20% more than cluster radius, or at least 5 bigger.
double check = clusterRadius * addRatio; double check = clusterRadius * addRatio;
if (check < clusterRadius + 5) if (check < clusterRadius + 5)
check = clusterRadius + 5; check = clusterRadius + 5;
// if it is smaller then update everything... // if it is smaller then update everything...
if (addCircle < check) { if (addCircle < check) {
addCircle = check; addCircle = check;
killCircle = killRatio * addCircle; killCircle = killRatio * addCircle;
updateViewSize(); }
} checkStop();
checkStop(); }
}
} }
// make a random move of the last particle in the particleList // make a random move of the last particle in the particleList
void DLASystem::moveLastParticle() { void DLASystem::moveLastParticle() {
int rr = rgen.randomInt(4); // pick a random number in the range 0-3, which direction do we hop? int rr = rgen.randomInt(4); // pick a random number in the range 0-3, which direction do we hop?
double newpos[2]; 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) { if (distanceFromOrigin(newpos) > killCircle) {
//cout << "#deleting particle" << endl; //cerr << "#deleting particle" << endl;
setGrid(lastP->pos, 0); setGrid(lastP->pos, 0);
particleList.pop_back(); // remove particle from particleList particleList.pop_back(); // remove particle from particleList
numParticles--; numParticles--;
setParticleInactive(); setParticleInactive();
} } else if (readGrid(newpos) == 0) {
// check if destination is empty setGrid(lastP->pos, 0); // set the old grid site to empty
else if (readGrid(newpos) == 0) { // update the position
setGrid(lastP->pos, 0); // set the old grid site to empty particleList[numParticles - 1]->pos[0] = newpos[0];
// update the position particleList[numParticles - 1]->pos[1] = newpos[1];
particleList[numParticles - 1]->pos[0] = newpos[0]; setGrid(lastP->pos, 1); // set the new grid site to be occupied
particleList[numParticles - 1]->pos[1] = newpos[1];
setGrid(lastP->pos, 1); // set the new grid site to be occupied
// check if we stick // check if we stick
if (checkStick()) { if (checkStick()) {
//cout << "stick" << endl; //cerr << "stick" << endl;
setParticleInactive(); // make the particle inactive (stuck) setParticleInactive(); // make the particle inactive (stuck)
updateClusterRadius(lastP->pos); // update the cluster radius, addCircle, etc. 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();
}
} }
// check if the last particle should stick (to a neighbour) // check if the last particle should stick (to a neighbour)
int DLASystem::checkStick() { int DLASystem::checkStick() {
Particle *lastP = particleList[numParticles - 1]; Particle *lastP = particleList[numParticles - 1];
int result = 0; // loop over neighbours
// loop over neighbours for (int i = 0; i < 4; i++) {
for (int i = 0; i < 4; i++) { double checkpos[2];
double checkpos[2]; setPosNeighbour(checkpos, lastP->pos, i);
setPosNeighbour(checkpos, lastP->pos, i); // if the neighbour is occupied and the particle will stick probabilistically.
// if the neighbour is occupied... if (readGrid(checkpos) == 1 && rgen.random01() < stickProbability) {
if (readGrid(checkpos) == 1) return 1;
result = 1; }
} }
return result;
return 0;
} }
// constructor // constructor
DLASystem::DLASystem(Window *set_win) { DLASystem::DLASystem(const int maxParticles, const string &csvPath, const double stickProbability) {
cout << "creating system, gridSize " << gridSize << endl; cerr << "creating system, gridSize " << gridSize << endl;
win = set_win; numParticles = 0;
numParticles = 0; endNum = maxParticles;
endNum = 1000; this->stickProbability = stickProbability;
// allocate memory for the grid, remember to free the memory in destructor // allocate memory for the grid, remember to free the memory in destructor
grid = new int*[gridSize]; grid = new int *[gridSize];
for (int i = 0; i < gridSize; i++) { for (int i = 0; i < gridSize; i++) {
grid[i] = new int[gridSize]; 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 // reset initial parameters
killRatio = 1.7; // how much bigger is the killCircle, compared to the addCircle Reset();
// this opens a logfile, if we want to... addRatio = 1.2; // how much bigger the addCircle should be, compared to cluster radius
//logfile.open("opfile.txt"); killRatio = 1.7; // how much bigger is the killCircle, compared to the addCircle
csv.open(csvPath);
} }
// destructor // destructor
DLASystem::~DLASystem() { DLASystem::~DLASystem() {
// strictly we should not print inside the destructor but never mind... // strictly we should not print inside the destructor but never mind...
cout << "deleting system" << endl; cerr << "deleting system" << endl;
// delete the particles // delete the particles
clearParticles(); clearParticles();
// delete the grid // delete the grid
for (int i = 0; i < gridSize; i++) for (int i = 0; i < gridSize; i++)
delete[] grid[i]; delete[] grid[i];
delete[] grid; delete[] grid;
if (logfile.is_open()) if (csv.is_open()) {
logfile.close(); csv.flush();
csv.close();
}
} }
void DLASystem::exportData() {
csv << "x,y" << endl;
for (auto particle: particleList) {
// this draws the system csv << particle->pos[0] << "," << particle->pos[1] << endl;
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();
}
// 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);
// 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);
}
} }

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <GLUT/glut.h>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <stdio.h> #include <stdio.h>
@ -11,7 +10,6 @@
#include <string> #include <string>
#include <sstream> #include <sstream>
#include "Window.h"
#include "Particle.h" #include "Particle.h"
#include "rnd.h" #include "rnd.h"
@ -21,13 +19,16 @@ using namespace std;
class DLASystem { class DLASystem {
private: private:
// these are private variables and functions that the user will not see // these are private variables and functions that the user will not see
Window *win; // window in which the system is running
// list of particles // list of particles
vector<Particle*> particleList; vector<Particle*> particleList;
int numParticles; int numParticles;
/*
* The probability that a particle will stick at a given site when adjacent.
* */
double stickProbability;
// delete particles and clear the particle list // delete particles and clear the particle list
void clearParticles(); void clearParticles();
@ -41,15 +42,11 @@ class DLASystem {
static const int gridSize = 1600; static const int gridSize = 1600;
int **grid; // this will be a 2d array that stores whether each site is occupied 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 // random number generator, class name is rnd, instance is rgen
rnd rgen; rnd rgen;
// output file (not used at the moment) // CSV ouput
ofstream logfile; ofstream csv;
// number of particles at which the simulation will stop // number of particles at which the simulation will stop
// (the value is set in constructor) // (the value is set in constructor)
@ -65,22 +62,16 @@ class DLASystem {
// update the system: if there is an active particle then move it, // update the system: if there is an active particle then move it,
// else create a new particle (on the adding circle) // else create a new particle (on the adding circle)
void Update(); void update();
// draw particles as squares // is the simulation running
void DrawSquares(); bool running;
// 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 // lastParticleIsActive is +1 if there is an active particle in the system, otherwise 0
int lastParticleIsActive; int lastParticleIsActive;
// constructor // constructor
DLASystem(Window *set_win); explicit DLASystem(int maxParticles, const string &csvPath, double stickProbability);
// destructor // destructor
~DLASystem(); ~DLASystem();
@ -92,25 +83,6 @@ class DLASystem {
// check whether we should stop (eg the cluster has reached the edge of the grid) // check whether we should stop (eg the cluster has reached the edge of the grid)
int checkStop(); int checkStop();
// stop/start the algorithm
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; }
// if the killcircle is almost as big as the view then increase the view
void updateViewSize();
// set the view to be the approx size of the addCircle
void viewAddCircle();
// if pos is outside the cluster radius then set clusterRadius to be the distance to pos. // if pos is outside the cluster radius then set clusterRadius to be the distance to pos.
void updateClusterRadius( double pos[] ); void updateClusterRadius( double pos[] );
@ -146,9 +118,5 @@ class DLASystem {
// currently it sticks whenever it touches another particle // currently it sticks whenever it touches another particle
int checkStick(); int checkStick();
// set the background colour for the window void exportData();
// 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); }
}; };

View File

@ -10,11 +10,11 @@
CXX = clang++ CXX = clang++
CXXFLAGS = -Wall -Wextra -g -O0 CXXFLAGS = -Wall -Wextra -g -O0 --std=c++20
IFLAGS = -I/usr/local/include -I/usr/include IFLAGS = -I/usr/local/include -I/usr/include
LFLAGS = -L/usr/local/lib -lm -framework OpenGL -framework GLUT LFLAGS = -L/usr/local/lib -lm
# ------------------------------------------ # ------------------------------------------
# FOR GENERIC MAKEFILE: # FOR GENERIC MAKEFILE:

4
README.md Normal file
View File

@ -0,0 +1,4 @@
# DLA Model
This currently contains The Initially Provided Code for the DLA model which will be used as the source of truth for
further alterations once verified.

View File

@ -1,26 +0,0 @@
#include "Window.h"
// constructor
Window::Window(int set_size[], string &set_title) {
size[0]=set_size[0]; size[1]=set_size[1];
title=set_title;
locateOnScreen();
glutInitWindowSize(size[0],size[1]);
glutInitWindowPosition(pos[0],pos[1]);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow(title.c_str());
// sets the background to black
glClearColor(0.0, 0.0, 0.0, 0.0);
}
// print a string at a given position, don't worry about how this works...
void Window::displayString( ostringstream &str, double x, double y, GLfloat col[]) {
string localString = str.str();
glColor4fv(col);
glRasterPos2d(x,y);
for (int i = 0; i < localString.length(); i++) {
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, localString[i]);
}
}

View File

@ -1,34 +0,0 @@
#pragma once
#include <GLUT/glut.h>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Window {
public:
string title;
int size[2];
int pos[2];
void locateOnScreen() {
// the fx sets where on the screen the window will appear
// (values should be between 0 and 1)
double fx[] = { 0.7,0.5 };
pos[0] = (glutGet(GLUT_SCREEN_WIDTH) - size[0]) * fx[0];
pos[1] = (glutGet(GLUT_SCREEN_HEIGHT) - size[1]) * fx[1];
}
// constructor, size is in pixels
Window(int set_size[], string &set_title);
// function which prints a string to the screen, at a given position, with a given color
// note position is "absolute", not easy to get two strings spaced one above each other like this
void displayString( ostringstream &str, double x, double y, GLfloat col[]);
};

View File

@ -1,169 +1,29 @@
#include <GLUT/glut.h>
#include <iostream> #include <iostream>
#include <stdio.h>
#include <vector>
#include <math.h>
#include <string>
#include "DLASystem.h" #include "DLASystem.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();
}
// this is a global pointer, which is how we access the system itself
DLASystem *sys;
int main(int argc, char **argv) { int main(int argc, char **argv) {
// turn on glut if (argc != 5) {
glutInit(&argc, argv); cerr << "Usage " << argv[0] << " <seed> <maxParticles> <stickProbability> <csvPath>" << endl;
return 1;
}
int window_size[] = { 480,480 }; int seed = std::stoi(argv[1]);
string window_title("simple DLA simulation"); int maxParticles = std::stoi(argv[2]);
double stickProbability = std::stod(argv[3]);
string csvPath = argv[4];
std::cerr << "Setting seed " << seed << endl;
// create a window // create the system
Window *win = new Window(window_size,window_title); auto *sys = new DLASystem(maxParticles, csvPath, stickProbability);
sys->setSeed(seed);
sys->running = true;
// create the system while (sys->running) {
sys = new DLASystem(win); sys->update();
}
// 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);
// start the openGL stuff sys->exportData();
glutMainLoop();
return 0; 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;
}
// 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();
}
// 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);
}
}
// 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);
// 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();
// Swap contents of backward and forward frame buffers
glutSwapBuffers();
}

View File

@ -1,27 +0,0 @@
To run the code on a Mac through the command line:
1. Download Makefile from this section
2. Put Makefile in same directory as DLASystem.cpp (! Remove the .txt extension if present !)
3. Relative to MS Visual Studio code, these files include the following changes: DLASystem.h Window.h mainDLA.cpp
change #include <gl/freeglut.h>
to #include <GLUT/glut.h>
4. Open the terminal in the same folder as these files
5. Type "make" to build project
6. Run the program by typing "./run"
7. To edit your files, run gedit, save the code, and recompile with "make -B" before running the program again.
Thanks to Eliot Ayache for figuring this out!
PS For Coursework 2: In addition, there needs to be a change in Line 72 of MAIN_Source.cpp file from "glutLeaveMainLoop();" to "exit(1);"