//=========================================================================== // A FRAMEWORK FOR TRAFFIC // May 2004 //=========================================================================== //--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "Unit1.h" // The following two lines are needed to enable the randomizer #include "stdlib.h" #include "time.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { // Double buffering eliminates some screen flicker... DoubleBuffered = true; } //--------------------------------------------------------------------------- //=========================================================================== // GLOBAL VARIABLES //=========================================================================== // ------------------------------------------------- your program begins here TShape *shape[24] = {0}; // sets up an array of shapes class aVehicle { public: float velocity; double direction; double newDirection; double newDistance; double lastDistance; float x; float y; } vehicle[24]; bool stop = true; int iterations; int i; int chosenVehicle; bool vehicleWasJustChosen = false; //=========================================================================== // FUNCTIONS //=========================================================================== //---------------------------------------------------------------- color ramp int colorRamp(int range, int value) { int pixelDistanceAlongPath = (value * 1792) / range; int red, green, blue; // Which edge of the color cube are we on? if (pixelDistanceAlongPath < 256) { // Edge 1 from BLACK to BLUE red=0; green=0; blue=pixelDistanceAlongPath; } else if (pixelDistanceAlongPath < 512) { // Edge 2 from BLUE to CYAN red =0; green=pixelDistanceAlongPath-256; blue=255; } else if (pixelDistanceAlongPath < 768) { // Edge 3 from CYAN to GREEN red =0; green =255; blue= 255-(pixelDistanceAlongPath-512); } else if (pixelDistanceAlongPath < 1024) { // Edge 4 from GREEN to YELLOW red= (pixelDistanceAlongPath-768); green =255; blue =0; } else if (pixelDistanceAlongPath <1280) { // Edge 5 from YELLOW to RED red =255; green=255-(pixelDistanceAlongPath-1024); blue =0; } else if (pixelDistanceAlongPath < 1536) { // Edge 6 from RED to MAGENTA red =255; green=0; blue=pixelDistanceAlongPath -1280; } else { // Edge 7 from MAGENTA to WHITE red =255; green=pixelDistanceAlongPath-1536; blue =255; } return (RGB(red, green, blue)); } //------------------------------------------------------------------- shuffle void shuffle (void) { for (int i = 0; i < 24; i++) { vehicle[i].x = random(400); shape[i]->Left = vehicle[i].x; vehicle[i].y = random(400); shape[i]->Top = vehicle[i].y; vehicle[i].direction = (float(random(1000)) / 500) * M_PI; vehicle[i].velocity = float(random(1000)) / 1500 + .1; } } //--------------------------------------------------------------------- reset void reset (void) { iterations = 0; Form1->EditIterations->Text = iterations; shuffle(); } //-------------------------------------------------------------------- circle void circle (void) { for (int i = 0; i < 24; i++) { vehicle[i].x = 200 + 180 * cos(i * (2 * M_PI / 24)); vehicle[i].y = 200 + 180 * sin(i * (2 * M_PI / 24)); shape[i]->Left = vehicle[i].x; shape[i]->Top = vehicle[i].y; } } //----------------------------------------------------------------- circulate // The code for this function is bad void circulate (void) { for (int j = 0; j < 100; j++) { for (int i = 0; i < 23; i++) { vehicle[i].newDistance = sqrt( pow(vehicle[i+1].x - vehicle[i].x, 2) + pow(vehicle[i+1].y - vehicle[i].y, 2)); if (vehicle[i+1].x - vehicle[i].x == 0) { vehicle[i].newDirection = atan(0); } else vehicle[i].newDirection = atan( vehicle[i+1].y - vehicle[i].y / vehicle[i+1].x - vehicle[i].x); } vehicle[23].newDistance = sqrt( pow(vehicle[23].x - vehicle[0].x, 2) + pow(vehicle[23].y - vehicle[0].y, 2)); vehicle[23].newDirection = atan( vehicle[0].y - vehicle[23].y / vehicle[0].x - vehicle[23].x); vehicle[i].x += vehicle[i].newDistance * cos(vehicle[i].newDirection); vehicle[i].y += vehicle[i].newDistance * sin(vehicle[i].newDirection); shape[i]->Left = vehicle[i].x; shape[i]->Top = vehicle[i].y; } } //---------------------------------------------------------------------- step void step (void) { iterations++; Form1->EditIterations->Text = iterations; for (i = 0; i < 24; i++) { vehicle[i].x += vehicle[i].velocity * cos(vehicle[i].direction) * 10; vehicle[i].y += vehicle[i].velocity * sin(vehicle[i].direction) * 10; shape[i]->Left = vehicle[i].x; shape[i]->Top = vehicle[i].y; if (shape[i]->Left >= 400 || shape[i]->Left <= 0) { vehicle[i].direction = M_PI - vehicle[i].direction; } if (shape[i]->Top >= 400 || shape[i]->Top <= 0) { vehicle[i].direction = 2 * M_PI - vehicle[i].direction; } if (vehicle[i].direction > 2 * M_PI) { vehicle[i].direction = vehicle[i].direction - 2 * M_PI; } if (vehicle[i].direction < 0) { vehicle[i].direction = vehicle[i].direction + 2 * M_PI; } /* // This group of commands allows the shapes to wrap around... if (shape[i]->Left >= 400) shape[i]->Left = 0; else if (shape[i]->Left <= 0) shape[i]->Left = 400; if (shape[i]->Top >= 400) shape[i]->Top = 0; else if (shape[i]->Top <= 0) shape[i]->Top = 400; */ } } //=========================================================================== // EVENT HANDLERS //=========================================================================== //------------------------------------------------------------ On Form Create void __fastcall TForm1::FormCreate(TObject *Sender) { randomize(); //emptyAll(); // defines an array of shapes with properties and events for (int i = 0; i < 24; i++) { shape[i] = new TShape(this); shape[i]->Parent = Form1; shape[i]->Visible = true; shape[i]->OnMouseDown = ShapeMouseDown; shape[i]->OnMouseMove = ShapeMouseMove; shape[i]->Height = 50; shape[i]->Width = 50; shape[i]->Shape = stCircle; shape[i]->Tag = i; shape[i]->Pen->Width = 2; shape[i]->Pen->Color = static_cast(colorRamp(25, 24 - shape[i]->Tag)); shape[i]->Brush->Color = static_cast(colorRamp(25, shape[i]->Tag)); } shuffle(); } //------------------------------------------------------- On Shape 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::ShapeMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { TShape *shape = dynamic_cast(Sender); // Captures the index number of the shape that was clicked chosenVehicle = shape->Tag; // Remembers that an shape was chosen vehicleWasJustChosen = true; } //------------------------------------------------------- On Shape 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::ShapeMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { TShape *shape = dynamic_cast(Sender); // When the mouse moves over an shape // its index number is displayed EditVehicle->Text = shape->Tag; EditDirection->Text = vehicle[shape->Tag].direction; EditVelocity->Text = vehicle[shape->Tag].velocity; } //-------------------------------------------------------- On Form Mouse Down void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if (vehicleWasJustChosen) { // moves the shape to the position that was just clicked vehicle[chosenVehicle].x = X; vehicle[chosenVehicle].y = Y; shape[chosenVehicle]->Left = X; shape[chosenVehicle]->Top = Y; vehicleWasJustChosen = false; } } //---------------------------------------------------------------- run button void __fastcall TForm1::ButtonRunClick(TObject *Sender) { stop = false; while (stop == false) { step(); Application->ProcessMessages(); } } //--------------------------------------------------------------- step button void __fastcall TForm1::ButtonStepClick(TObject *Sender) { stop = true; step(); } //--------------------------------------------------------------- stop button void __fastcall TForm1::ButtonStopClick(TObject *Sender) { stop = true; } //--------------------------------------------------------------- reset button void __fastcall TForm1::ButtonResetClick(TObject *Sender) { reset(); } //------------------------------------------------------------- circle button void __fastcall TForm1::ButtonCircleClick(TObject *Sender) { circle(); } //---------------------------------------------------------- circulate button void __fastcall TForm1::ButtonCirculateClick(TObject *Sender) { //circulate(); // the code for this function is bad } //---------------------------------------------------------------------------