program FraktalMaldenborta;
uses crt,graph,dos;


type zespolona = record { tak samo, jak w deklaracji zmiennej }
	Re : real;
	Im : real;
end;

var 
	c,wyn:zespolona;
	i,x,y:integer;
	promien:real;
	karta,tryb:integer;
	times:integer;
	Hour_1, Minute_1, Second_1, Sec100_1:word;
	Hour_2, Minute_2, Second_2, Sec100_2:word;
	optymalizacja:shortint;

{wstaw pixel}
procedure Kolor(x,y,i:integer);
begin
	{mocno zoptymalizowane wybieranie koloru}
	putPixel(x,y,i);
end;

{obliczanie n(ile)tego wyrazu ciagu Maldenbrota dla zadanego C}
function Ciag(c:zespolona;ile:integer):zespolona;
var 
	i:integer;
	x,y,tmp:real;
begin

	x:=0;
	y:=0;
	
	for i:=1 to ile do
	begin
	
		tmp:=x;
		x := c.Re + x*x - y*y;
		y := c.Im + tmp*y + y*tmp; {do obliczenia y jest potrzebna zamapmietana wart x}
		
	end;
	
	Ciag.Re:=x;
	Ciag.Im:=y;
end;

begin

	{powitanie}
	writeln('Program: Fraktal Maldenborta');
	writeln('===========================');
	writeln('code:	Dawid Urbański');
	writeln('url:		www.dawidurbanski.pl');
	writeln('===========================');
	writeln('>');
	{wybor optylamizacji}
	write('optymalizacja [1-slabo,2-mocno,inny - brak]: ');
	readln(optymalizacja);

	{ustawienie okna do rysowania}
	karta:=detect;
	initgraph(karta,tryb,'');
	clrscr;

	{inicjacja}
	wyn.Re	:=0;
	wyn.Im	:=0;
	
	c.Re	:= 0;
	c.Im	:= 0;
	
	

	{rysowanie 100 rzutów}
	for times:=1 to 100 do
	begin
	
		{zapamietaj czas przed}
		GetTime(Hour_1, Minute_1, Second_1, Sec100_1);
	
		{zarysowywanie 'calego' ekranu}
		for x:=0	to 1600 do
		for y:=0	to 800 do
		begin

			{optymalizacja}
			case optymalizacja of
				1:
				begin
					//konserwatywnie
					if x mod 2 =0 then continue;
					if y mod 2 =0 then continue;
				end;
				
				2:
				begin
					//mocno
					if x mod 4 <>0 then continue;
					if y mod 4 <>0 then continue;
				end;
			end;
			{-------------}
			
			{podaje wartosc dla liczby 'c'}
			c.Re:=x;
			c.Im:=y;
			
			{kalibracja}
			c.Re:=c.Re/639-2;
			c.Im:=c.Im/479-1;
	
			c.Re := c.Re / (times/10);
			c.Im := c.Im / (times/10);
			{======================}
			i:=-1;		
			repeat
				
				i:=i+1;
				wyn:=Ciag(c,i);
				
				promien:=wyn.Re*wyn.Re + wyn.Im*wyn.Im;
			
			until (i>=30) OR (promien>4);
			{======================}
			
			{======================}
			Kolor(x,y,i);
			{======================}
			
		end;

		{wypisanie w konsoli ile czasu zabralo narysowanie}
		//tak wiem ze to zly sposob obliczania
		GetTime(Hour_2, Minute_2, Second_2, Sec100_2);
		writeln('narysowano w: ',Minute_2*60-Minute_1*60+Second_2-Second_1,'.',Sec100_2-Sec100_1 mod 100);
		{poczekaj sekunde przed rysowaniem nowego}
		delay(1000); 
	end;
	
	{koniec}
	closeGraph;

end.
