//=========================================================================== // Flocking, Musical Chairs // 18 March 2010 - Version 24a // A prototype for introducing inanimate objects or "Things" // The bottom of the array is used for "Persons" // The top of the array is used for "Things" // PaintBox is 700 x 700 // To Do: create add, destroy and defines for number of things. //=========================================================================== // The Leonardo image is 700 by 700 pixels. // The Voyager images are 100 by 44 pixels. //--------------------------------------------------------------------------- #include #include // for trigonometric functions #pragma hdrstop #include "Unit1.h" #include "stdlib.h" #include // for multimedia #define SEQUENTIAL 0 // for Polling sequence #define RANDOM 1 #define NORTH 0 // wall designatios #define EAST 1 #define SOUTH 2 #define WEST 3 #define BEEP 1 // sound types #define PLAYSOUNDWINDOWS 2 #define PLAYSOUNDPINBALL 3 #define MIDI 4 #define MAXPOP 100 // maximum population of persons and things #define INIPOP 21 // initial (and current) population of persons #define WOMAN 1 // agent types #define MAN 0 #define ALIEN 2 #define CHAIR 3 #define WHITE 0 // agent colors #define CYAN 1 #define MAGENTA 2 #define YELLOW 3 #define BLACK 4 #define RED 5 #define GREEN 6 #define BLUE 7 #define WIDTH 700 // world size and center #define HEIGHT 700 #define CENTER 350 //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- //=========================================================================== // GLOBAL VARIABLES //=========================================================================== // ------------------------------------------------- your program begins here // Varialbes for a 700 x 700 bitmap image that you may import Graphics::TBitmap* b = new Graphics::TBitmap(); // Holds the bitmap image RGBTRIPLE* t; // Holds one Pixel's R, G, and B values int bmpRed[700][700]; // RED channel of bitmap for environment variables int bmpGreen[700][700]; // GREEN channel of bitmap for environment variables int bmpBlue[700][700]; // BLUE channel of bitmap for environment variables int iterationPath[700][700]; // Paths recorded by iteration int agentPath[700][700]; // Paths recorded by agent int ix, iy; // These commands set up the MIDI functionality int midiport = 0; HMIDIOUT device; union { public: unsigned long word; unsigned char data[4]; } message; int soundType = 0; int instrument; int note; TImage *image[MAXPOP] = {0}; // sets up an array of images for the agents TShape *shape[MAXPOP] = {0}; // sets up an array of shapes for the agents class anAgent { // describes an abstract class for an-agent public: double velocity; // agent's speed double direction; // agent's direction double newDirection; double newDistance; double lastDistance; float x; // agent's X coordinate float y; // agent's Y coordinate int kind; // agent or thing (chair) bool flocking; // int lastNN; // to distinguish last from current neighbor bool active; // bool sitting; // if person, sitting / if chair sat-in int encounters[MAXPOP]; // encounters with each other person int numEncounters; // encounters with all persons int color; // a color representation of type int sex; // male or female int seeking; // someone not self int following; // follow neighbor } ; anAgent* agent[MAXPOP] = {0}; // creates MAXPOP instances of that class double sumXs, sumYs; // sums of Xs and Ys double aveDir, aveVelo; // average directions & velocities double leaderDirection; // for calculating follow the leader direction int sumVisibleNeighbors; // sum of visible neighbors int increment = 5; double x, y, z; // in anticipation of 3D bool stop = true; bool wasStopped = false; bool showNNs = false; bool collisions = false; bool agentsAreDisplayed = true; bool mouseDown = false; bool behavioralSonification = false; bool wrap = true; bool movePerTimer = true; bool followingTheLeader = false; bool followingTheCursor = false; int iterations; int i; int who; int NNeighborTag; // tag (ID) of nearest neighbor int NNeighborDist; // distance to nearest neighbor int NThingTag; // tag (ID) of nearest thing int NThingDist; // distance to nearest thing int radius = 30; int chosenAgent; // agent you MouseDowned upon int runTo = 50000; int curpop = INIPOP; int lastMouseOver; // agent you last MousedOver int mult; // TrackBar Multiplier // Variables required in order to drag and agent int imageDownX, imageDownY; bool agentWasJustChosen = false; // Variables required in order to throw an agent int agentDownX, agentDownY; int agentUpX, agentUpY; double dY, dX; double timeDown, timeUp; int polling = SEQUENTIAL; //=========================================================================== // FUNCTIONS //=========================================================================== //----------------------------------------------- MAKE CHAIRS VISIBLE OR NOT void chairs (bool visible) { for (int i = 90; i < 100; i++) { image[i]->Visible = visible; } } //-------------------------------------------------- FILL ARRAYS FROM BITMAP // This fills the Red, Green and Blue arrays from the bitmap. // It converts the color values (0-255) to preferences (0-7). // The conversion divides the color values by 35. // With a gray-scale image the Red, Green and Blue values are identical. void bmpToArray(Graphics::TBitmap* bm) { for (int y = 0; y < 700; y++) { t = (RGBTRIPLE*)bm->ScanLine[y]; for (int x = 0; x < WIDTH; x++) { bmpRed[x][y] = t->rgbtRed; // used for preference 0-4 bmpGreen[x][y] = t->rgbtGreen; // used for distance 0-3 bmpBlue[x][y] = t->rgbtBlue; // used for neighborhood 0-2 t++; } } } //------------------------------------------------------------- RENDER BITMAP // This renders the imported bitmap to the screen. // It does not change the values in any of the arrays. // All it does is confirm that the image has been acquired. void renderBMP(Graphics::TBitmap* bm) { for (int y = 0; y < 700; y++) { t = (RGBTRIPLE*)bm->ScanLine[y]; for (int x = 0; x < WIDTH; x++) { Form1->Canvas->Pixels[x][y]= static_cast(RGB(t->rgbtRed, t->rgbtGreen, t->rgbtBlue)); t++; } } } //--------------------------------------------------- Color Ramp Version 2008 TColor colorRamp(int part, int whole) { if (whole == 0) whole++; // prevent divide by zero int pixelDistanceAlongEdges = (part * 1792) / whole; int red, green, blue; // Which edge of the color cube are we on? if (pixelDistanceAlongEdges < 256) { // from BLACK to BLUE red = 0; green = 0; blue = pixelDistanceAlongEdges; } else if (pixelDistanceAlongEdges < 512) { // from BLUE to CYAN red = 0; green = pixelDistanceAlongEdges - 256; blue = 255; } else if (pixelDistanceAlongEdges < 768) { // from CYAN to GREEN red = 0; green = 255; blue = 255 - (pixelDistanceAlongEdges - 512); } else if (pixelDistanceAlongEdges < 1024) { // from GREEN to YELLOW red = (pixelDistanceAlongEdges - 768); green = 255; blue = 0; } else if (pixelDistanceAlongEdges < 1280) { // from YELLOW to RED red = 255; green= 255-(pixelDistanceAlongEdges - 1024); blue = 0; } else if (pixelDistanceAlongEdges < 1536) { // from RED to MAGENTA red = 255; green= 0; blue = pixelDistanceAlongEdges - 1280; } else { // from MAGENTA to WHITE red = 255; green = pixelDistanceAlongEdges - 1537; blue = 255; } return static_cast(RGB(red, green, blue)); } //----------------------------------------------------------------- visualize void visualize (int i) { // move the agent IMAGE if called for if (Form1->RadioGroupMoveAgentImages->ItemIndex == 0) { image[i]->Left = agent[i]->x - image[i]->Width / 2; image[i]->Top = agent[i]->y - image[i]->Height / 2; } // move the agent CIRCLE if called for if (Form1->RadioGroupMoveAgentShapes->ItemIndex == 0) { shape[i]->Left = agent[i]->x - image[i]->Width / 2 + 10; shape[i]->Top = agent[i]->y - image[i]->Height / 2 + 12; } } //------------------------------------------------------------------- shuffle void shuffle (void) { for (int i = 0; i < curpop; i++) { agent[i]->x = random(650) + 25; agent[i]->y = random(605) + 45; visualize(i); agent[i]->direction = (float(random(360)) / 360) * 2 * M_PI; agent[i]->velocity = float(random(1000)) / 1500 + .1; agent[i]->lastNN = NNeighborTag = -1; agent[i]->seeking = random(curpop); int next = i+1; agent[i]->following = next; if (next == curpop) { agent[i]->following = 0; } while (i == agent[i]->seeking) { // don't seek self agent[i]->seeking = random(curpop); } for (int j = 0; j < curpop; j++) { agent[i]->encounters[j] = 0; } agent[i]->numEncounters = 0; agent[i]->flocking = false; for (int i = 0; i <= curpop; i++) { shape[i]->Brush->Color = colorRamp(shape[i]->Tag, curpop - 1); } } for (int i = 90; i < 100; i++) { agent[i]->sitting = false; agent[i]->x = random(650) + 25; agent[i]->y = random(605) + 45; visualize(i); } } //--------------------------------------------------------------------- reset void reset (void) { Form1->Refresh(); iterations = 0; Form1->EditIterations->Text = iterations; shuffle(); for (int i = 0; i < 700; i++) { for (int j = 0; j < 700; j++) { agentPath[i][j] = 0; iterationPath[i][j] = 0; } } } //-------------------------------------------------------------------- circle void circle (void) { Form1->Refresh(); for (int i = 0; i < curpop; i++) { agent[i]->x = 350 + 300 * cos(i * (2 * M_PI / curpop)); agent[i]->y = 350 + 300 * sin(i * (2 * M_PI / curpop)); visualize(i); } for (int i = 90; i < 100; i++) { agent[i]->x = 350 + 150 * cos(i * (2 * M_PI / 10)); agent[i]->y = 350 + 150 * sin(i * (2 * M_PI / 10)); visualize(i); } } //-------------------------------------------------------------------- corner void corner (void) { Form1->Refresh(); for (int i = 0; i < curpop; i++) { // move the agent IMAGE if called for if (Form1->RadioGroupMoveAgentImages->ItemIndex == 0) { image[i]->Left = 7; image[i]->Top = 10; } // move the agent CIRCLE if called for if (Form1->RadioGroupMoveAgentShapes->ItemIndex == 0) { shape[i]->Left = 0; shape[i]->Top = 0; } } } //------------------------------------------------------------- Add New Agent void addNewAgent (int i) { agent[i]->active = true; agent[i]->seeking = random(i); agent[i]->following = 0; agent[i-1]->following = i; shape[i]->Visible = true; shape[i]->SendToBack(); image[i]->Visible = true; image[i]->BringToFront(); Form1->ImageBackground->SendToBack(); visualize(i); } //------------------------------------------------------------- Kill Old Agent void killOldAgent (int i) { agent[i]->active = false; agent[i]->seeking = random(i); shape[i]->Visible = false; shape[i]->SendToBack(); image[i]->Visible = false; image[i]->BringToFront(); Form1->ImageBackground->SendToBack(); visualize(i); } //----------------------------------- returns a direction from agent A to B double directionFromTo (int from, int to) { if (to == CENTER) { x = CENTER; y = CENTER; } else { x = agent[to]->x - agent[from]->x; y = agent[to]->y - agent[from]->y; } return atan2(y, x); } //------------------------------------ returns a distance from agent A to B int distanceFromTo (int from, int to) { x = abs(agent[from]->x - agent[to]->x); y = abs(agent[from]->y - agent[to]->y); if (wrap) { // wrapped world if (x > 337) x = 675 - x; if (y > 327) y = 655 - y; } z = sqrt(x * x + y * y); return z; } //--------------------- calculates average Velocity and Direction of neighbors // within a radius void averageOfNeighbors (int me) { aveDir = 0; // average directions aveVelo = 0; // average velocities sumXs = 0; // x component sums sumYs = 0; // y component sums sumVisibleNeighbors = 0; // number of visible neighbors for (int i = 0; i < curpop; i++) { if (i == me) continue; x = abs(agent[i]->x - agent[me]->x); y = abs(agent[i]->y - agent[me]->y); if (wrap) { // wrapped world if (x > 337) x = 675 - x; if (y > 327) y = 655 - y; } z = sqrt(x * x + y * y); if (z < radius) { // average all visible neighbors sumVisibleNeighbors++; sumYs += agent[i]->velocity * sin(agent[i]->direction); sumXs += agent[i]->velocity * cos(agent[i]->direction); } } if ((sumYs != 0) && (sumXs != 0) && (sumVisibleNeighbors > 0)) { aveDir = atan2(sumYs, sumXs); aveVelo = sqrt(sumXs * sumXs + sumYs * sumYs) / sumVisibleNeighbors; } } //----------------------------------------------------- Find Nearest Thing To // this only searches the last 10 things in the array int findNThingTo (int who) { NThingTag = 0; // nearest thing NThingDist = 10000; // distance to nearest thing for (int i = 90; i < 100; i++) { if (i == who) continue; // will never happen x = abs(agent[i]->x - agent[who]->x); y = abs(agent[i]->y - agent[who]->y); if (wrap) { // wrapped world if (x > 337) x = 675 - x; if (y > 327) y = 655 - y; } z = sqrt(x * x + y * y); if (z < NThingDist) { // select nearest thing NThingDist = z; NThingTag = i; } } return NThingTag; } //----------------------------------------------------- FInd Nearest Agent To // this searches active agents from Tag 0 to curpop -1. int findNNeighborTo (int who) { NNeighborTag = 0; // nearest neighbor NNeighborDist = 10000; // distance to nearest neighbor for (int i = 0; i < curpop; i++) { if (i == who) continue; x = abs(agent[i]->x - agent[who]->x); y = abs(agent[i]->y - agent[who]->y); if (wrap) { // wrapped world if (x > 337) x = 675 - x; if (y > 327) y = 655 - y; } z = sqrt(x * x + y * y); if (z < NNeighborDist) { // select nearest neighbor NNeighborDist = z; NNeighborTag = i; } } return NNeighborTag; } //---------------------------------------------------- show nearest neighbor void showNearestNeighbor (int who) { if (agentsAreDisplayed) { // connect the IMAGES of the agents Form1->Canvas->Pen->Width = 1; Form1->Canvas->Pen->Color = clRed; Form1->Canvas->MoveTo(agent[who]->x, agent[who]->y); Form1->Canvas->LineTo(agent[findNNeighborTo(who)]->x, agent[findNNeighborTo(who)]->y); } else { // connect the PATHS of the agents Form1->PaintBox1->Canvas->Pen->Width = 2; Form1->PaintBox1->Canvas->Pen->Color = clWhite; Form1->PaintBox1->Canvas->Ellipse(agent[who]->x - 3, agent[who]->y - 3, agent[who]->x + 3, agent[who]->y + 3); Form1->PaintBox1->Canvas->MoveTo(agent[who]->x, agent[who]->y); Form1->PaintBox1->Canvas->LineTo(agent[findNNeighborTo(who)]->x, agent[findNNeighborTo(who)]->y); } Form1->Canvas->Pen->Width = 1; } //---------------------------------------------------- show perceptual field void showPerceptualField (int me) { Form1->Canvas->Brush->Style = bsClear; Form1->Canvas->Ellipse(agent[me]->x - radius, agent[me]->y - radius, agent[me]->x + radius, agent[me]->y + radius); } //-------------------------------------------------------------------- sonify // different sound types are associated with each of the 4 walls // the user may select Beep(), PlaySound(), or midiOutShortMsg() void sonify (int wall) { if (soundType == BEEP) { if (wall == EAST) Beep(196, 50); if (wall == SOUTH) Beep(261, 50); if (wall == WEST) Beep(330, 50); if (wall == NORTH) Beep(392, 50); } if (soundType == PLAYSOUNDWINDOWS) { if (wall == EAST) PlaySound("C:\\WINDOWS\\Media\\Windows XP Balloon.wav", NULL, SND_ASYNC); if (wall == SOUTH) PlaySound("C:\\WINDOWS\\Media\\Windows XP pop-up blocked.wav", NULL, SND_ASYNC); if (wall == WEST) PlaySound("C:\\WINDOWS\\Media\\Windows XP Balloon.wav", NULL, SND_ASYNC); if (wall == NORTH) PlaySound("C:\\WINDOWS\\Media\\Windows XP pop-up blocked.wav", NULL, SND_ASYNC); } if (soundType == PLAYSOUNDPINBALL) { if (wall == EAST) PlaySound("C:\\Program Files\\Windows NT\\Pinball\\SOUND181.wav", NULL, SND_ASYNC); if (wall == SOUTH) PlaySound("C:\\Program Files\\Windows NT\\Pinball\\SOUND243.wav", NULL, SND_ASYNC); if (wall == WEST) PlaySound("C:\\Program Files\\Windows NT\\Pinball\\SOUND713.wav", NULL, SND_ASYNC); if (wall == NORTH) PlaySound("C:\\Program Files\\Windows NT\\Pinball\\SOUND735.wav", NULL, SND_ASYNC); } if (soundType == MIDI) { if (wall == EAST) { message.data[0] = 0x90; message.data[1] = 55; midiOutShortMsg(device, message.word); } if (wall == SOUTH) { message.data[0] = 0x90; message.data[1] = 60; midiOutShortMsg(device, message.word); } if (wall == WEST) { message.data[0] = 0x90; message.data[1] = 64; midiOutShortMsg(device, message.word); } if (wall == NORTH) { message.data[0] = 0x90; message.data[1] = 67; midiOutShortMsg(device, message.word); } } } //---------------------------------------------------------------------- step void step (void) { iterations++; Form1->EditIterations->Text = iterations; increment = Form1->TrackBarIncrement->Position; for (who = 0; who < curpop; who++) { if (polling == RANDOM) i = random(curpop); if (polling == SEQUENTIAL) i = who; // calculate agent's new position based on velocity and direction agent[i]->x += agent[i]->velocity * cos(agent[i]->direction) * increment; agent[i]->y += agent[i]->velocity * sin(agent[i]->direction) * increment; visualize(i); /////////////////////////////////////////////////////////////////////// ///////////////////// FLOCKING BEHAVIORS BELOW //////////////////////// /////////////////////////////////////////////////////////////////////// // adopt your nearest neighbor's direction 1 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 1) { agent[i]->direction = agent[findNNeighborTo(i)]->direction; } // increment your direction by 1/100 your nearest neighbor's 2 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 2) { agent[i]->direction += agent[findNNeighborTo(i)]->direction / 100; if (agent[i]->direction > 2 * M_PI) { // modulo divide agent[i]->direction = agent[i]->direction - 2 * M_PI; } } // decrement your direction by 1/200 your nearest neighbor's 3 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 3) { agent[i]->direction -= agent[findNNeighborTo(i)]->direction / 200; if (agent[i]->direction > 2 * M_PI) { // modulo divide agent[i]->direction = agent[i]->direction - 2 * M_PI; } } // adopt your nearest neighbor's velocity 4 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 4) { agent[i]->velocity = agent[findNNeighborTo(i)]->velocity; } // seek a random other agent but don't seek yourself 5 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 5 && i != agent[i]->seeking) { if (i % 4 == 0) { // 1/4 of the time do this agent[i]->direction = .01 * mult + directionFromTo(i, agent[i]->seeking); } if (i % 4 == 1) { // 1/4 of the time do this agent[i]->direction = .015 * mult + directionFromTo(i, agent[i]->seeking); } if (i % 4 == 2) { // 1/4 of the time do this agent[i]->direction = .02 * mult + directionFromTo(i, agent[i]->seeking); } if (i % 4 == 3) { // 1/4 of the time do this agent[i]->direction = .025 * mult + directionFromTo(i, agent[i]->seeking); } } // adopt your nearest neighbor's direction and speed 6 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 6) { agent[i]->velocity = agent[findNNeighborTo(i)]->velocity; agent[i]->direction = agent[findNNeighborTo(i)]->direction; } // STRAIGHT COUPLES 7 // if same sex: both reverse direction and take random velocities // if opposite sex: both take average direction and NN velocity if (Form1->RadioGroupFlockingBehavior->ItemIndex == 7) { findNNeighborTo(i); if ((NNeighborDist < radius) && (agent[i]->lastNN != NNeighborTag)) { if (agent[i]->sex == agent[NNeighborTag]->sex) { // leave if (behavioralSonification) { message.data[0] = 0x90; message.data[1] = 55; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } agent[i]->direction += M_PI; if (agent[i]->direction > 2 * M_PI) { agent[i]->direction = agent[i]->direction - 2 * M_PI; } agent[NNeighborTag]->direction += M_PI; if (agent[NNeighborTag]->direction > 2 * M_PI) { agent[NNeighborTag]->direction = agent[NNeighborTag]->direction - 2 * M_PI; } agent[i]->velocity = float(random(1000)) / 1500 + .1; agent[NNeighborTag]->velocity = float(random(1000)) / 1500 + .1; } else { // join if (behavioralSonification) { message.data[0] = 0x90; message.data[1] = 67; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } sumYs = agent[i]->velocity * sin(agent[i]->direction) + agent[NNeighborTag]->velocity * sin(agent[NNeighborTag]->direction); sumXs = agent[i]->velocity * cos(agent[i]->direction) + agent[NNeighborTag]->velocity * cos(agent[NNeighborTag]->direction); agent[i]->direction = atan2(sumYs, sumXs); agent[NNeighborTag]->direction = agent[i]->direction; agent[i]->velocity = sqrt(sumYs * sumYs + sumXs * sumXs) / 2; agent[NNeighborTag]->velocity = agent[i]->velocity; } agent[i]->lastNN = NNeighborTag; // remember lastNN agent[NNeighborTag]->lastNN = i; agent[i]->encounters[NNeighborTag]++; // remember encounter agent[i]->numEncounters++; agent[NNeighborTag]->encounters[i]++; agent[NNeighborTag]->numEncounters++; } } // GAY/LES COUPLES 8 // if opposite sex: both reverse direction and take random velocities // if same sex: both take average direction and NN velocity if (Form1->RadioGroupFlockingBehavior->ItemIndex == 8) { findNNeighborTo(i); if ((NNeighborDist < radius) && (agent[i]->lastNN != NNeighborTag)) { if (agent[i]->sex != agent[NNeighborTag]->sex) { // leave if (behavioralSonification) { message.data[0] = 0x90; message.data[1] = 55; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } agent[i]->direction += M_PI; if (agent[i]->direction > 2 * M_PI) { agent[i]->direction = agent[i]->direction - 2 * M_PI; } agent[NNeighborTag]->direction += M_PI; if (agent[NNeighborTag]->direction > 2 * M_PI) { agent[NNeighborTag]->direction = agent[NNeighborTag]->direction - 2 * M_PI; } agent[i]->velocity = float(random(1000)) / 1500 + .1; agent[NNeighborTag]->velocity = float(random(1000)) / 1500 + .1; } else { // join if (behavioralSonification) { message.data[0] = 0x90; message.data[1] = 67; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } sumYs = agent[i]->velocity * sin(agent[i]->direction) + agent[NNeighborTag]->velocity * sin(agent[NNeighborTag]->direction); sumXs = agent[i]->velocity * cos(agent[i]->direction) + agent[NNeighborTag]->velocity * cos(agent[NNeighborTag]->direction); agent[i]->direction = atan2(sumYs, sumXs); agent[NNeighborTag]->direction = agent[i]->direction; agent[i]->velocity = sqrt(sumYs * sumYs + sumXs * sumXs) / 2; agent[NNeighborTag]->velocity = agent[i]->velocity; } agent[i]->lastNN = NNeighborTag; // remember lastNN agent[NNeighborTag]->lastNN = i; agent[i]->encounters[NNeighborTag]++; // remember encounter agent[i]->numEncounters++; agent[NNeighborTag]->encounters[i]++; agent[NNeighborTag]->numEncounters++; } } // Your direction and velocity are the average of those 9 // you can see within a given radius... if (Form1->RadioGroupFlockingBehavior->ItemIndex == 9) { averageOfNeighbors(i); if (aveVelo != 0 && aveDir != 0 && sumVisibleNeighbors > 1) { if (random(2)) { agent[i]->velocity = aveVelo + (float(random(50))/200); } else { agent[i]->velocity = aveVelo - (float(random(50))/200); } if (random(2)) { agent[i]->direction = aveDir + (float(random(10))/360)*2*M_PI; } else { agent[i]->direction = aveDir - (float(random(10))/360)*2*M_PI; } agent[i]->flocking = true; } else if (agent[i]->flocking == TRUE) { agent[i]->direction = (float(random(360))/360)*2*M_PI; agent[i]->velocity = float(random(1000)) / 1500 + .1; agent[i]->flocking = false; } } // Musical Chairs cycle all things once per iteration 10 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 10) { findNThingTo(i); // finds NThingTag and NThingDist if (agent[NThingTag]->sitting == false) { // go to chair agent[i]->direction = directionFromTo(i, NThingTag); } else { // go away agent[i]->direction += .01 * directionFromTo(i, CENTER); //agent[i]->direction += .02; //agent[i]->direction = directionFromTo(i, i + 90); } // sit down if (NThingDist < 5 && agent[NThingTag]->sitting == false) { agent[i]->sitting = true; agent[i]->velocity = 0; agent[NThingTag]->sitting = true; } } // follow neighbor, i+1 11 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 11) { for (int i = 0; i < curpop; i++) { agent[i]->velocity = float(Form1->TrackbarFollow->Position) / 1500 + .1; } agent[i]->direction = .02 * mult + directionFromTo(i, agent[i]->following); } // follow neighbor, i+1; agent[curpop] follows mouse click 12 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 12) { if (followingTheLeader == false) { for (int i = 0; i < (curpop); i++) { agent[i]->velocity = float(Form1->TrackbarFollow->Position) / 1500 + .1; agent[i]->direction = (Form1->TrackbarFolRad->Position)/100 * mult + directionFromTo(i, agent[i]->following); } } if (followingTheLeader == true) { agent[i]->velocity = float(Form1->TrackbarFollow->Position) / 1500 + .1; for (int i = 0; i < (curpop-1); i++) { agent[i]->direction = (Form1->TrackbarFolRad->Position)/100 * mult + directionFromTo(i, agent[i]->following); } if (i == curpop - 1) { agent[i]->direction = 0.02 * mult + directionFromTo(i, 88); } } } // follow leader with leader traveling in square 13 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 13) { if (i < (curpop-1)) { for (int i = 0; i < curpop; i++) { agent[i]->velocity = float(Form1->TrackbarFollow->Position) / 1500 + .1; } agent[i]->direction = .1 * mult + directionFromTo(i, agent[i]->following); } if (i == curpop) { double squareX1 = 100 - agent[i]->x; double squareY1 = 100 - agent[i]->y; double squareX2 = 600 - agent[i]->x; double squareY2 = 100 - agent[i]->y; double squareX3 = 600 - agent[i]->x; double squareY3 = 600 - agent[i]->y; double squareX4 = 100 - agent[i]->x; double squareY4 = 600 - agent[i]->y; double squareDir1 = atan2(squareY1, squareX1); double squareDir2 = atan2(squareY2, squareX2); double squareDir3 = atan2(squareY3, squareX3); double squareDir4 = atan2(squareY4, squareX4); if (iterations = 1) { if (agent[i]->x < 350 && agent[i]->y < 350) { agent[i]->direction = squareDir1; } if (agent[i]->x >= 350 && agent[i]->y < 350) { agent[i]->direction = squareDir2; } if (agent[i]->x >= 350 && agent[i]->y >= 350) { agent[i]->direction = squareDir3; } if (agent[i]->x < 350 && agent[i]->y >= 350) { agent[i]->direction = squareDir4; } } else { if (agent[i]->x == 100 && agent[i]->y == 100) { agent[i]->direction = squareDir2; } if (agent[i]->x == 600 && agent[i]->y == 100) { agent[i]->direction = squareDir3; } if (agent[i]->x == 600 && agent[i]->y == 600) { agent[i]->direction = squareDir4; } if (agent[i]->x == 100 && agent[i]->y == 600) { agent[i]->direction = squareDir1; } } } } // follow neighbor, i+1; agent[curpop] follows mouse click 14 if (Form1->RadioGroupFlockingBehavior->ItemIndex == 14) { if (followingTheCursor == false) { for (int i = 0; i < (curpop); i++) { agent[i]->velocity = float(Form1->TrackbarFollow->Position) / 1500 + .1; agent[i]->direction = (Form1->TrackbarFolRad->Position)/100 * mult + directionFromTo(i, agent[i]->following); } } if (followingTheCursor == true) { agent[i]->velocity = float(Form1->TrackbarFollow->Position) / 1500 + .1; for (int i = 0; i < (curpop-1); i++) { agent[i]->direction = (Form1->TrackbarFolRad->Position)/100 * mult + directionFromTo(i, agent[i]->following); } if (i == curpop - 1) { agent[i]->direction = 0.02 * mult + directionFromTo(i, 89); } } } /////////////////////////////////////////////////////////////////////// ///////////////////// FLOCKING BEHAVIORS ABOVE /////////////////////// /////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// WRAP if (wrap) { if (agent[i]->x > 675) { agent[i]->x = 25; sonify(EAST); } if (agent[i]->y > 655) { agent[i]->y = 45; sonify(SOUTH); } if (agent[i]->x < 25) { agent[i]->x = 675; sonify(NORTH); } if (agent[i]->y < 45) { agent[i]->y = 655; sonify(WEST); } visualize(i); } //////////////////////////////////////////////////////////////// BOUNCE else { if (agent[i]->x > 675) { agent[i]->x = 674; agent[i]->direction = M_PI - agent[i]->direction; sonify(EAST); } if (agent[i]->y > 655) { agent[i]->y = 654; agent[i]->direction = 2 * M_PI - agent[i]->direction; sonify(SOUTH); } if (agent[i]->x < 25) { agent[i]->x = 26; agent[i]->direction = M_PI - agent[i]->direction; sonify(WEST); } if (agent[i]->y < 45) { agent[i]->y = 46; agent[i]->direction = 2 * M_PI - agent[i]->direction; sonify(NORTH); } // modular divide direction by one rotation if (agent[i]->direction > 2 * M_PI) { agent[i]->direction = agent[i]->direction - 2 * M_PI; } if (agent[i]->direction < 0) { agent[i]->direction = agent[i]->direction + 2 * M_PI; } } ///////////////////////////////////////////////////////// RECORD A PATH ix = agent[i]->x; iy = agent[i]->y; iterationPath[ix][iy] = iterations; agentPath[ix][iy] = i + 5; } } //----------------------------------------------------------------------- Run void run (void) { Form1->Refresh(); agentsAreDisplayed = true; stop = false; showNNs = false; while (stop == false && iterations < runTo) { step(); Application->ProcessMessages(); } if (!mouseDown) { PlaySound("C:\\WINDOWS\\Media\\chimes.wav", NULL, SND_ASYNC); } if (showNNs) { for (int i = 0; i < curpop; i++) { showNearestNeighbor(i); } } stop = true; showNNs = false; } //=========================================================================== // EVENT HANDLERS //=========================================================================== //---------------------------- BORLAND will create this EVENT HANDLER for you //------------------------------- Place your VARIABLES and FUNCTIONS ABOVE it // ------------------------------------------ Use this instead of FORM CREATE __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Randomize(); curpop = INIPOP; // Double buffering eliminates some screen flicker but takes 30% longer. DoubleBuffered = true; randomize(); // initializes MIDI midiOutOpen(&device, midiport, 0, 0, CALLBACK_NULL); message.data[0] = 0xC0; message.data[1] = 6; message.data[2] = 100; // we don't need to repeat these message.data[3] = 0; // we don't need to repeat these midiOutShortMsg(device, message.word); // INITIALIZE ALL AGENTS for (int i = 0; i < MAXPOP; i++) { // defines an array of agents agent[i] = new anAgent; agent[i]->x = random(650) + 25; agent[i]->y = random(605) + 45; agent[i]->direction = (float(random(1000)) / 500) * M_PI; agent[i]->velocity = float(random(1000)) / 1500 + .1; agent[i]->flocking = false; if (i % 10 == 0) { agent[i]->color = WHITE; agent[i]->sex = WOMAN; } if (i % 10 == 1) { agent[i]->color = WHITE; agent[i]->sex = MAN; } if (i % 10 == 2) { agent[i]->color = CYAN; agent[i]->sex = WOMAN; } if (i % 10 == 3) { agent[i]->color = CYAN; agent[i]->sex = MAN; } if (i % 10 == 4) { agent[i]->color = MAGENTA; agent[i]->sex = WOMAN; } if (i % 10 == 5) { agent[i]->color = MAGENTA; agent[i]->sex = MAN; } if (i % 10 == 6) { agent[i]->color = YELLOW; agent[i]->sex = WOMAN; } if (i % 10 == 7) { agent[i]->color = YELLOW; agent[i]->sex = MAN; } if (i % 10 == 8) { agent[i]->color = BLACK; agent[i]->sex = WOMAN; } if (i % 10 == 9) { agent[i]->color = BLACK; agent[i]->sex = MAN; } agent[i]->newDirection = 0; agent[i]->newDistance = 0; agent[i]->lastDistance = 0; agent[i]->flocking = 0; agent[i]->lastNN = -1; agent[i]->sitting = false; agent[i]->seeking = random(MAXPOP); while (i == agent[i]->seeking) { // don't seek self agent[i]->seeking = random(MAXPOP); } if (i < curpop) { agent[i]->active = true; } else agent[i]->active = false; for (int j = 0; j < MAXPOP; j++) { agent[i]->encounters[j] = 0; } // defines an array of images with properties and events image[i] = new TImage(Form1); image[i]->Parent = Form1; image[i]->OnMouseDown = Form1->ImageMouseDown; image[i]->OnMouseUp = Form1->ImageMouseUp; image[i]->OnMouseMove = Form1->ImageMouseMove; image[i]->AutoSize= true; image[i]->Left = 0; image[i]->Top = 0; if (i % 10 == 0) { image[i]->Picture = Form1->ImageWomanWhite->Picture; } if (i % 10 == 1) { image[i]->Picture = Form1->ImageManWhite->Picture; } if (i % 10 == 2) { image[i]->Picture = Form1->ImageWomanCyan->Picture; } if (i % 10 == 3) { image[i]->Picture = Form1->ImageManCyan->Picture; } if (i % 10 == 4) { image[i]->Picture = Form1->ImageWomanMagenta->Picture; } if (i % 10 == 5) { image[i]->Picture = Form1->ImageManMagenta->Picture; } if (i % 10 == 6) { image[i]->Picture = Form1->ImageWomanYellow->Picture; } if (i % 10 == 7) { image[i]->Picture = Form1->ImageManYellow->Picture; } if (i % 10 == 8) { image[i]->Picture = Form1->ImageWomanBlack->Picture; } if (i % 10 == 9) { image[i]->Picture = Form1->ImageManBlack->Picture; } image[i]->Transparent = true; image[i]->Tag = i; image[i]->BringToFront(); if (i < curpop) { image[i]->Visible = true; } else image[i]->Visible = false; // defines an array of shapes with properties and events shape[i] = new TShape(Form1); shape[i]->Parent = Form1; //shape[i]->OnMouseDown = ShapeMouseDown; //shape[i]->OnMouseUp = ShapeMouseUp; //shape[i]->OnMouseMove = ShapeMouseMove; shape[i]->Height = 30; shape[i]->Width = 30; shape[i]->Left = 0; shape[i]->Top = 0; shape[i]->Shape = stCircle; shape[i]->Tag = i; shape[i]->Pen->Width = 2; //shape[i]->Pen->Color = colorRamp // (INIPOP - 1 - shape[i]->Tag, INIPOP - 1); shape[i]->Pen->Color = clGray; shape[i]->Brush->Color = colorRamp(shape[i]->Tag, INIPOP - 1); shape[i]->SendToBack(); if (i < curpop) { shape[i]->Visible = true; } else shape[i]->Visible = false; } // create some "thing" agents as the last agents in MAXPOP // we overwrite the previous assignments for (int i = 90; i < 100; i++) { agent[i]->kind = CHAIR; //agent[i]->type = BLACK; image[i]->Picture = ImageChairPrototype->Picture; image[i]->Visible = false; } for (int i = 0; i < INIPOP; i++) { image[i]->BringToFront(); } // send the background behind every "thing" and "human" Form1->ImageBackground->SendToBack(); Form1->EditPopulation->Text = INIPOP; shuffle(); } //------------------------------------------------------- On image MOUSE DOWN // An exception to the rule which says "Let Borland write event handlers." // This one you must type in yourself in addition to a reference to it // in Unit1.h (look at the source code in that unit). void __fastcall TForm1::ImageMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { // Remembers where on the image the mouse was downed TImage *image = dynamic_cast(Sender); // The following will be used for mouseMove and mouseUp events... // Captures the index number of the image that was clicked chosenAgent = image->Tag; // Captures the position within the image that was clicked imageDownX = X; imageDownY = Y; // Captures the position of the agent when its image was clicked agentDownX = agent[chosenAgent]->x; agentDownY = agent[chosenAgent]->y; // remembers if we were stopped or running wasStopped = stop; mouseDown = true; stop = true; if (Button == 0) { // LEFT Button means drag an agent image // Remembers that an image was chosen for mouseMove and mouseUp agentWasJustChosen = true; } else { // RIGHT Button means show nearest neighbor showNearestNeighbor(chosenAgent); showPerceptualField(chosenAgent); } // Capture time on Mouse Down timeDown = Now(); } //------------------------------------------------------- On image MOUSE MOVE // An exception to the rule which says "Let Borland write event handlers." // This one you must type in yourself in addition to a reference to it // in Unit1.h (look at the source code in that unit). void __fastcall TForm1::ImageMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { TImage *image = dynamic_cast(Sender); chosenAgent = image->Tag; if (agentWasJustChosen) { // drag an agent image // this drags the image along... image->Left = image->Left + X - imageDownX; image->Top = image->Top + Y - imageDownY; agent[chosenAgent]->x = image->Left + image->Width / 2; agent[chosenAgent]->y = image->Top + image->Height / 2; } else if (image->Tag != lastMouseOver) { // probe an agent // agent values are displayed ONLY ONCE per MouseMove Form1->Refresh(); EditAgent->Text = image->Tag; EditX->Text = int(agent[chosenAgent]->x); EditY->Text = int(agent[chosenAgent]->y); EditSeeking->Text = agent[chosenAgent]->seeking; EditEncounters->Text = agent[chosenAgent]->numEncounters; if (agent[chosenAgent]->color == WHITE) EditType->Text = "White"; if (agent[chosenAgent]->color == CYAN) EditType->Text = "Cyan"; if (agent[chosenAgent]->color == MAGENTA) EditType->Text = "Magenta"; if (agent[chosenAgent]->color == YELLOW) EditType->Text = "Yellow"; if (agent[chosenAgent]->color == BLACK) EditType->Text = "Gray"; if (agent[chosenAgent]->color == RED) EditType->Text = "Red"; if (agent[chosenAgent]->color == GREEN) EditType->Text = "Green"; if (agent[chosenAgent]->color == BLUE) EditType->Text = "Blue"; EditDirection->Text = FormatFloat("0.00", agent[chosenAgent]->direction); EditVelocity->Text = FormatFloat("0.00", agent[chosenAgent]->velocity); for (int i = 0; i < curpop; i++) { Form1->Canvas->TextOutA(agent[i]->x - 3, agent[i]->y - 4, agent[chosenAgent]->encounters[i]); if (i == chosenAgent) { Form1->Canvas->TextOutA(agent[i]->x - 7, agent[i]->y - 4, "ME"); } } if (agent[chosenAgent]->kind == WOMAN) EditSex->Text= "Woman"; if (agent[chosenAgent]->kind == MAN) EditSex->Text= "Man"; if (agent[chosenAgent]->kind == ALIEN) EditSex->Text= "Alien"; if (agent[chosenAgent]->kind == CHAIR) EditSex->Text= "Chair"; EditNN->Text = findNNeighborTo(chosenAgent); lastMouseOver = chosenAgent; } } //--------------------------------------------------------- On image MOUSE UP // An exception to the rule which says "Let Borland write event handlers." // This one you must type in yourself in addition to a reference to it // in Unit1.h (look at the source code in that unit). void __fastcall TForm1::ImageMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { mouseDown = false; //TImage *image = dynamic_cast(Sender); // this is the end of the drag... agentWasJustChosen = false; EditAgent->Text = chosenAgent; // Capture Position of Agent on Mouse Up agentUpY = agent[chosenAgent]->y; agentUpX = agent[chosenAgent]->x; // Capture Change of Position of Agent dY = agentUpY - agentDownY; dX = agentUpX - agentDownX; // Avoid division by zero in "atan(dY / dX)" below: if (dX == 0) { dX = 0.0000000000001; } // Assign new agent direction: agent[chosenAgent]->direction = atan2(dY, dX); // Capture Time on Mouse Up timeUp = Now(); // Assign New Agent Velocity as "distance / time": agent[chosenAgent]->velocity = (sqrt((dY*dY) + (dX * dX))/(timeUp - timeDown)) / 15000000; Form1->Refresh(); // if we were running before the drag, then run... if (!wasStopped) { run(); } } //---------------------------------------------------------------- Run BUTTON void __fastcall TForm1::ButtonRunClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); Form1->LabelPathsBy->Visible = false; run(); } //--------------------------------------------------------------- Step BUTTON void __fastcall TForm1::ButtonStepClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); Form1->LabelPathsBy->Visible = false; Form1->Refresh(); stop = true; step(); } //--------------------------------------------------------------- Stop BUTTON void __fastcall TForm1::ButtonStopClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); stop = true; } //---------------------------------------------------------- Randomize BUTTON void __fastcall TForm1::ButtonResetClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); Form1->LabelPathsBy->Visible = false; reset(); } //------------------------------------------------------------- Circle BUTTON void __fastcall TForm1::ButtonCircleClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); Form1->LabelPathsBy->Visible = false; circle(); } //----------------------------------------------------------- Sideline BUTTON void __fastcall TForm1::ButtonSidelineClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); Form1->LabelPathsBy->Visible = false; corner(); } //--------------------------------------------- Show Nearest Neighbors BUTTON void __fastcall TForm1::ButtonShowNNsClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); if (agentsAreDisplayed) Form1->Refresh(); if (stop) { for (int i = 0; i < curpop; i++) { showNearestNeighbor(i); } } else { showNNs = true; stop = true; } } //-------------------------------------------------------- Open Bitmap BUTTON void __fastcall TForm1::ButtonOpenBMPClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); if (OpenBitMapDialog->Execute() ) b->LoadFromFile(OpenBitMapDialog->FileName); bmpToArray(b); renderBMP(b); } //------------------------------------------------ Show Paths By Agent BUTTON void __fastcall TForm1::ButtonShowPathsByAgent2dClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); agentsAreDisplayed = false; Form1->LabelPathsBy->Visible = true; Form1->LabelPathsBy->Caption = "Paths Colored by Agent"; for (int i = 0; i < 700; i++) { for (int j = 0; j < 700; j++) { Form1->PaintBox1->Canvas->Pixels[i][j] = colorRamp(agentPath[i][j], curpop + 4); } } Form1->LabelPathsBy->BringToFront(); } //------------------------------------------------- Show Paths By Time BUTTON void __fastcall TForm1::ButtonShowPathsByTime2dClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); agentsAreDisplayed = false; Form1->LabelPathsBy->Visible = true; Form1->LabelPathsBy->Caption = "Paths Colored by Time"; for (int i = 0; i < 700; i++) { for (int j = 0; j < 700; j++) { Form1->PaintBox1->Canvas->Pixels[i][j] = colorRamp(iterationPath[i][j], iterations); } } Form1->LabelPathsBy->BringToFront(); } //------------------------------------------------------- Add an Agent BUTTON void __fastcall TForm1::ButtonAddAnAgentClick(TObject *Sender) { if (curpop < 100) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); addNewAgent(curpop); curpop++; Form1->EditPopulation->Text = curpop; } else { PlaySound ("C:\\WINDOWS\\Media\\Windows XP Battery Low.wav", NULL, SND_ASYNC); } } //------------------------------------------------------ Kill an Agent BUTTON void __fastcall TForm1::ButtonKillAnAgentClick(TObject *Sender) { if (curpop > 2) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); curpop--; killOldAgent(curpop); Form1->EditPopulation->Text = curpop; } else { PlaySound ("C:\\WINDOWS\\Media\\Windows XP Battery Low.wav", NULL, SND_ASYNC); } } //--------------------------------------------------- Zeroize Velocity BUTTON void __fastcall TForm1::ButtonZeroizeVelocityClick(TObject *Sender) { for (int i = 0; i < curpop; i++) { agent[i]->velocity = 0; } } //-------------------------------------------------- Zeroize Direction BUTTON void __fastcall TForm1::ButtonZeroizeDirectionClick(TObject *Sender) { for (int i = 0; i < curpop; i++) { agent[i]->direction = 0; } } //------------------------------------------------ Show All Encounters BUTTON void __fastcall TForm1::ButtonShowAllEncountersClick(TObject *Sender) { Form1->Canvas->Pen->Width = 3; int maxEncounters = 0; for (int i = 0; i < curpop; i++) { // find maximum encounters for (int j = 0; j < curpop; j++) { if (agent[i]->encounters[j] > maxEncounters) { maxEncounters = agent[i]->encounters[j]; } } } for (int i = 0; i < curpop; i++) { // show all encounters for (int j = 0; j < curpop; j++) { if (maxEncounters > 0) Form1->Canvas->Pen->Width = 10 * float(agent[i]->encounters[j]) / maxEncounters; else Form1->Canvas->Pen->Width = 0; Form1->Canvas->Pen->Color = colorRamp (agent[i]->encounters[j], maxEncounters); if (agent[i]->encounters[j] > 0) { Form1->Canvas->MoveTo(agent[i]->x, agent[i]->y); Form1->Canvas->LineTo(agent[j]->x, agent[j]->y); } } } } //---------------------------------------------------------- Show Tags BUTTON void __fastcall TForm1::ButtonShowTagsClick(TObject *Sender) { for (int i = 0; i < curpop; i++) { Form1->Canvas->TextOutA(agent[i]->x - 3, agent[i]->y - 4, i); } } //---------------------------------------------- Move Agent Images RADIOGROUP void __fastcall TForm1::RadioGroupMoveAgentImagesClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); } //---------------------------------------------- Move Agent Shapes RADIOGROUP void __fastcall TForm1::RadioGroupMoveAgentShapesClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); } //---------------------------------------------- Flocking Behavior RADIOGROUP void __fastcall TForm1::RadioGroupFlockingBehaviorClick(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); if (RadioGroupFlockingBehavior->ItemIndex == 10) chairs(true); else chairs(false); } //----------------------------------- Perceptual Field Radius Change TRACKBAR void __fastcall TForm1::TrackBarRadiusChange(TObject *Sender) { Form1->Refresh(); radius = TrackBarRadius->Position; Form1->EditRadius->Text = radius; if (stop == true) { for (int i = 0; i < curpop; i++) { showPerceptualField(i); } } } //---------------------------------------------------------------- FORM CLOSE void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { midiOutClose(&device); } //--------------------------------------------------------------------------- void __fastcall TForm1::N1001Click(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); runTo = 100; } //---------------------------------------------------------- MENU ITEMS BELOW void __fastcall TForm1::N5001Click(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); runTo = 500; } //--------------------------------------------------------------------------- void __fastcall TForm1::N10001Click(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); runTo = 1000; } //--------------------------------------------------------------------------- void __fastcall TForm1::N50001Click(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); runTo = 5000; } //--------------------------------------------------------------------------- void __fastcall TForm1::N100001Click(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); runTo = 10000; } //--------------------------------------------------------------------------- void __fastcall TForm1::N500001Click(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); runTo = 50000; } //--------------------------------------------------------------------------- void __fastcall TForm1::Off1Click(TObject *Sender) { soundType = 0; } //--------------------------------------------------------------------------- void __fastcall TForm1::Beep1Click(TObject *Sender) { soundType = 1; behavioralSonification = false; Form1->Off2->Checked = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Windows1Click(TObject *Sender) { soundType = 2; behavioralSonification = false; Form1->Off2->Checked = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Pinball1Click(TObject *Sender) { soundType = 3; behavioralSonification = false; Form1->Off2->Checked = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Midi1Click(TObject *Sender) { soundType = 4; behavioralSonification = false; Form1->Off2->Checked = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Off2Click(TObject *Sender) { behavioralSonification = false; } //--------------------------------------------------------------------------- void __fastcall TForm1::On1Click(TObject *Sender) { behavioralSonification = true; soundType = false; Form1->Off1->Checked = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Sequential1Click(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); polling = SEQUENTIAL; } //--------------------------------------------------------------------------- void __fastcall TForm1::Random1Click(TObject *Sender) { PlaySound("C:\\WINDOWS\\Media\\start.wav", NULL, SND_ASYNC); polling = RANDOM; } //--------------------------------------------------------------------------- void __fastcall TForm1::Wrap1Click(TObject *Sender) { wrap = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Bounce1Click(TObject *Sender) { wrap = false; } //--------------------------------------------------------------------------- //-------------------------------------------------------- "That's All Folks" void __fastcall TForm1::TrackBarMultiplierChange(TObject *Sender) { mult = TrackBarMultiplier->Position; } //--------------------------------------------------------------------------- void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { followingTheCursor = true; agent[89]->x = X; agent[89]->y = Y; } //--------------------------------------------------------------------------- void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { followingTheLeader = true; agent[88]->x = X; agent[88]->y = Y; } //---------------------------------------------------------------------------