Procedure DrawM1; //pf8bit var NrBajtu:integer; // odpowiada x Linia:PByteArray; // iteration:integer; // Xi,Yi:integer; { wpolrzedne ekranu} {eObszar = zakres C} CxMin:extended; {C=Cx+Cy*i} CxMax:extended; CyMin:extended; CyMax:extended; // DeltaX,DeltaY:extended; // PDeltyX,PDeltyY:extended; // ZFixedX,ZFixedY:extended; Dx:extended; // i:byte; NewPalette: TMaxLogPalette; Label WithOutIteration; // rysowanie bez iteracji label NoPicture; // nie rysuje bo zły format koloru tj. pf < 8bit begin //1 bajt zawiera kolor 8 punktow 1 bitowych Bitmapa.PixelFormat:=pf8bit; // iterationMax:=300; // with obszar.eObszar do begin CxMin:=eLeft; {C=Cx+Cy*i} CxMax:=eRight; CyMin:=eBottom; CyMax:=eTop; end; {........... caption ..............} MainForm.Caption:=('Rysuję, czekaj'); {........ czas rysowania ...........} start:=GetTickCount; {....................................} // {..... obliczenia potrzebne do rysowania na bitmapie pamieciowej, nie widoczne .................} XiMin:=Obszar.iObszar.Left; XiMax:=Obszar.iObszar.Right; KrokCx:=(CxMax-CxMin)/(XiMax-XiMin); YiMin:=Obszar.iObszar.Bottom; YiMax:=Obszar.iObszar.Top; KrokCy:=(CyMax-CyMin)/(YiMax-YiMin); //optymalizacja kodu, zamiast Sqrt(Sqr(Zx))>bailOut sprawdzamy Sqr(Zx)>bailOut2)) BailOut2:=Sqr(BailOut); // // Define 256 shades of gray palette NewPalette.palVersion := $0300; // "Magic Number" for Windows LogPalette NewPalette.palNumEntries := 256; // FOR i := 0 TO 255 DO BEGIN NewPalette.palPalEntry[i].peRed := i; NewPalette.palPalEntry[i].peGreen := i; NewPalette.palPalEntry[i].peBlue := i; NewPalette.palPalEntry[i].peFlags := PC_NOCOLLAPSE; END; // Bitmapa.Palette := CreatePalette(pLogPalette(@NewPalette)^); For Yi:=0 to bitmapa.Height-1 do begin { odczytuje MainForm.Rysowac aby mozna bylo przerwac rysowanie} Application.ProcessMessages; if MainForm.Rysowac then begin Linia:=Bitmapa.ScanLine[Yi]; //X:= 0; for Xi := 0 to Bitmapa.Width-1 do begin Cy:=CyMin+(YiMax-Yi)*KrokCy; { Yi=YiMax-Yi tj.Xi odwrócenie osi Y } Cx:=CxMin+Xi*KrokCx; // Cy:=CyMin+(YiMax-Yi)*KrokCy; { Yi=YiMax-Yi tj.Xi odwrócenie osi Y } // Zx0:= 0+0*i; punkt poczatkowy ciągu Zx:=0; Zy:=0; // cardioid checkig - thx to Hugh Allen //sprawdzamy Czy punkt C jest w głównej kardioidzie //Cardioid in squere :[-0.75,0.4] x [ -0.65,0.65] if InRange(Cx,-0.75,0.4)and InRange(Cy,-0.65,065) then begin // M1= all C for which Fc(z) has attractive( = stable) fixed point // znajdyjemy punkt staly z: z=z*z+c // czyli rozwiazujemy rownanie kwadratowe // zmiennej zespolonej o wspolczynnikach zespolonych // Z*Z - Z + C = 0 //Delta:=1-4*a*c; Delta i C sa liczbami zespolonymi DeltaX:=1-4*Cx; DeltaY:=-4*Cy; // Pierwiastek zespolony z delty CplxSqrt(DeltaX,DeltaY,PDeltyX,PDeltyY); // obliczmy punkt staly jeden z dwóch, ten jest prawdopodobnie przyciągający ZFixedX:=1.0-PDeltyX; //0.5-0.5*PDeltyX; ZFixedY:=PDeltyY; //-0.5*PDeltyY; // jesli punkt stały jest przyciągający // to należy do M1 If (ZfixedX*ZFixedX + ZFixedY*ZFixedY)<1.0 then begin kolor:=clBlack; // nie trzeba iterowac GoTo WithOutIteration; end; // If (ZfixedX*ZFixedX // ominięcie iteracji M1 przyspiesza 3500 do 1500 msek end; // if InRange(Cx ... // czy punkt C nalezy do koła na lewo od kardioidy // circle: center = -1.0 and radius 1/4 dx:=Cx+1.0; if (Dx*Dx+Cy*Cy) < 0.0625 then begin Kolor:=clBlack; GoTo WithOutIteration; end; {iteracja punktu C ; Z(n+1)=F(Zn)=Zn*Zn + C} For iteration:=0 to iterationMax-1 do begin // Z(n+1):= Sqr(Zn) + C temp:=Sqr(Zx)-Sqr(Zy) +Cx; Zy:=2*Zx*Zy+Cy; Zx:=temp; //optymalizacja kodu, zamiast Sqrt(Sqr(Zx))>bailOut sprawdzamy Sqr(Zx)>bailOut2)) if ((Sqr(Zx)> bailOut2) and (Sqr(Zy)>bailOut2)) then break; end; {okresla kolor punktu dla } if SameValue(Iteration,IterationMax,0) then Kolor:=clBlack {zbior Mandelbrota} else Kolor:=clWhite;{ otoczenie zbioru} {Level set method } // WithOutIteration: ; // if kolor=ClBlack then Linia[Xi]:=0 else Linia[Xi]:=255; end; {for Xi:=0 to bitmapa.Width-1} end else break; {If MainForm.Rysowac} { przerywa petle po nacisnieciu dowolnego klawisza lub menu} end; {for Yi:=0 to bitmapa.Height-1} {...........czas rysowania .............} stop:=GetTickCount; CzasRysowania:=stop-start; {zmienna globalna z modulu MainForm} {........ wyswietla rysunek na oknie ........} //MainForm.Image1.Canvas.Draw(XiMin,YiMin,bitmapa); // zmieniono bo nie reagowal na zmiane wielkosci bitmapy w oknie dialogowym BitmapDlg MainForm.Image1.Picture.Graphic:=Bitmapa; NoPicture: ; end; //-----------------------------------