Nadesłany przez Tomasz Lubiński, 19 stycznia 2009 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
Fraktale Netwona - C++/Newton.cpp:
// Fraktale Newtona // www.algorytm.org // Tomasz Lubinski (c) 2009 //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Newton.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } #define MIN(a,b) ((a<b)?a:b) #define MAX(a,b) ((a>b)?a:b) //--------------------------------------------------------------------------- //Describes places to render double ratioX, ratioY; double minX, minY, maxX, maxY; int downX, downY; int cSet; //colors TColor colors[101]; //--------------------------------------------------------------------------- //for HSV colors void HSV2RGB(float hue, float sat, float val, float &red, float &grn, float &blu) { int i; float f, p, q, t; if(val==0) {red=0; grn=0; blu=0;} else{ hue/=60; i = (int)(hue); f = hue-i; p = val*(1-sat); q = val*(1-(sat*f)); t = val*(1-(sat*(1-f))); if (i==0) {red=val; grn=t; blu=p;} else if (i==1) {red=q; grn=val; blu=p;} else if (i==2) {red=p; grn=val; blu=t;} else if (i==3) {red=p; grn=q; blu=val;} else if (i==4) {red=t; grn=p; blu=val;} else if (i==5) {red=val; grn=p; blu=q;} } } //initialize array with colors used to color different levels void initializeColors() { int level; float r, g, b; for (level=0; level<100; level++) { HSV2RGB(level*2.5, 0.85, 0.8, r, g, b); colors[level] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } colors[100] = (TColor)0; } //type for complex numbers typedef struct complex_type { double real; double imaginary; } complex_t; //calculate squared modus of given complex c double complexModSq(complex_t c) { return c.real*c.real + c.imaginary*c.imaginary; } //complex addition complex_t add(complex_t a, complex_t b) { complex_t result; result.real = a.real + b.real; result.imaginary = a.imaginary + b.imaginary; return result; } //complex substraction complex_t sub(complex_t a, complex_t b) { complex_t result; result.real = a.real - b.real; result.imaginary = a.imaginary - b.imaginary; return result; } //complex multiplication complex_t mul(complex_t a, complex_t b) { complex_t result; result.real = a.real*b.real - a.imaginary*b.imaginary; result.imaginary = a.real*b.imaginary + a.imaginary*b.real; return result; } //complex divide complex_t div(complex_t a, complex_t b) { complex_t result; double x = b.real*b.real + b.imaginary*b.imaginary; result.real = (a.real*b.real + a.imaginary*b.imaginary) / x; result.imaginary = (a.imaginary*b.real - a.real*b.imaginary) / x; return result; } //func = a[0] + a[1]*z^1 + a[2]*z^2 + ... a[n]*z^2 complex_t func(complex_t z, complex_t *a, int n) { int i; complex_t result; result.real = 0; result.imaginary = 0; for (i=n; i>=0; i--) { result = add(a[i], mul(result, z)); } return result; } complex_t results[10]; int resultsCnt; int findResult(complex_t a) { int i; for (i=0; i<resultsCnt; i++) { if (complexModSq(sub(a, results[i])) < 0.1) { return i; } } results[resultsCnt] = a; resultsCnt++; return resultsCnt; } //value is inside set in the returned level int levelSet(complex_t a, complex_t p, complex_t *w, complex_t *d, int n) { complex_t z, z_prev; int iteration; iteration = 0; z = p; do { z_prev = z; z = sub(z, mul(a, div(func(z, w, n), func(z, d, n-1)))); iteration++; } while (complexModSq(sub(z_prev,z)) > 0.0001 && iteration < 100); if (cSet == true) { if (iteration < 100) { return 10*findResult(z); } } return iteration; } //generate fractal void __fastcall TForm1::Button1Click(TObject *Sender) { int i, j, level; complex_t p, w[6], d[5], a; minX = StrToFloat(minx->Text); minY = StrToFloat(miny->Text); maxX = StrToFloat(maxx->Text); maxY = StrToFloat(maxy->Text); for (i=0; i<6; i++) { w[i].real = StrToFloat(aArray->Cells[1][i+1]); w[i].imaginary = StrToFloat(aArray->Cells[2][i+1]); } for (i=1; i<6; i++) { d[i-1].real = (double)i*StrToFloat(aArray->Cells[1][i+1]); d[i-1].imaginary = (double)i*StrToFloat(aArray->Cells[2][i+1]); } a.real = StrToFloat(aRe->Text); a.imaginary = StrToFloat(aIm->Text); ratioX = (maxX - minX) / Fractal->Width; ratioY = (maxY - minY) / Fractal->Height; resultsCnt = 0; cSet = colorSet->Checked; for (i=0; i<Fractal->Height; i++) { p.imaginary = i*ratioY + minY; for (j=0; j<Fractal->Width; j++) { p.real = j*ratioX + minX; level = levelSet(a, p, w, d, 5); Fractal->Canvas->Pixels[j][i] = colors[level]; } } Fractal->Refresh(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { minx->Text = FloatToStr(-1.5); maxx->Text = FloatToStr(1.5); miny->Text = FloatToStr(-1.5); maxy->Text = FloatToStr(1.5); aRe->Text = FloatToStr(1.0); aIm->Text = FloatToStr(0.0); aArray->Cells[1][0] = "p(Re)^n"; aArray->Cells[2][0] = "p(Im)^n"; aArray->Cells[0][0] = "n"; aArray->Cells[0][1] = "0"; aArray->Cells[0][2] = "1"; aArray->Cells[0][3] = "2"; aArray->Cells[0][4] = "3"; aArray->Cells[0][5] = "4"; aArray->Cells[0][6] = "5"; aArray->Cells[1][1] = FloatToStr(-1.0); aArray->Cells[1][2] = FloatToStr(0.0); aArray->Cells[1][3] = FloatToStr(0.0); aArray->Cells[1][4] = FloatToStr(1.0); aArray->Cells[1][5] = FloatToStr(0.0); aArray->Cells[1][6] = FloatToStr(0.0); aArray->Cells[2][1] = FloatToStr(0.0); aArray->Cells[2][2] = FloatToStr(0.0); aArray->Cells[2][3] = FloatToStr(0.0); aArray->Cells[2][4] = FloatToStr(0.0); aArray->Cells[2][5] = FloatToStr(0.0); aArray->Cells[2][6] = FloatToStr(0.0); minX = StrToFloat(minx->Text); minY = StrToFloat(miny->Text); maxX = StrToFloat(maxx->Text); maxY = StrToFloat(maxy->Text); ratioX = (maxX - minX) / Fractal->Width; ratioY = (maxY - minY) / Fractal->Height; //initialize array with colors initializeColors(); //render new fractal Button1Click(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::FractalMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { downX = X; downY = Y; Selection->Width = 0; Selection->Height = 0; Selection->Visible = true; } //--------------------------------------------------------------------------- void __fastcall TForm1::FractalMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { //remove selection Selection->Visible = false; //get new range to render minx->Text = FloatToStr(MIN(downX, X)*ratioX + minX); maxx->Text = FloatToStr(MAX(downX, X)*ratioX + minX); miny->Text = FloatToStr(MIN(downY, Y)*ratioY + minY); maxy->Text = FloatToStr(MAX(downY, Y)*ratioY + minY); minX = StrToFloat(minx->Text); minY = StrToFloat(miny->Text); maxX = StrToFloat(maxx->Text); maxY = StrToFloat(maxy->Text); //render new fractal Button1Click(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::FractalMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { //if left mouse button is held then draw selection if (Shift.Contains(ssLeft)) { Selection->Width = abs(downX - X); Selection->Height = abs(downY - Y); Selection->Left = Fractal->Left + MIN(downX, X); Selection->Top = Fractal->Top + MIN(downY, Y); } } //---------------------------------------------------------------------------