mandel.pp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. { Mandelbrot 2 (C)opyright 1994 by Gernot Tenchio }
  2. { dieses Programm kann modifiziert, geloescht, verschenkt, kopiert, validiert, }
  3. { bewegt, komprimiert, ausgelacht usw. werden. Allerdings bittscheen immer mit }
  4. { meinem (G)obbirait }
  5. USES GRAPH;
  6. const shift:byte=12;
  7. VAR SerchPoint,ActualPoint,NextPoint : PointType ;
  8. LastColor : longint;
  9. Gd,Gm,Max_Color,Max_X_Width,
  10. Max_Y_Width,Y_Width : INTEGER ;
  11. Y1,Y2,X1,X2,Dy,Dx : Real ;
  12. Zm : Integer ;
  13. Flag : BOOLEAN ;
  14. LineY : ARRAY [0..600] OF BYTE;
  15. LineX : ARRAY [0..100,0..600] OF INTEGER;
  16. CONST
  17. SX : ARRAY [0..7] OF SHORTINT=(-1, 0, 1, 1, 1, 0,-1,-1);
  18. SY : ARRAY [0..7] OF SHORTINT=(-1,-1,-1, 0, 1, 1, 1, 0);
  19. TYPE
  20. ArrayType = array[1..50] of integer;
  21. {------------------------------------------------------------------------------}
  22. FUNCTION CalcMandel(Point:PointType; z:integer) : Longint ;
  23. var x,y,xq,yq,Cx,Cy : real ;
  24. BEGIN
  25. Cy:=y2 + dy*Point.y ;
  26. Cx:=x2 + dx*Point.x ;
  27. X:=-Cx ; Y:=-Cy ;
  28. REPEAT
  29. xq:=x * x;
  30. yq:=y * y ;
  31. y :=x * y;
  32. y :=y + y - cy;
  33. x :=xq - yq - cx ;
  34. z :=z -1;
  35. UNTIL (Z=0) OR (Xq + Yq > 4 );
  36. IF Z=0 Then CalcMandel:=1 else CalcMandel:=(z mod Max_Color) + 1 ;
  37. END ;
  38. {-----------------------------------------------------------------------------}
  39. PROCEDURE Partition(VAR A : ArrayType; First, Last : Byte);
  40. { ist nicht auf meinem Mist gewachsen. Weiss aber auch nicht mehr so richtig
  41. wo es herkommt. Allseits bekannter Sortieralgo }
  42. VAR
  43. Right,Left : BYTE ;
  44. V,Temp : integer;
  45. BEGIN
  46. V := A[(First + Last) SHR 1];
  47. Right := First;
  48. Left := Last;
  49. REPEAT
  50. WHILE (A[Right] < V) DO
  51. Right:=Right+1;
  52. WHILE (A[Left] > V) DO
  53. Left:=Left-1;
  54. IF (Right <= Left) THEN
  55. BEGIN
  56. Temp:=A[Left];
  57. A[Left]:=A[Right];
  58. A[Right]:=Temp;
  59. Right:=Right+1;
  60. Left:=Left-1;
  61. END;
  62. UNTIL Right > Left;
  63. IF (First < Left) THEN
  64. Partition(A, First, Left);
  65. IF (Right < Last) THEN
  66. Partition(A, Right, Last)
  67. END;
  68. FUNCTION BlackScan(var NextPoint:PointType) : BOOLEAN ;
  69. BEGIN
  70. BlackScan:=TRUE;
  71. REPEAT
  72. IF NextPoint.X=Max_X_Width THEN
  73. BEGIN
  74. IF NextPoint.Y < Y_Width THEN
  75. BEGIN
  76. NextPoint.X:=0 ;
  77. NextPoint.Y:=NextPoint.Y+1;
  78. END
  79. ELSE
  80. BEGIN
  81. BlackScan:=FALSE;
  82. EXIT;
  83. END ; { IF }
  84. END ; { IF }
  85. NextPoint.X:=NextPoint.X+1;
  86. UNTIL GetPixel(NextPoint.X,NextPoint.Y)=0;
  87. END ;
  88. {------------------------------------------------------------------------------}
  89. PROCEDURE Fill(Ymin,Ymax,LastColor:integer);
  90. VAR P1,P3,P4,P : INTEGER ;
  91. Len,P2 : BYTE ;
  92. Darray : ARRAYTYPE;
  93. BEGIN
  94. SetColor(LastColor);
  95. FOR P1:=Ymin+1 TO Ymax-1 DO
  96. BEGIN
  97. Len:=LineY[P1] ;
  98. IF Len >= 2 THEN
  99. BEGIN
  100. FOR P2:=1 TO Len DO
  101. BEGIN
  102. Darray[P2]:=LineX[P2,P1] ;
  103. END; { FOR }
  104. IF Len > 2 THEN Partition(Darray,1,len);
  105. P2:=1;
  106. REPEAT
  107. P3:= Darray[P2] ; P4:= Darray[P2 + 1];
  108. IF P3 <> P4 THEN
  109. BEGIN
  110. LINE ( P3 , P1 , P4 , P1) ;
  111. IF Flag THEN
  112. BEGIN
  113. P:=Max_Y_Width-P1;
  114. LINE ( P3 , P , P4 , P ) ;
  115. END;
  116. END; { IF }
  117. P2:=P2+2;
  118. UNTIL P2 >= Len ;
  119. END; { IF }
  120. END; { FOR }
  121. END;
  122. {-----------------------------------------------------------------------------}
  123. Function NewPosition(Last:Byte):Byte;
  124. begin
  125. newposition:=(((last+1) and 254)+6) and 7;
  126. END;
  127. {-----------------------------------------------------------------------------}
  128. PROCEDURE CalcBounds;
  129. VAR LastOperation,KK,
  130. Position : Byte ;
  131. foundcolor : longint;
  132. Start,Found,NotFound : BOOLEAN ;
  133. MerkY,Ymax : Integer ;
  134. LABEL L;
  135. BEGIN
  136. REPEAT
  137. FillChar(LineY,SizeOf(LineY),0) ;
  138. ActualPoint:=NextPoint;
  139. LastColor:=CalcMandel(NextPoint,Zm) ;
  140. PUTPIXEL (ActualPoint.X,ActualPoint.Y,LastColor);
  141. IF Flag THEN PUTPIXEL (ActualPoint.X,
  142. Max_Y_Width-ActualPoint.Y,LastColor) ;
  143. Ymax:=NextPoint.Y ;
  144. MerkY:=NextPoint.Y ;
  145. NotFound:=FALSE ;
  146. Start:=FALSE ;
  147. LastOperation:=4 ;
  148. REPEAT
  149. Found:=FALSE ;
  150. KK:=0 ;
  151. Position:=NewPosition(LastOperation);
  152. REPEAT
  153. LastOperation:=(Position+KK) AND 7 ;
  154. SerchPoint.X:=ActualPoint.X+Sx[LastOperation];
  155. SerchPoint.Y:=ActualPoint.Y+Sy[LastOperation];
  156. IF ( (SerchPoint.X < 0)
  157. OR (SerchPoint.X > Max_X_Width)
  158. OR (SerchPoint.Y < NextPoint.Y)
  159. OR (SerchPoint.Y > Y_Width) ) THEN GOTO L;
  160. IF (SerchPoint.X=NextPoint.X) AND (SerchPoint.Y=NextPoint.Y) THEN
  161. BEGIN
  162. Start:=TRUE ;
  163. Found:=TRUE ;
  164. END
  165. ELSE
  166. BEGIN
  167. FoundColor:=GetPixel(SerchPoint.X,SerchPoint.Y) ;
  168. IF FoundColor = 0 THEN
  169. BEGIN
  170. FoundColor:= CalcMandel (SerchPoint,Zm) ;
  171. Putpixel (SerchPoint.X,SerchPoint.Y,FoundColor) ;
  172. IF Flag THEN PutPixel (SerchPoint.X,Max_Y_Width-SerchPoint.Y,
  173. FoundColor) ;
  174. END ;
  175. IF FoundColor=LastColor THEN
  176. BEGIN
  177. IF ActualPoint.Y <> SerchPoint.Y THEN
  178. BEGIN
  179. IF SerchPoint.Y = MerkY THEN LineY[ActualPoint.Y]:=LineY[ActualPoint.Y]-1;
  180. MerkY:= ActualPoint.Y ;
  181. LineY[SerchPoint.Y]:=LineY[SerchPoint.Y]+1;
  182. END ;
  183. LineX[LineY[SerchPoint.Y],SerchPoint.Y]:=SerchPoint.X ;
  184. IF SerchPoint.Y > Ymax THEN Ymax:= SerchPoint.Y ;
  185. Found:=TRUE ;
  186. ActualPoint:=SerchPoint ;
  187. END;
  188. L:
  189. KK:=KK+1;
  190. IF KK > 8 THEN
  191. BEGIN
  192. Start:=TRUE ;
  193. NotFound:=TRUE ;
  194. END;
  195. END;
  196. UNTIL Found OR (KK > 8);
  197. UNTIL Start ;
  198. IF not NotFound THEN Fill(NextPoint.Y,Ymax,LastColor) ;
  199. UNTIL NOT BlackScan(NextPoint);
  200. END ;
  201. {------------------------------------------------------------------------------}
  202. {-----------------------}
  203. { MAINROUTINE }
  204. {-----------------------}
  205. BEGIN
  206. gm:=$103;
  207. gd:=$ff;
  208. {$IFDEF TURBO}
  209. gd:=detect;
  210. {$ENDIF}
  211. InitGraph(gd,gm,'D:\bp\bgi');
  212. IF GraphResult <> grOk THEN Halt(1);
  213. Max_X_Width:=GetMaxX;
  214. Max_y_Width:=GetMaxY;
  215. Max_Color:=GetMaxColor-1;
  216. ClearViewPort;
  217. x1:=-0.9;
  218. x2:= 2.2;
  219. y1:= 1.25;
  220. y2:=-1.25;
  221. zm:=90;
  222. dx:=(x1 - x2) / Max_X_Width ;
  223. dy:=(y1 - y2) / Max_Y_Width ;
  224. IF ABS(y1) = ABS(y2) THEN
  225. BEGIN
  226. flag:=TRUE ; Y_Width:=Max_Y_Width shr 1;
  227. END
  228. ELSE
  229. BEGIN
  230. flag:=FALSE ; Y_Width:=Max_Y_Width;
  231. END;
  232. NextPoint.X:=0; NextPoint.Y:=0;
  233. LastColor:=CalcMandel(SerchPoint,zm);
  234. CalcBounds ;
  235. readln;
  236. CloseGraph;
  237. END.