mandel.pp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993-98 by Gernot Tenchio
  5. Mandelbrot Example using the Graph unit
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. program mandel;
  13. {
  14. Mandelbrot example using the graph unit.
  15. Note: For linux you need to run this program as root !!
  16. }
  17. uses
  18. Graph;
  19. const
  20. shift:byte=12;
  21. var
  22. SerchPoint,ActualPoint,NextPoint : PointType;
  23. LastColor : longint;
  24. Gd,Gm,
  25. Max_Color,Max_X_Width,
  26. Max_Y_Width,Y_Width : integer;
  27. Y1,Y2,X1,X2,Dy,Dx : Real;
  28. Zm : Integer;
  29. Flag : boolean;
  30. LineY : array [0..600] OF BYTE;
  31. LineX : array [0..100,0..600] OF INTEGER;
  32. const
  33. SX : array [0..7] OF SHORTINT=(-1, 0, 1, 1, 1, 0,-1,-1);
  34. SY : array [0..7] OF SHORTINT=(-1,-1,-1, 0, 1, 1, 1, 0);
  35. type
  36. arrayType = array[1..50] of integer;
  37. {------------------------------------------------------------------------------}
  38. function CalcMandel(Point:PointType; z:integer) : Longint ;
  39. var
  40. x,y,xq,yq,Cx,Cy : real ;
  41. begin
  42. Cy:=y2 + dy*Point.y ;
  43. Cx:=x2 + dx*Point.x ;
  44. X:=-Cx ; Y:=-Cy ;
  45. repeat
  46. xq:=x * x;
  47. yq:=y * y ;
  48. y :=x * y;
  49. y :=y + y - cy;
  50. x :=xq - yq - cx ;
  51. z :=z -1;
  52. until (Z=0) or (Xq + Yq > 4 );
  53. if Z=0 Then
  54. CalcMandel:=1
  55. else
  56. CalcMandel:=(z mod Max_Color) + 1 ;
  57. end;
  58. {-----------------------------------------------------------------------------}
  59. procedure Partition(var A : arrayType; First, Last : Byte);
  60. var
  61. Right,Left : byte ;
  62. V,Temp : integer;
  63. begin
  64. V := A[(First + Last) SHR 1];
  65. Right := First;
  66. Left := Last;
  67. repeat
  68. while (A[Right] < V) do
  69. inc(Right);
  70. while (A[Left] > V) do
  71. Dec(Left);
  72. if (Right <= Left) then
  73. begin
  74. Temp:=A[Left];
  75. A[Left]:=A[Right];
  76. A[Right]:=Temp;
  77. Right:=Right+1;
  78. Left:=Left-1;
  79. end;
  80. until Right > Left;
  81. if (First < Left) then
  82. Partition(A, First, Left);
  83. if (Right < Last) then
  84. Partition(A, Right, Last)
  85. end;
  86. {-----------------------------------------------------------------------------}
  87. function BlackScan(var NextPoint:PointType) : boolean;
  88. begin
  89. BlackScan:=true;
  90. repeat
  91. if NextPoint.X=Max_X_Width then
  92. begin
  93. if NextPoint.Y < Y_Width then
  94. begin
  95. NextPoint.X:=0 ;
  96. NextPoint.Y:=NextPoint.Y+1;
  97. end
  98. else
  99. begin
  100. BlackScan:=false;
  101. exit;
  102. end ; { IF }
  103. end ; { IF }
  104. NextPoint.X:=NextPoint.X+1;
  105. until GetPixel(NextPoint.X,NextPoint.Y)=0;
  106. end ;
  107. {------------------------------------------------------------------------------}
  108. procedure Fill(Ymin,Ymax,LastColor:integer);
  109. var
  110. P1,P3,P4,P : integer ;
  111. Len,P2 : byte ;
  112. Darray : arraytype;
  113. begin
  114. SetColor(LastColor);
  115. for P1:=Ymin+1 to Ymax-1 do
  116. begin
  117. Len:=LineY[P1] ;
  118. if Len >= 2 then
  119. begin
  120. for P2:=1 to Len do
  121. Darray[P2]:=LineX[P2,P1] ;
  122. if Len > 2 then
  123. Partition(Darray,1,len);
  124. P2:=1;
  125. repeat
  126. P3:= Darray[P2] ; P4:= Darray[P2 + 1];
  127. if P3 <> P4 then
  128. begin
  129. line ( P3 , P1 , P4 , P1) ;
  130. if Flag then
  131. begin
  132. P:=Max_Y_Width-P1;
  133. line ( P3 , P , P4 , P ) ;
  134. end;
  135. end; { IF }
  136. P2:=P2+2;
  137. until P2 >= Len ;
  138. end; { IF }
  139. end; { FOR }
  140. end;
  141. {-----------------------------------------------------------------------------}
  142. Function NewPosition(Last:Byte):Byte;
  143. begin
  144. newposition:=(((last+1) and 254)+6) and 7;
  145. end;
  146. {-----------------------------------------------------------------------------}
  147. procedure CalcBounds;
  148. var
  149. lastOperation,KK,
  150. Position : Byte ;
  151. foundcolor : longint;
  152. Start,Found,NotFound : boolean ;
  153. MerkY,Ymax : Integer ;
  154. label
  155. L;
  156. begin
  157. repeat
  158. FillChar(LineY,SizeOf(LineY),0) ;
  159. ActualPoint:=NextPoint;
  160. LastColor:=CalcMandel(NextPoint,Zm) ;
  161. putpixel (ActualPoint.X,ActualPoint.Y,LastColor);
  162. if Flag then
  163. putpixel (ActualPoint.X,Max_Y_Width-ActualPoint.Y,LastColor) ;
  164. Ymax:=NextPoint.Y ;
  165. MerkY:=NextPoint.Y ;
  166. NotFound:=false ;
  167. Start:=false ;
  168. LastOperation:=4 ;
  169. repeat
  170. Found:=false ;
  171. KK:=0 ;
  172. Position:=NewPosition(LastOperation);
  173. repeat
  174. LastOperation:=(Position+KK) and 7 ;
  175. SerchPoint.X:=ActualPoint.X+Sx[LastOperation];
  176. SerchPoint.Y:=ActualPoint.Y+Sy[LastOperation];
  177. if ((SerchPoint.X < 0) or
  178. (SerchPoint.X > Max_X_Width) or
  179. (SerchPoint.Y < NextPoint.Y) or
  180. (SerchPoint.Y > Y_Width)) then
  181. goto L;
  182. if (SerchPoint.X=NextPoint.X) and (SerchPoint.Y=NextPoint.Y) then
  183. begin
  184. Start:=true ;
  185. Found:=true ;
  186. end
  187. else
  188. begin
  189. FoundColor:=GetPixel(SerchPoint.X,SerchPoint.Y) ;
  190. if FoundColor = 0 then
  191. begin
  192. FoundColor:= CalcMandel (SerchPoint,Zm) ;
  193. Putpixel (SerchPoint.X,SerchPoint.Y,FoundColor) ;
  194. if Flag then
  195. PutPixel (SerchPoint.X,Max_Y_Width-SerchPoint.Y,FoundColor) ;
  196. end ;
  197. if FoundColor=LastColor then
  198. begin
  199. if ActualPoint.Y <> SerchPoint.Y then
  200. begin
  201. if SerchPoint.Y = MerkY then
  202. LineY[ActualPoint.Y]:=LineY[ActualPoint.Y]-1;
  203. MerkY:= ActualPoint.Y ;
  204. LineY[SerchPoint.Y]:=LineY[SerchPoint.Y]+1;
  205. end ;
  206. LineX[LineY[SerchPoint.Y],SerchPoint.Y]:=SerchPoint.X ;
  207. if SerchPoint.Y > Ymax then Ymax:= SerchPoint.Y ;
  208. Found:=true ;
  209. ActualPoint:=SerchPoint ;
  210. end;
  211. L:
  212. KK:=KK+1;
  213. if KK > 8 then
  214. begin
  215. Start:=true ;
  216. NotFound:=true ;
  217. end;
  218. end;
  219. until Found or (KK > 8);
  220. until Start ;
  221. if not NotFound then
  222. Fill(NextPoint.Y,Ymax,LastColor) ;
  223. until not BlackScan(NextPoint);
  224. end ;
  225. {------------------------------------------------------------------------------
  226. MAINROUTINE
  227. ------------------------------------------------------------------------------}
  228. begin
  229. {$ifdef Linux}
  230. gm:=0;
  231. gd:=0;
  232. {$else}
  233. gm:=$103;
  234. gd:=$ff;
  235. {$ifDEF TURBO}
  236. gd:=detect;
  237. {$endif}
  238. {$endif}
  239. InitGraph(gd,gm,'D:\bp\bgi');
  240. if GraphResult <> grOk then Halt(1);
  241. Max_X_Width:=GetMaxX;
  242. Max_y_Width:=GetMaxY;
  243. Max_Color:=GetMaxColor-1;
  244. ClearViewPort;
  245. x1:=-0.9;
  246. x2:= 2.2;
  247. y1:= 1.25;
  248. y2:=-1.25;
  249. zm:=90;
  250. dx:=(x1 - x2) / Max_X_Width ;
  251. dy:=(y1 - y2) / Max_Y_Width ;
  252. if abs(y1) = abs(y2) then
  253. begin
  254. flag:=true;
  255. Y_Width:=Max_Y_Width shr 1
  256. end
  257. else
  258. begin
  259. flag:=false;
  260. Y_Width:=Max_Y_Width;
  261. end;
  262. NextPoint.X:=0;
  263. NextPoint.Y:=0;
  264. LastColor:=CalcMandel(SerchPoint,zm);
  265. CalcBounds ;
  266. readln;
  267. CloseGraph;
  268. end.
  269. {
  270. $Log$
  271. Revision 1.3 1998-09-11 10:55:25 peter
  272. + header+log
  273. }