mandel.pp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  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. {$ifdef go32v2}
  19. dpmiexcp,
  20. {$endif go32v2}
  21. Graph;
  22. {$ifdef go32v2}
  23. {$ifndef ver0_99_8}
  24. {$define has_colors_equal}
  25. {$endif ver0_99_8}
  26. {$endif go32v2}
  27. const
  28. shift:byte=12;
  29. var
  30. SearchPoint,ActualPoint,NextPoint : PointType;
  31. LastColor : longint;
  32. Gd,Gm,
  33. Max_Color,Max_X_Width,
  34. Max_Y_Width,Y_Width : integer;
  35. Y1,Y2,X1,X2,Dy,Dx : Real;
  36. Zm : Integer;
  37. Flag : boolean;
  38. LineY : array [0..600] OF BYTE;
  39. LineX : array [0..100,0..600] OF INTEGER;
  40. const
  41. SX : array [0..7] OF SHORTINT=(-1, 0, 1, 1, 1, 0,-1,-1);
  42. SY : array [0..7] OF SHORTINT=(-1,-1,-1, 0, 1, 1, 1, 0);
  43. type
  44. arrayType = array[1..50] of integer;
  45. {------------------------------------------------------------------------------}
  46. {$ifndef has_colors_equal}
  47. function ColorsEqual(c1, c2 : longint) : boolean;
  48. begin
  49. ColorsEqual:=((GetMaxColor=$FF) and ((c1 and $FF)=(c2 and $FF))) or
  50. ((GetMaxColor=$7FFF) and ((c1 and $F8F8F8)=(c2 and $F8F8F8))) or
  51. ((GetMaxColor=$FFFF) and ((c1 and $F8FCF8)=(c2 and $F8FCF8))) or
  52. ((GetMaxColor>$10000) and ((c1 and $FFFFFF)=(c2 and $FFFFFF)));
  53. end;
  54. {$endif not has_colors_equal}
  55. {------------------------------------------------------------------------------}
  56. function CalcMandel(Point:PointType; z:integer) : Longint ;
  57. var
  58. x,y,xq,yq,Cx,Cy : real ;
  59. begin
  60. Cy:=y2 + dy*Point.y ;
  61. Cx:=x2 + dx*Point.x ;
  62. X:=-Cx ; Y:=-Cy ;
  63. repeat
  64. xq:=x * x;
  65. yq:=y * y ;
  66. y :=x * y;
  67. y :=y + y - cy;
  68. x :=xq - yq - cx ;
  69. z :=z -1;
  70. until (Z=0) or (Xq + Yq > 4 );
  71. if Z=0 Then
  72. CalcMandel:=(blue and $FFFFFF)
  73. else
  74. {$ifdef go32v2}
  75. if getMaxColor>255 then
  76. CalcMandel:=(stdcolors[(z mod 254) + 1] and $FFFFFF)
  77. else
  78. {$endif}
  79. CalcMandel:=(z mod Max_Color) + 1 ;
  80. end;
  81. {-----------------------------------------------------------------------------}
  82. procedure Partition(var A : arrayType; First, Last : Byte);
  83. var
  84. Right,Left : byte ;
  85. V,Temp : integer;
  86. begin
  87. V := A[(First + Last) SHR 1];
  88. Right := First;
  89. Left := Last;
  90. repeat
  91. while (A[Right] < V) do
  92. inc(Right);
  93. while (A[Left] > V) do
  94. Dec(Left);
  95. if (Right <= Left) then
  96. begin
  97. Temp:=A[Left];
  98. A[Left]:=A[Right];
  99. A[Right]:=Temp;
  100. Right:=Right+1;
  101. Left:=Left-1;
  102. end;
  103. until Right > Left;
  104. if (First < Left) then
  105. Partition(A, First, Left);
  106. if (Right < Last) then
  107. Partition(A, Right, Last)
  108. end;
  109. {-----------------------------------------------------------------------------}
  110. function BlackScan(var NextPoint:PointType) : boolean;
  111. begin
  112. BlackScan:=true;
  113. repeat
  114. if NextPoint.X=Max_X_Width then
  115. begin
  116. if NextPoint.Y < Y_Width then
  117. begin
  118. NextPoint.X:=0 ;
  119. NextPoint.Y:=NextPoint.Y+1;
  120. end
  121. else
  122. begin
  123. BlackScan:=false;
  124. exit;
  125. end ; { IF }
  126. end ; { IF }
  127. NextPoint.X:=NextPoint.X+1;
  128. until GetPixel(NextPoint.X,NextPoint.Y)=0;
  129. end ;
  130. {------------------------------------------------------------------------------}
  131. procedure Fill(Ymin,Ymax,LastColor:integer);
  132. var
  133. P1,P3,P4,P : integer ;
  134. Len,P2 : byte ;
  135. Darray : arraytype;
  136. begin
  137. SetColor(LastColor);
  138. for P1:=Ymin+1 to Ymax-1 do
  139. begin
  140. Len:=LineY[P1] ;
  141. if Len >= 2 then
  142. begin
  143. for P2:=1 to Len do
  144. Darray[P2]:=LineX[P2,P1] ;
  145. if Len > 2 then
  146. Partition(Darray,1,len);
  147. P2:=1;
  148. repeat
  149. P3:= Darray[P2] ; P4:= Darray[P2 + 1];
  150. if P3 <> P4 then
  151. begin
  152. line ( P3 , P1 , P4 , P1) ;
  153. if Flag then
  154. begin
  155. P:=Max_Y_Width-P1;
  156. line ( P3 , P , P4 , P ) ;
  157. end;
  158. end; { IF }
  159. P2:=P2+2;
  160. until P2 >= Len ;
  161. end; { IF }
  162. end; { FOR }
  163. end;
  164. {-----------------------------------------------------------------------------}
  165. Function NewPosition(Last:Byte):Byte;
  166. begin
  167. newposition:=(((last+1) and 254)+6) and 7;
  168. end;
  169. {-----------------------------------------------------------------------------}
  170. procedure CalcBounds;
  171. var
  172. lastOperation,KK,
  173. Position : Byte ;
  174. foundcolor : longint;
  175. Start,Found,NotFound : boolean ;
  176. MerkY,Ymax : Integer ;
  177. label
  178. L;
  179. begin
  180. repeat
  181. FillChar(LineY,SizeOf(LineY),0) ;
  182. ActualPoint:=NextPoint;
  183. LastColor:=CalcMandel(NextPoint,Zm) ;
  184. putpixel (ActualPoint.X,ActualPoint.Y,LastColor);
  185. if Flag then
  186. putpixel (ActualPoint.X,Max_Y_Width-ActualPoint.Y,LastColor) ;
  187. Ymax:=NextPoint.Y ;
  188. MerkY:=NextPoint.Y ;
  189. NotFound:=false ;
  190. Start:=false ;
  191. LastOperation:=4 ;
  192. repeat
  193. Found:=false ;
  194. KK:=0 ;
  195. Position:=NewPosition(LastOperation);
  196. repeat
  197. LastOperation:=(Position+KK) and 7 ;
  198. SearchPoint.X:=ActualPoint.X+Sx[LastOperation];
  199. SearchPoint.Y:=ActualPoint.Y+Sy[LastOperation];
  200. if ((SearchPoint.X < 0) or
  201. (SearchPoint.X > Max_X_Width) or
  202. (SearchPoint.Y < NextPoint.Y) or
  203. (SearchPoint.Y > Y_Width)) then
  204. goto L;
  205. if (SearchPoint.X=NextPoint.X) and (SearchPoint.Y=NextPoint.Y) then
  206. begin
  207. Start:=true ;
  208. Found:=true ;
  209. end
  210. else
  211. begin
  212. FoundColor:=GetPixel(SearchPoint.X,SearchPoint.Y) ;
  213. if FoundColor = 0 then
  214. begin
  215. FoundColor:= CalcMandel (SearchPoint,Zm) ;
  216. Putpixel (SearchPoint.X,SearchPoint.Y,FoundColor) ;
  217. if Flag then
  218. PutPixel (SearchPoint.X,Max_Y_Width-SearchPoint.Y,FoundColor) ;
  219. end ;
  220. if ColorsEqual(FoundColor,LastColor) then
  221. begin
  222. if ActualPoint.Y <> SearchPoint.Y then
  223. begin
  224. if SearchPoint.Y = MerkY then
  225. LineY[ActualPoint.Y]:=LineY[ActualPoint.Y]-1;
  226. MerkY:= ActualPoint.Y ;
  227. LineY[SearchPoint.Y]:=LineY[SearchPoint.Y]+1;
  228. end ;
  229. LineX[LineY[SearchPoint.Y],SearchPoint.Y]:=SearchPoint.X ;
  230. if SearchPoint.Y > Ymax then Ymax:= SearchPoint.Y ;
  231. Found:=true ;
  232. ActualPoint:=SearchPoint ;
  233. end;
  234. L:
  235. KK:=KK+1;
  236. if KK > 8 then
  237. begin
  238. Start:=true ;
  239. NotFound:=true ;
  240. end;
  241. end;
  242. until Found or (KK > 8);
  243. until Start ;
  244. if not NotFound then
  245. Fill(NextPoint.Y,Ymax,LastColor) ;
  246. until not BlackScan(NextPoint);
  247. end ;
  248. {------------------------------------------------------------------------------
  249. MAINROUTINE
  250. ------------------------------------------------------------------------------}
  251. {$ifndef Linux}
  252. var
  253. error : word;
  254. {$endif not Linux}
  255. begin
  256. {$ifdef go32v2}
  257. {$ifdef debug}
  258. {$warning If the compilation fails, you need to recompile}
  259. {$warning the graph unit with -dDEBUG option }
  260. Write('Use linear ? ');
  261. readln(st);
  262. if st='y' then UseLinear:=true;
  263. {$endif debug}
  264. {$endif go32v2}
  265. {$ifdef Linux}
  266. gm:=0;
  267. gd:=0;
  268. {$else}
  269. if paramcount>0 then
  270. begin
  271. val(paramstr(1),gm,error);
  272. if error<>0 then
  273. gm:=$103;
  274. end
  275. else
  276. gm:=$103;
  277. gd:=$ff;
  278. {$ifDEF TURBO}
  279. gd:=detect;
  280. {$endif}
  281. {$endif}
  282. InitGraph(gd,gm,'');
  283. if GraphResult <> grOk then Halt(1);
  284. Max_X_Width:=GetMaxX;
  285. Max_y_Width:=GetMaxY;
  286. Max_Color:=GetMaxColor-1;
  287. ClearViewPort;
  288. x1:=-0.9;
  289. x2:= 2.2;
  290. y1:= 1.25;
  291. y2:=-1.25;
  292. zm:=90;
  293. dx:=(x1 - x2) / Max_X_Width ;
  294. dy:=(y1 - y2) / Max_Y_Width ;
  295. if abs(y1) = abs(y2) then
  296. begin
  297. {$ifndef NOFLAG}
  298. flag:=true;
  299. {$endif NOFLAG}
  300. Y_Width:=Max_Y_Width shr 1
  301. end
  302. else
  303. begin
  304. flag:=false;
  305. Y_Width:=Max_Y_Width;
  306. end;
  307. NextPoint.X:=0;
  308. NextPoint.Y:=0;
  309. LastColor:=CalcMandel(SearchPoint,zm);
  310. CalcBounds ;
  311. {$ifndef fpc_profile}
  312. readln;
  313. {$endif fpc_profile}
  314. CloseGraph;
  315. end.
  316. {
  317. $Log$
  318. Revision 1.5 1999-05-27 21:36:33 peter
  319. * new demo's
  320. * fixed mandel for linux
  321. Revision 1.4 1998/12/20 22:22:10 peter
  322. * updates
  323. }