Created
April 24, 2014 01:52
-
-
Save macroxela/11238852 to your computer and use it in GitHub Desktop.
Particle Swarm Optimization using OpenGL and C++. Creates various particles and allows the user to add/remove particles and manipulate variables in PSO algorithm to view effects on particles.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <GLUT/glut.h> | |
#include <stdlib.h> | |
#include<iostream> | |
#include<fstream> | |
#include<string> | |
#include<time.h> | |
using namespace std; | |
float radius; | |
int segments; | |
double sfitness, maxfit; | |
float V = 0.0001; | |
int Pink, Yellow, Red, Blue, Green, White; | |
int cPink, cYellow, cRed, cBlue, cGreen, cWhite; | |
int Xpixels, YPixels; | |
int nump, cntp; | |
double acc1 = 0.5; | |
double acc2 = 0.5; | |
bool PSO = false; | |
ofstream out("output.txt"); | |
//acc2*r2*(p->fitness - p->x) | |
class Particle{ | |
public: | |
double fitness; | |
float x, y, dx, dy; | |
bool moveable; | |
int c1, c2, c3; | |
bool cent; | |
Particle *nxt; | |
Particle(); | |
Particle(const Particle& other); | |
}; | |
Particle::Particle() | |
{ | |
fitness = -99; | |
x = 0; y = 0; | |
dx = 0; dy = 0; | |
moveable = true; | |
cent = false; | |
c1 = 1; | |
c2 = 0; | |
c3 = 0; | |
nxt = NULL; | |
} | |
Particle::Particle(const Particle& other) | |
{ | |
x = other.x; | |
y = other.y; | |
dx = other.dx; | |
dy = other.dy; | |
c1 = other.c1; | |
c2 = other.c2; | |
c3 = other.c3; | |
fitness = other.fitness; | |
nxt = other.nxt; | |
moveable = other.moveable; | |
cent = other.cent; | |
} | |
Particle *swarm; //Stores all the particles in linked list | |
Particle *center; //The center of orbit of particles | |
//Calculates the distance between two points | |
double euclideanDist(double x1, double y1, double x2, double y2) | |
{ | |
return sqrt(pow(x1-x2,2) + pow(y1-y2,2)); | |
} | |
//Evaluates a particular fitness | |
double evalIfitness(Particle *p1, Particle *p2) | |
{ | |
double fit = euclideanDist(p1->x, p1->y, p2->x, p2->y); | |
return fit; | |
} | |
void update() | |
{ | |
Particle *s = swarm; | |
Particle *c = center; | |
for(int i = 0; i < nump; i++) | |
{ | |
for(int j = 0; j < cntp; j++) | |
{ | |
if(c->c1 == s->c1 && c->c2 == s->c2 && c->c3 == s->c3) | |
{ | |
//cout<<"Inside\n"; | |
//Update individual fitness | |
double fit = evalIfitness(s,c); | |
if(s->fitness < fit && fit <= maxfit) | |
{ | |
s->fitness = fit; | |
if(fit > sfitness && maxfit >= fit) | |
sfitness = fit; | |
out<<"Fitness: "<<s->fitness<<" "<<sfitness<<" Pos: "<<s->x<<" "<<s->y<<" "; | |
} | |
/************************************************************/ | |
double r1 = (rand()%10)/10.0; | |
double r2 = (rand()%10)/10.0; | |
double dx = s->dx; | |
double dy = s->dy; | |
double val1 = abs(acc1*r1*(sfitness - (double)s->x) + acc2*r2*(s->fitness - (double)s->x)); | |
double val2 = abs(acc1*r1*(sfitness - (double)s->y) + acc2*r2*(s->fitness - (double)s->y)); | |
r1 = rand()/RAND_MAX; | |
r2 = rand()/RAND_MAX; | |
//Negative dx means moving right to left | |
//Negative dy means moving up to down | |
if(r1 < val1) | |
{ | |
if(s->x < c->x) | |
{ | |
if(s->dx < 0) | |
s->dx = c->dx; | |
} | |
if(s->x > c->x) | |
{ | |
if(s->dx > 0) | |
s->dx = c->dx; | |
} | |
} | |
if(r2 < val2) | |
{ | |
if(s->y < c->y) | |
{ | |
if(s->dy < 0) | |
s->dy = c->dy; | |
} | |
if(s->y > c->y) | |
{ | |
if(s->dy > 0) | |
s->dy = c->dy; | |
} | |
} | |
out<<"Velocity: "<<s->dx<<" "<<s->dy<<" "; | |
out<<endl; | |
/************************************************************/ | |
} | |
c = c->nxt; | |
} | |
c = center; | |
s = s->nxt; | |
} | |
} | |
void moveShape(int x, int y) | |
{ | |
double p1 = ((double)x/(glutGet(GLUT_WINDOW_WIDTH)/2)-1); //((double)x/141-1); | |
double p2 = (-1*(double)y/(glutGet(GLUT_WINDOW_WIDTH)/2)+1); //(-1*(double)y/141+1); | |
float x1 = (float)p1; | |
float y1 = (float)p2; | |
//Linked List | |
Particle *trav = swarm; | |
for(int i = 0; i < nump; i++) | |
{ | |
if(!trav->moveable) | |
{ | |
trav->x = (float)x1; | |
trav->y = (float)y1; | |
} | |
trav = trav->nxt; | |
} | |
trav = center; | |
for(int i = 0; i < cntp; i++) | |
{ | |
if(!trav->moveable) | |
{ | |
trav->x = (float)x1; | |
trav->y = (float)y1; | |
} | |
trav = trav->nxt; | |
} | |
} | |
//Returns boolean value for collision | |
bool collision(float x1, float y1, float x2, float y2) | |
{ | |
//paddle.x < x + 20 && x < paddle.x+ paddle.width && paddle.y < y + 20 && y < paddle.y + paddle.height | |
bool collide = false; | |
if(x1 < x2 + radius && x2 < x1 + radius && y1 < y2 + radius && y2 < y1 + radius) | |
collide = true; | |
if(x1 + radius < x2 && x2 + radius < x1 && y1 + radius < y2 && y2 + radius < y1) | |
collide = true; | |
return collide; | |
} | |
void checkCollision() | |
{ | |
//Linked List | |
Particle *trav = swarm; | |
for(int i = 0; i < nump; i++) | |
{ | |
Particle *sec = swarm; | |
for(int j = 0; j < nump; j++) | |
{ | |
if(sec != trav) | |
{ | |
if(collision(trav->x,trav->y,sec->x,sec->y)) | |
{ | |
trav->dx *= -1; | |
trav->dy *= -1; | |
} | |
} | |
sec = sec->nxt; | |
} | |
trav = trav->nxt; | |
} | |
trav = center; | |
for(int i = 0; i < cntp; i++) | |
{ | |
Particle *sec = swarm; | |
for(int j = 0; j < nump; j++) | |
{ | |
if(sec != trav) | |
{ | |
if(collision(trav->x,trav->y,sec->x,sec->y)) | |
{ | |
trav->dx *= -1; | |
trav->dy *= -1; | |
} | |
} | |
sec = sec->nxt; | |
} | |
trav = trav->nxt; | |
} | |
trav = center; | |
for(int i = 0; i < cntp; i++) | |
{ | |
Particle *sec = center; | |
for(int j = 0; j < cntp; j++) | |
{ | |
if(sec != trav) | |
{ | |
if(collision(trav->x,trav->y,sec->x,sec->y)) | |
{ | |
trav->dx *= -1; | |
trav->dy *= -1; | |
} | |
} | |
sec = sec->nxt; | |
} | |
trav = trav->nxt; | |
} | |
} | |
void animate() | |
{ | |
checkCollision(); | |
//Linked List | |
Particle *trav = swarm; | |
for(int i = 0; i < nump; i++) | |
{ | |
if(trav->moveable) | |
{ | |
trav->x += trav->dx; | |
trav->y += trav->dy; | |
} | |
if(trav->x - radius < -1 || trav->x + radius > 1) | |
trav->dx *= -1; | |
if(trav->y - radius < -1 || trav->y + radius > 1) | |
trav->dy *= -1; | |
trav = trav->nxt; | |
} | |
trav = center; | |
for(int i = 0; i < cntp; i++) | |
{ | |
if(trav->moveable) | |
{ | |
trav->x += trav->dx; | |
trav->y += trav->dy; | |
} | |
if(trav->x - radius < -1 || trav->x + radius > 1) | |
trav->dx *= -1; | |
if(trav->y - radius < -1 || trav->y + radius > 1) | |
trav->dy *= -1; | |
trav = trav->nxt; | |
} | |
if(PSO) | |
update(); | |
glutPostRedisplay(); | |
} | |
/*********************************************************************/ | |
//Code borrowed from http://slabode.exofire.net/circle_draw.shtml | |
void DrawCircle(float cx, float cy, float r, int num_segments, bool c) | |
{ | |
float theta = 2 * 3.1415926 / float(num_segments); | |
float tangetial_factor = tanf(theta);//calculate the tangential factor | |
float radial_factor = cosf(theta);//calculate the radial factor | |
float x = r;//we start at angle = 0 | |
float y = 0; | |
glBegin(GL_LINE_LOOP); | |
for(int ii = 0; ii < num_segments; ii++) | |
{ | |
glVertex2f(x + cx, y + cy);//output vertex | |
//calculate the tangential vector | |
//remember, the radial vector is (x, y) | |
//to get the tangential vector we flip those coordinates and negate one of them | |
float tx = -y; | |
float ty = x; | |
//add the tangential vector | |
x += tx * tangetial_factor; | |
y += ty * tangetial_factor; | |
//correct using the radial factor | |
x *= radial_factor; | |
y *= radial_factor; | |
} | |
glEnd(); | |
//Added to original code to fill circle | |
glBegin(GL_POLYGON); //Square | |
glVertex2f((double)cx - radius/sqrt(2),(double)cy + radius/sqrt(2)); | |
glVertex2f((double)cx + radius/sqrt(2),(double)cy + radius/sqrt(2)); | |
glVertex2f((double)cx + radius/sqrt(2),(double)cy - radius/sqrt(2)); | |
glVertex2f((double)cx - radius/sqrt(2),(double)cy - radius/sqrt(2)); | |
glEnd(); | |
if(!c) | |
{ | |
glBegin(GL_POLYGON); //Diamond | |
glVertex2f((double)cx,(double)cy + radius); | |
glVertex2f((double)cx + radius,(double)cy); | |
glVertex2f((double)cx,(double)cy - radius); | |
glVertex2f((double)cx - radius,(double)cy); | |
glEnd(); | |
} | |
} | |
/*********************************************************************/ | |
void mydisplay(){ | |
glClear(GL_COLOR_BUFFER_BIT); | |
Particle *trav = swarm; | |
for(int i = 0; i < nump; i++) | |
{ | |
glColor3f(trav->c1,trav->c2,trav->c3); | |
/*glColor3f(1,1,1); //White | |
glColor3f(1,1,0); //Yellow | |
glColor3f(1,0,1); //Pink | |
glColor3f(0,1,1); //Light Blue | |
glColor3f(1,0,0); //Red | |
glColor3f(0,1,0); //Green | |
glColor3f(0,0,1); //Dark Blue | |
glColor3f(0,0,0); //Black | |
*/ | |
DrawCircle(trav->x,trav->y,radius,segments, trav->cent); | |
trav = trav->nxt; | |
} | |
trav = center; | |
for(int i = 0; i < cntp; i++) | |
{ | |
glColor3f(trav->c1,trav->c2,trav->c3); | |
DrawCircle(trav->x,trav->y,radius,segments, trav->cent); | |
trav = trav->nxt; | |
} | |
glFlush(); | |
} | |
void OnMouseClick(int button, int state, int x, int y) | |
{ | |
double p1 = ((double)x/(glutGet(GLUT_WINDOW_WIDTH)/2)-1); //((double)x/141-1); | |
double p2 = (-1*(double)y/(glutGet(GLUT_WINDOW_WIDTH)/2)+1); //(-1*(double)y/141+1); | |
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) | |
{ | |
glutMotionFunc(moveShape); | |
} | |
if(button == GLUT_LEFT_BUTTON && state == GLUT_UP) | |
{ | |
//Linked List | |
Particle *trav = swarm; | |
for(int i = 0; i < nump; i++) | |
{ | |
trav->moveable = true; | |
trav = trav->nxt; | |
} | |
trav = center; | |
for(int i = 0; i < cntp; i++) | |
{ | |
trav->moveable = true; | |
trav = trav->nxt; | |
} | |
} | |
if(button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) | |
{ | |
//puts("Middle button clicked"); | |
cout<<x<<" "<<y<<endl; | |
int test = glutGet(GLUT_WINDOW_WIDTH); | |
//cout<<"Window width: "<<test<<endl; | |
test = glutGet(GLUT_WINDOW_HEIGHT); | |
//cout<<"Window height: "<<test<<endl; | |
//Linked List | |
Particle *trav = swarm; | |
for(int i = 0; i < nump; i++) | |
{ | |
if(collision(p1,p2,trav->x,trav->y)) | |
trav->moveable = false; | |
trav = trav->nxt; | |
} | |
trav = center; | |
for(int i = 0; i < cntp; i++) | |
{ | |
if(collision(p1,p2,trav->x,trav->y)) | |
trav->moveable = false; | |
trav = trav->nxt; | |
} | |
} | |
} | |
void setParticleData(Particle *p) | |
{ | |
//Set Colors | |
if(Red != 0) | |
{ | |
p->c1 = 1; | |
p->c2 = 0; | |
p->c3 = 0; | |
Red--; | |
cRed++; | |
} | |
else if(Yellow != 0) | |
{ | |
p->c1 = 1; | |
p->c2 = 1; | |
p->c3 = 0; | |
Yellow--; | |
cYellow++; | |
} | |
else if(Blue != 0) | |
{ | |
p->c1 = 0; | |
p->c2 = 1; | |
p->c3 = 1; | |
Blue--; | |
cBlue++; | |
} | |
else if(Green != 0) | |
{ | |
p->c1 = 0; | |
p->c2 = 1; | |
p->c3 = 0; | |
Green--; | |
cGreen++; | |
} | |
else if(White != 0) | |
{ | |
p->c1 = 1; | |
p->c2 = 1; | |
p->c3 = 1; | |
White--; | |
cWhite++; | |
} | |
else if(Pink != 0) | |
{ | |
p->c1 = 1; | |
p->c2 = 0; | |
p->c3 = 1; | |
Pink--; | |
cPink++; | |
} | |
else | |
{ | |
if((double)rand()/RAND_MAX <= 0.5) | |
p->c1 = 0; | |
else | |
p->c1 = 1; | |
if((double)rand()/RAND_MAX <= 0.5) | |
p->c2 = 0; | |
else | |
p->c2 = 1; | |
if((double)rand()/RAND_MAX <= 0.5) | |
p->c3 = 0; | |
else | |
p->c3 = 1; | |
if(p->c1 == 0 && p->c2 == 0 && p->c3 == 0) | |
p->c1 = 1; | |
} | |
//Set Positions | |
do{ | |
p->x = (float)rand()/RAND_MAX; | |
}while(p->x + radius > 1); | |
do{ | |
p->y = (float)rand()/RAND_MAX; | |
}while(p->y + radius > 1); | |
if(rand()%2 == 0) | |
p->y *= -1; | |
if(rand()%2 == 0) | |
p->x *= -1; | |
//Set Velocities | |
p->dx = V; | |
p->dy = V; | |
if((double)rand()/RAND_MAX <= 0.5) | |
p->dx *= -1; | |
if((double)rand()/RAND_MAX <= 0) | |
p->dy *= -1; | |
p->moveable = true; | |
p->fitness = -99; | |
} | |
void printParticleData(Particle *p) | |
{ | |
cout<<"Position: "<<p->x<<" "<<p->y<<endl; | |
cout<<"Velocities: "<<p->dx<<" "<<p->dy<<endl; | |
cout<<"Colors: "<<p->c1<<" "<<p->c2<<" "<<p->c3<<endl<<endl; | |
} | |
float getNewVelocity() | |
{ | |
cout<<"\nNew Velocity: "; | |
float temp = 0; | |
cin>>temp; | |
return temp; | |
} | |
void changeAll() | |
{ | |
V = getNewVelocity(); | |
Particle *trav = swarm; | |
int ran = 0; | |
for(int i = 0; i < nump; i++) | |
{ | |
ran = rand()%2; | |
if(ran == 0) | |
trav->dx = V; | |
else | |
trav->dx = -1*V; | |
ran = rand()%2; | |
if(ran == 0) | |
trav->dy = V; | |
else | |
trav->dy = -1*V; | |
trav = trav->nxt; | |
} | |
trav = center; | |
for(int i = 0; i < cntp; i++) | |
{ | |
trav->dx = V; | |
trav->dy = V; | |
trav = trav->nxt; | |
} | |
} | |
void changeOne(int button, int state, int x, int y) | |
{ | |
double p1 = ((double)x/(glutGet(GLUT_WINDOW_WIDTH)/2)-1); | |
double p2 = (-1*(double)y/(glutGet(GLUT_WINDOW_WIDTH)/2)+1); | |
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) | |
{ | |
Particle *trav = swarm; | |
for(int i = 0; i < nump; i++) | |
{ | |
if(collision(p1,p2,trav->x,trav->y)) | |
{ | |
float n = getNewVelocity(); | |
trav->dx = n; | |
trav->dy = n; | |
break; | |
} | |
trav = trav->nxt; | |
} | |
trav = center; | |
for(int i = 0; i < cntp; i++) | |
{ | |
if(collision(p1,p2,trav->x,trav->y)) | |
{ | |
float n = getNewVelocity(); | |
trav->dx = n; | |
trav->dy = n; | |
break; | |
} | |
trav = trav->nxt; | |
} | |
} | |
} | |
void changeVelocityMenu(int c) | |
{ | |
switch(c) | |
{ | |
case 1: | |
changeAll(); | |
break; | |
case 2: | |
glutMouseFunc(changeOne); | |
break; | |
} | |
} | |
void AddParticle() | |
{ | |
Particle *p = new Particle; | |
setParticleData(p); | |
cout<<"New Particle:\n"; | |
printParticleData(p); | |
cout<<endl; | |
Particle *trav = swarm; | |
for(int i = 0; i < nump - 1; i++) | |
{ | |
trav = trav->nxt; | |
} | |
trav->nxt = p; | |
nump++; | |
} | |
void AddParticleMenu(int c) | |
{ | |
switch (c) | |
{ | |
case 1: | |
Red++; | |
AddParticle(); | |
break; | |
case 2: | |
Yellow++; | |
AddParticle(); | |
break; | |
case 3: | |
Blue++; | |
AddParticle(); | |
break; | |
case 4: | |
Green++; | |
AddParticle(); | |
break; | |
case 5: | |
White++; | |
AddParticle(); | |
break; | |
case 6: | |
Pink++; | |
AddParticle(); | |
break; | |
} | |
cout<<"New Particle List:\n"; | |
Particle *trav = swarm; | |
for(int i = 0; i < nump; i++) | |
{ | |
printParticleData(trav); | |
trav = trav->nxt; | |
} | |
} | |
void removeCenter(int c1, int c2, int c3) | |
{ | |
if(c1 == 1 && c2 == 1 && c3 == 1) | |
{ | |
cWhite--; | |
if(cWhite == 0) | |
{ | |
Particle *rem = center; | |
Particle *rem_prev = NULL; | |
Particle *rem_nxt = rem->nxt; | |
for(int j = 0; j < cntp; j++) | |
{ | |
if(rem->c1 == c1 && rem->c2 == c2 && rem->c3 == c3) | |
{ | |
if(rem_prev != NULL) | |
rem_prev->nxt = rem_nxt; | |
else | |
center = center->nxt; | |
} | |
rem_prev = rem; | |
rem = rem->nxt; | |
if(rem_nxt != NULL) | |
rem_nxt == rem->nxt; | |
} | |
} | |
} | |
if(c1 == 1 && c2 == 1 && c3 == 0) | |
{ | |
cYellow--; | |
if(cYellow == 0) | |
{ | |
Particle *rem = center; | |
Particle *rem_prev = NULL; | |
Particle *rem_nxt = rem->nxt; | |
for(int j = 0; j < cntp; j++) | |
{ | |
if(rem->c1 == c1 && rem->c2 == c2 && rem->c3 == c3) | |
{ | |
if(rem_prev != NULL) | |
rem_prev->nxt = rem_nxt; | |
else | |
center = center->nxt; | |
} | |
rem_prev = rem; | |
rem = rem->nxt; | |
if(rem_nxt != NULL) | |
rem_nxt == rem->nxt; | |
} | |
} | |
} | |
if(c1 == 1 && c2 == 0 && c3 == 1) | |
{ | |
cPink--; | |
if(cPink == 0) | |
{ | |
Particle *rem = center; | |
Particle *rem_prev = NULL; | |
Particle *rem_nxt = rem->nxt; | |
for(int j = 0; j < cntp; j++) | |
{ | |
if(rem->c1 == c1 && rem->c2 == c2 && rem->c3 == c3) | |
{ | |
if(rem_prev != NULL) | |
rem_prev->nxt = rem_nxt; | |
else | |
center = center->nxt; | |
} | |
rem_prev = rem; | |
rem = rem->nxt; | |
if(rem_nxt != NULL) | |
rem_nxt == rem->nxt; | |
} | |
} | |
} | |
if(c1 == 0 && c2 == 1 && c3 == 1) | |
{ | |
cBlue--; | |
if(cBlue == 0) | |
{ | |
Particle *rem = center; | |
Particle *rem_prev = NULL; | |
Particle *rem_nxt = rem->nxt; | |
for(int j = 0; j < cntp; j++) | |
{ | |
if(rem->c1 == c1 && rem->c2 == c2 && rem->c3 == c3) | |
{ | |
if(rem_prev != NULL) | |
rem_prev->nxt = rem_nxt; | |
else | |
center = center->nxt; | |
} | |
rem_prev = rem; | |
rem = rem->nxt; | |
if(rem_nxt != NULL) | |
rem_nxt == rem->nxt; | |
} | |
} | |
} | |
if(c1 == 1 && c2 == 0 && c3 == 0) | |
{ | |
cRed--; | |
if(cRed == 0) | |
{ | |
Particle *rem = center; | |
Particle *rem_prev = NULL; | |
Particle *rem_nxt = rem->nxt; | |
for(int j = 0; j < cntp; j++) | |
{ | |
if(rem->c1 == c1 && rem->c2 == c2 && rem->c3 == c3) | |
{ | |
if(rem_prev != NULL) | |
rem_prev->nxt = rem_nxt; | |
else | |
center = center->nxt; | |
} | |
rem_prev = rem; | |
rem = rem->nxt; | |
if(rem_nxt != NULL) | |
rem_nxt == rem->nxt; | |
} | |
} | |
} | |
if(c1 == 0 && c2 == 1 && c3 == 0) | |
{ | |
cGreen--; | |
if(cGreen == 0) | |
{ | |
Particle *rem = center; | |
Particle *rem_prev = NULL; | |
Particle *rem_nxt = rem->nxt; | |
for(int j = 0; j < cntp; j++) | |
{ | |
if(rem->c1 == c1 && rem->c2 == c2 && rem->c3 == c3) | |
{ | |
if(rem_prev != NULL) | |
rem_prev->nxt = rem_nxt; | |
else | |
center = center->nxt; | |
} | |
rem_prev = rem; | |
rem = rem->nxt; | |
if(rem_nxt != NULL) | |
rem_nxt == rem->nxt; | |
} | |
} | |
} | |
cout<<"Red: "<<cRed<<endl; | |
cout<<"Yellow: "<<cYellow<<endl; | |
cout<<"White: "<<cWhite<<endl; | |
cout<<"Blue: "<<cBlue<<endl; | |
cout<<"Green: "<<cGreen<<endl; | |
cout<<"Pink: "<<cPink<<endl; | |
} | |
void RemoveParticle(int button, int state, int x, int y) | |
{ | |
double p1 = ((double)x/(glutGet(GLUT_WINDOW_WIDTH)/2)-1); //((double)x/141-1); | |
double p2 = (-1*(double)y/(glutGet(GLUT_WINDOW_WIDTH)/2)+1); //(-1*(double)y/141+1); | |
float x1 = (float)p1; | |
float y1 = (float)p2; | |
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) | |
{ | |
//Linked List | |
Particle *trav = swarm; | |
Particle *prev = NULL; | |
Particle *nxt = swarm->nxt; | |
for(int i = 0; i < nump; i++) | |
{ | |
if(collision(p1,p2,trav->x,trav->y)) | |
{ | |
//int c1 = trav->c1; | |
//int c2 = trav->c2; | |
//int c3 = trav->c3; | |
removeCenter(trav->c1, trav->c2, trav->c3); | |
if(prev != NULL) | |
prev->nxt = nxt; | |
else | |
swarm = swarm->nxt; | |
nump--; | |
cout<<"Removed a particle\n"; | |
} | |
prev = trav; | |
trav = trav->nxt; | |
if(trav != NULL) | |
nxt = trav->nxt; | |
} | |
trav = center; | |
prev = NULL; | |
nxt = center->nxt; | |
for(int i = 0; i < cntp; i++) | |
{ | |
if(collision(p1,p2,trav->x,trav->y)) | |
{ | |
if(prev != NULL) | |
prev->nxt = nxt; | |
else | |
center = center->nxt; | |
cntp--; | |
cout<<"Removed a particle\n"; | |
} | |
prev = trav; | |
trav = trav->nxt; | |
if(trav != NULL) | |
nxt = trav->nxt; | |
} | |
} | |
} | |
void RemoveMenu(int c) | |
{ | |
switch(c) | |
{ | |
case 1: | |
glutMouseFunc(RemoveParticle); | |
break; | |
} | |
return; | |
} | |
void changeAccG() | |
{ | |
cout<<"Desired global acceleration: "; | |
cin>>acc1; | |
} | |
void changeAccI() | |
{ | |
cout<<"Desired individual acceleration: "; | |
cin>>acc2; | |
} | |
void changeAcc(int c) | |
{ | |
switch(c) | |
{ | |
case 1: | |
changeAccG(); | |
break; | |
case 2: | |
changeAccI(); | |
break; | |
} | |
} | |
void mouseMenu(int c) | |
{ | |
switch (c) | |
{ | |
case 1: | |
glutMouseFunc(OnMouseClick); | |
break; | |
} | |
return; | |
} | |
void changeMaxFit(int c) | |
{ | |
switch(c) | |
{ | |
case 1: | |
cout<<"Desired maximum fitness: "; | |
cin>>maxfit; | |
break; | |
} | |
} | |
void activatePSO(int c) | |
{ | |
switch(c) | |
{ | |
case 1: | |
PSO = true; | |
cout<<"ON\n"; | |
break; | |
case 2: | |
PSO = false; | |
cout<<"OFF\n"; | |
Particle *s = swarm; | |
for(int i = 0; i < nump; i++) | |
{ | |
s->fitness = 0; | |
} | |
break; | |
} | |
} | |
void topMenu(int c) | |
{ | |
} | |
void setVar() | |
{ | |
srand (time(NULL)); | |
segments = 45; | |
//Set global swarm fitness | |
sfitness = 0; | |
maxfit = 1; | |
//Pink, Yellow, Red, Blue, Green, White; | |
cPink = 0; | |
cYellow = 0; | |
cRed = 0; | |
cBlue = 0; | |
cGreen = 0; | |
cWhite = 0; | |
bool red = false; | |
bool pink = false; | |
bool yellow = false; | |
bool blue = false; | |
bool green = false; | |
bool white = false; | |
if(Red != 0) | |
red = true; | |
if(Pink != 0) | |
pink = true; | |
if(Yellow != 0) | |
yellow = true; | |
if(Blue != 0) | |
blue = true; | |
if(Green != 0) | |
green = true; | |
if(White != 0) | |
white = true; | |
//Initialize Particle Linked List | |
swarm = new Particle; | |
Particle *trav = swarm; | |
for(int i = 0; i < nump; i++) | |
{ | |
trav->nxt = new Particle; | |
setParticleData(trav); | |
trav = trav->nxt; | |
} | |
//Initialize center particles | |
center = new Particle; | |
int cnt = 0; | |
if(red) | |
{ | |
Red++; | |
cnt++; | |
} | |
if(pink) | |
{ | |
Pink++; | |
cnt++; | |
} | |
if(yellow) | |
{ | |
Yellow++; | |
cnt++; | |
} | |
if(blue) | |
{ | |
Blue++; | |
cnt++; | |
} | |
if(green) | |
{ | |
Green++; | |
cnt++; | |
} | |
if(white) | |
{ | |
White++; | |
cnt++; | |
} | |
cntp = cnt; | |
trav = center; | |
for(int i = 0; i < cnt; i++) | |
{ | |
trav->nxt = new Particle; | |
setParticleData(trav); | |
trav->cent = true; | |
trav = trav->nxt; | |
//cout<<"Particle "<<i+1<<" made\n"; | |
} | |
if(cRed != 0) | |
cRed--; | |
if(cPink != 0) | |
cPink--; | |
if(cYellow != 0) | |
cYellow--; | |
if(cBlue != 0) | |
cBlue--; | |
if(cGreen != 0) | |
cGreen--; | |
if(cWhite != 0) | |
cWhite--; | |
Xpixels = 500; | |
YPixels = Xpixels; | |
} | |
int main(int argc, char** argv){ | |
cout<<"How many red: "; | |
cin>>Red; | |
cout<<"How many yellow: "; | |
cin>>Yellow; | |
cout<<"How many blue: "; | |
cin>>Blue; | |
cout<<"How many green: "; | |
cin>>Green; | |
cout<<"How many white: "; | |
cin>>White; | |
cout<<"How many pink: "; | |
cin>>Pink; | |
cout<<"Velocity: "; | |
cin>>V; | |
cout<<"Radius: "; | |
cin>>radius; | |
nump = Red + Yellow + Blue + Green + White + Pink; | |
srand(time(NULL)); | |
setVar(); | |
cout<<"\n\n\n# of initial particles: "<<nump<<endl; | |
cout<<"Initial radius: "<<radius<<endl; | |
cout<<"Initial velocity: "<<V<<endl; | |
cout<<"Maximum Fitness: "<<maxfit<<endl; | |
glutInit(&argc,argv); | |
//Default of 300 X 300 | |
glutInitWindowSize(Xpixels, YPixels); | |
glutCreateWindow("Particle Swarm"); | |
glutDisplayFunc(mydisplay); | |
int m1 = glutCreateMenu(mouseMenu); | |
glutAddMenuEntry("Position",1); | |
int m2 = glutCreateMenu(AddParticleMenu); | |
glutAddMenuEntry("Red",1); | |
glutAddMenuEntry("Yellow",2); | |
glutAddMenuEntry("Blue",3); | |
glutAddMenuEntry("Green",4); | |
glutAddMenuEntry("White",5); | |
glutAddMenuEntry("Pink",6); | |
int m3 = glutCreateMenu(RemoveMenu); | |
glutAddMenuEntry("Remove",1); | |
int m4 = glutCreateMenu(changeVelocityMenu); | |
glutAddMenuEntry("Change All",1); | |
glutAddMenuEntry("Change One",2); | |
int m5 = glutCreateMenu(activatePSO); | |
glutAddMenuEntry("Activate",1); | |
glutAddMenuEntry("Turn off",2); | |
int m6 = glutCreateMenu(changeAcc); | |
glutAddMenuEntry("Global Acc",1); | |
glutAddMenuEntry("Individual Acc",2); | |
int m7 = glutCreateMenu(changeMaxFit); | |
glutAddMenuEntry("Change",1); | |
glutCreateMenu(topMenu); | |
glutAddSubMenu("Move",m1); | |
glutAddSubMenu("Add Particle",m2); | |
glutAddSubMenu("Remove Particle",m3); | |
glutAddSubMenu("Change Speed",m4); | |
glutAddSubMenu("Activate",m5); | |
glutAddSubMenu("Acceleration",m6); | |
glutAddSubMenu("Change Max Fit",m7); | |
glutAttachMenu (GLUT_RIGHT_BUTTON); | |
glutIdleFunc(animate); | |
glutMainLoop(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment