//=========================================================================== // CHAOS GAME TWEAKED // Nick Gessler // 24 January 2012 //=========================================================================== #include #pragma hdrstop #include "Unit1.h" #include "math.h" //#include //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //=========================================================================== // VARIABLES //=========================================================================== int numberOfCities; int cityX[100]; int cityY[100]; int target; int cmpX, cmpY; int world[500][500]; int iterations; int colorMultiplier = 1; double campX = 250; double campY = 250; double maxWorld = 1; double ratio; double from = 0.50; double to = 0.50; double step = 0.001; AnsiString palette = "Blue to Red"; //=========================================================================== // FUNCTIONS //=========================================================================== //-------------------------------------------------------------- Draw Borders void drawBorders (void) { Form1->PaintBox1->Canvas->MoveTo(0, 0); Form1->PaintBox1->Canvas->LineTo(0, 499); Form1->PaintBox1->Canvas->LineTo(499, 499); Form1->PaintBox1->Canvas->LineTo(499, 0); Form1->PaintBox1->Canvas->LineTo(0, 0); } //--------------------------------------------------- Color Ramp Version 2012 TColor colorRamp(int part, int whole) { if (whole == 0) whole++; // prevent divide by zero part = part % whole; // keep part <= whole int pixelDistanceAlongEdges = (part * 1792) / whole; int red, green, blue; // Which edge of the palette 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)); } //---------------------------------------------------- Gray Ramp Version 2012 TColor grayRamp(int part, int whole) { if (whole == 0) whole = 1; // prevent divide by zero part = part % whole; // keep part less than whole int distance = ( part * 255 ) / whole; return static_cast(RGB(distance, distance, distance)); } //--------------------------------------------------------------------- Color void color (AnsiString palette) { for (int i = 0; i < 500; i++) { for (int j = 0; j < 500; j++) { if (palette == "Blue to Red") { Form1->PaintBox1->Canvas->Pixels[i][j] = colorRamp(world[i][j] * colorMultiplier, maxWorld); } if (palette == "Red to Blue") { Form1->PaintBox1->Canvas->Pixels[i][j] = colorRamp((maxWorld - world[i][j]) * colorMultiplier, maxWorld); } if (palette == "Black to White") { Form1->PaintBox1->Canvas->Pixels[i][j] = grayRamp(world[i][j] * colorMultiplier, maxWorld); } if (palette == "White to Black") { Form1->PaintBox1->Canvas->Pixels[i][j] = grayRamp((maxWorld - world[i][j]) * colorMultiplier, maxWorld); } // Faux Shadows if (palette == "Faux Shadows") { if (i == 0 || j == 0) continue; if (world[i-1][j-1] > world[i][j]) { Form1->PaintBox1->Canvas->Pixels[i][j] = clBlack; } else Form1->PaintBox1->Canvas->Pixels[i][j] = clWhite; } // Log values if (palette == "Log Blue to Red") { if (world[i][j] == 0) Form1->PaintBox1->Canvas->Pixels[i][j] = clBlack; else {Form1->PaintBox1->Canvas->Pixels[i][j] = colorRamp(100 * log(world[i][j]), 100 * log(maxWorld)); } } if (palette == "Log Red to Blue") { if (world[i][j] == maxWorld) Form1->PaintBox1->Canvas-> Pixels[i][j] = clBlack; else {Form1->PaintBox1->Canvas->Pixels[i][j] = colorRamp(100 * log(maxWorld - world[i][j]), 100 * log(maxWorld)); } } if (palette == "Log Black to White") { if (world[i][j] == 0) Form1->PaintBox1->Canvas->Pixels[i][j] = clBlack; else {Form1->PaintBox1->Canvas->Pixels[i][j] = grayRamp(100 * log(world[i][j]), 100 * log(maxWorld)); } } if (palette == "Log White to Black") { if (world[i][j] == maxWorld) Form1->PaintBox1->Canvas-> Pixels[i][j] = clBlack; else {Form1->PaintBox1->Canvas->Pixels[i][j] = grayRamp(100 * log(maxWorld - world[i][j]), 100 * log(maxWorld)); } } // Neighbor Shadows if (palette == "Gray Neighbor Shadows") { if (i == 0 || j == 0 || i == 499 || j == 499) continue; float sum = 0; for (int m = -1; m <= 1; m++) { for (int n = -1; n <= 1; n++) { if (m == i && n == j) continue; sum += world[m][n]; } } float ave = sum / 7; if (world[i][j] == 0) { Form1->PaintBox1->Canvas->Pixels[i][j] = clBlack; } else { Form1->PaintBox1->Canvas->Pixels[i][j] = grayRamp(((ave - world[i][j]) / world[i][j]), colorMultiplier); } } if (palette == "Color Neighbor Shadows") { if (i == 0 || j == 0 || i == 499 || j == 499) continue; float sum = 0; for (int m = -1; m <= 1; m++) { for (int n = -1; n <= 1; n++) { if (m == i && n == j) continue; sum += world[m][n]; } } float ave = sum / 7; if (world[i][j] == 0) { Form1->PaintBox1->Canvas->Pixels[i][j] = clBlack; } else { Form1->PaintBox1->Canvas->Pixels[i][j] = colorRamp(((ave - world[i][j]) / world[i][j]), colorMultiplier); } } } } drawBorders(); } //----------------------------------------------------------------------- Run void run (void) { for (ratio = from; ratio <= to; ratio += step) { for (int i = 0; i < 100000; i++) { iterations++; if (iterations < 10000) continue; target = random(numberOfCities); campX += (cityX[target] - campX) * ratio; cmpX = Int(campX); campY += (cityY[target] - campY) * ratio; cmpY = Int(campY); if (campX < 500 && campY < 500 && campX >= 0 && campY >= 0) { world[cmpX][cmpY]++; if (world[cmpX][cmpY] > maxWorld) { maxWorld = world[cmpX][cmpY]; } } } if (to != from) { Form1->ProgressBar1->Position = 100 * ((ratio - from) / (to - from)); } } Form1->EditMaxHits->Text = FloatToStrF(maxWorld, ffNumber, 10, 0); Form1->EditIterations->Text = FloatToStrF(iterations, ffNumber, 10, 0); Beep(1000, 50); color(palette); Form1->ProgressBar1->Position = 0; } //--------------------------------------------------------------------- Reset void reset (void) { Form1->PaintBox1->Refresh(); campX = 250; campY = 250; maxWorld = 1; iterations = 0; Form1->EditIterations->Text = iterations; Form1->EditMaxHits->Text = 0; Form1->ProgressBar1->Position = 0; numberOfCities = 0; for (int i = 0; i < 500; i++) { for (int j = 0; j < 500; j++) { world[i][j] = 0; } } drawBorders(); } //=========================================================================== // EVENT HANDLERS //=========================================================================== //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { cityX[numberOfCities] = X; cityY[numberOfCities] = Y; numberOfCities ++; Form1->PaintBox1->Canvas->Pixels[X][Y] = clBlack; } //--------------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { drawBorders(); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonRunClick(TObject *Sender) { run(); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonResetClick(TObject *Sender) { reset(); } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBarColorMultiplierChange(TObject *Sender) { colorMultiplier = TrackBarColorMultiplier->Position; EditColorScale->Text = TrackBarColorMultiplier->Position; Timer1->Enabled = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBarFromChange(TObject *Sender) { from = TrackBarFrom->Position / 100.0; EditFrom->Text = FloatToStrF(from, ffNumber, 1, 2); } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBarToChange(TObject *Sender) { to = TrackBarTo->Position / 100.0; EditTo->Text = FloatToStrF(to, ffNumber, 1, 2); } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBarStepChange(TObject *Sender) { step = TrackBarStep->Position / 1000.0; EditStep->Text = FloatToStrF(step, ffNumber, 1, 3); } //--------------------------------------------------------------------------- void __fastcall TForm1::RadioGroupColorClick(TObject *Sender) { if (RadioGroupColor->ItemIndex == 0) { palette = "Blue to Red"; } if (RadioGroupColor->ItemIndex == 1) { palette = "Red to Blue"; } if (RadioGroupColor->ItemIndex == 2) { palette = "Black to White"; } if (RadioGroupColor->ItemIndex == 3) { palette = "White to Black"; } if (RadioGroupColor->ItemIndex == 4) { palette = "Faux Shadows"; } if (RadioGroupColor->ItemIndex == 5) { palette = "Log Blue to Red"; } if (RadioGroupColor->ItemIndex == 6) { palette = "Log Red to Blue"; } if (RadioGroupColor->ItemIndex == 7) { palette = "Log Black to White"; } if (RadioGroupColor->ItemIndex == 8) { palette = "Log White to Black"; } if (RadioGroupColor->ItemIndex == 9) { palette = "Gray Neighbor Shadows"; } if (RadioGroupColor->ItemIndex == 10) { palette = "Color Neighbor Shadows"; } color(palette); } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { color(palette); Timer1->Enabled = false; } //--------------------------------------------------------------------------- void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { Form1->EditProbe->Text = FloatToStrF(world[X][Y], ffNumber, 10, 0); } //----------------------------------------------------------------------- End