//=========================================================================== // LORENZ ATTRACTOR // Nicholas Gessler // July 2006 // http://www.zeuscat.com/andrew/chaos/lorenz.html // http://www.planetmath.org/ehcyclopeda/LorenzEquation.html // dx/dt = p * (y - x) // dy/dt = r * x - y - x * 2 // dz/dt = x * y - b * z //=========================================================================== #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- //=========================================================================== // VARIABLES //=========================================================================== double x = 3; double dx; double p = 10; // Prandt number double y = 15; double dy; double r = 28; // Rayleigh Number double z = 1; double dz; double b = 8 / 3; // Height to width ratio of box double dt = .0001; int i; int times = 500000; bool stop = false; //=========================================================================== // FUNCTIONS //=========================================================================== int colorRamp(int value, int maximum) { int pixelDistanceAlongPath = (value * 1792) / maximum; 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)); } void step (void) { i++; dx = (p * (y - x)); dy = ((r * x) - y - (x * z)); dz = ((x * y) - (b * z)); x = x + dx * dt; y = y + dy * dt; z = z + dz * dt; //Form1->PaintBoxXZ->Canvas-> // Pixels[x * 6 + 120][z * 6 - 00] // = static_cast(colorRamp(i, 500000)); //Form1->EditX->Text = x; Form1->PaintBoxYZ->Canvas-> Pixels[y * 11 + 250][z * 11 - 00] = static_cast(colorRamp(i, 500000)); //Form1->EditY->Text = y; //Form1->PaintBoxXY->Canvas-> // Pixels[x * 6 + 120][y * 6 + 150] // = static_cast(colorRamp(i, 500000)); //Form1->EditZ->Text = z; Form1->EditIterations->Text = i; Application->ProcessMessages(); } void run (void) { //for (int i = 0; i < times; i++) { // step(); //} while (!stop) { step(); if (i >= times) stop = true; } } //=========================================================================== // EVENT HANDLERS //=========================================================================== void __fastcall TForm1::ButtonRunClick(TObject *Sender) { stop = false; run(); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonStepClick(TObject *Sender) { step(); } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonResetClick(TObject *Sender) { Form1->Refresh(); i = 0; x = 3; y = 15; z = 1; Application->ProcessMessages(); } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBarDTChange(TObject *Sender) { switch (TrackBarDT->Position) { case 0: { dt = .02; //times = 500000; //500; break; } case 1: { dt = .01; //times = 500000; //1000; break; } case 2: { dt = .001; //times = 500000; //10000; break; } case 3: { dt = .0001; //times = 500000; //100000; break; } } Form1->EditDT->Text = dt; } //--------------------------------------------------------------------------- void __fastcall TForm1::ComboBoxRayleighChange(TObject *Sender) { switch (ComboBoxRayleigh->ItemIndex) { case 0: { r = 28; times = 500000; break; } case 1: { r = 15; times = 100000; break; } case 2: { r = 14; times = 100000; break; } case 3: { r = 13; times = 100000; break; } } } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonStopClick(TObject *Sender) { stop = true; } //---------------------------------------------------------------------------