123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- { Mandelbrot 2 (C)opyright 1994 by Gernot Tenchio }
- { dieses Programm kann modifiziert, geloescht, verschenkt, kopiert, validiert, }
- { bewegt, komprimiert, ausgelacht usw. werden. Allerdings bittscheen immer mit }
- { meinem (G)obbirait }
- USES GRAPH;
- const shift:byte=12;
- VAR SerchPoint,ActualPoint,NextPoint : PointType ;
- LastColor : longint;
- Gd,Gm,Max_Color,Max_X_Width,
- Max_Y_Width,Y_Width : INTEGER ;
- Y1,Y2,X1,X2,Dy,Dx : Real ;
- Zm : Integer ;
- Flag : BOOLEAN ;
- LineY : ARRAY [0..600] OF BYTE;
- LineX : ARRAY [0..100,0..600] OF INTEGER;
- CONST
- SX : ARRAY [0..7] OF SHORTINT=(-1, 0, 1, 1, 1, 0,-1,-1);
- SY : ARRAY [0..7] OF SHORTINT=(-1,-1,-1, 0, 1, 1, 1, 0);
- TYPE
- ArrayType = array[1..50] of integer;
- {------------------------------------------------------------------------------}
- FUNCTION CalcMandel(Point:PointType; z:integer) : Longint ;
- var x,y,xq,yq,Cx,Cy : real ;
- BEGIN
- Cy:=y2 + dy*Point.y ;
- Cx:=x2 + dx*Point.x ;
- X:=-Cx ; Y:=-Cy ;
- REPEAT
- xq:=x * x;
- yq:=y * y ;
- y :=x * y;
- y :=y + y - cy;
- x :=xq - yq - cx ;
- z :=z -1;
- UNTIL (Z=0) OR (Xq + Yq > 4 );
- IF Z=0 Then CalcMandel:=1 else CalcMandel:=(z mod Max_Color) + 1 ;
- END ;
- {-----------------------------------------------------------------------------}
- PROCEDURE Partition(VAR A : ArrayType; First, Last : Byte);
- { ist nicht auf meinem Mist gewachsen. Weiss aber auch nicht mehr so richtig
- wo es herkommt. Allseits bekannter Sortieralgo }
- VAR
- Right,Left : BYTE ;
- V,Temp : integer;
- BEGIN
- V := A[(First + Last) SHR 1];
- Right := First;
- Left := Last;
- REPEAT
- WHILE (A[Right] < V) DO
- Right:=Right+1;
- WHILE (A[Left] > V) DO
- Left:=Left-1;
- IF (Right <= Left) THEN
- BEGIN
- Temp:=A[Left];
- A[Left]:=A[Right];
- A[Right]:=Temp;
- Right:=Right+1;
- Left:=Left-1;
- END;
- UNTIL Right > Left;
- IF (First < Left) THEN
- Partition(A, First, Left);
- IF (Right < Last) THEN
- Partition(A, Right, Last)
- END;
- FUNCTION BlackScan(var NextPoint:PointType) : BOOLEAN ;
- BEGIN
- BlackScan:=TRUE;
- REPEAT
- IF NextPoint.X=Max_X_Width THEN
- BEGIN
- IF NextPoint.Y < Y_Width THEN
- BEGIN
- NextPoint.X:=0 ;
- NextPoint.Y:=NextPoint.Y+1;
- END
- ELSE
- BEGIN
- BlackScan:=FALSE;
- EXIT;
- END ; { IF }
- END ; { IF }
- NextPoint.X:=NextPoint.X+1;
- UNTIL GetPixel(NextPoint.X,NextPoint.Y)=0;
- END ;
- {------------------------------------------------------------------------------}
- PROCEDURE Fill(Ymin,Ymax,LastColor:integer);
- VAR P1,P3,P4,P : INTEGER ;
- Len,P2 : BYTE ;
- Darray : ARRAYTYPE;
- BEGIN
- SetColor(LastColor);
- FOR P1:=Ymin+1 TO Ymax-1 DO
- BEGIN
- Len:=LineY[P1] ;
- IF Len >= 2 THEN
- BEGIN
- FOR P2:=1 TO Len DO
- BEGIN
- Darray[P2]:=LineX[P2,P1] ;
- END; { FOR }
- IF Len > 2 THEN Partition(Darray,1,len);
- P2:=1;
- REPEAT
- P3:= Darray[P2] ; P4:= Darray[P2 + 1];
- IF P3 <> P4 THEN
- BEGIN
- LINE ( P3 , P1 , P4 , P1) ;
- IF Flag THEN
- BEGIN
- P:=Max_Y_Width-P1;
- LINE ( P3 , P , P4 , P ) ;
- END;
- END; { IF }
- P2:=P2+2;
- UNTIL P2 >= Len ;
- END; { IF }
- END; { FOR }
- END;
- {-----------------------------------------------------------------------------}
- Function NewPosition(Last:Byte):Byte;
- begin
- newposition:=(((last+1) and 254)+6) and 7;
- END;
- {-----------------------------------------------------------------------------}
- PROCEDURE CalcBounds;
- VAR LastOperation,KK,
- Position : Byte ;
- foundcolor : longint;
- Start,Found,NotFound : BOOLEAN ;
- MerkY,Ymax : Integer ;
- LABEL L;
- BEGIN
- REPEAT
- FillChar(LineY,SizeOf(LineY),0) ;
- ActualPoint:=NextPoint;
- LastColor:=CalcMandel(NextPoint,Zm) ;
- PUTPIXEL (ActualPoint.X,ActualPoint.Y,LastColor);
- IF Flag THEN PUTPIXEL (ActualPoint.X,
- Max_Y_Width-ActualPoint.Y,LastColor) ;
- Ymax:=NextPoint.Y ;
- MerkY:=NextPoint.Y ;
- NotFound:=FALSE ;
- Start:=FALSE ;
- LastOperation:=4 ;
- REPEAT
- Found:=FALSE ;
- KK:=0 ;
- Position:=NewPosition(LastOperation);
- REPEAT
- LastOperation:=(Position+KK) AND 7 ;
- SerchPoint.X:=ActualPoint.X+Sx[LastOperation];
- SerchPoint.Y:=ActualPoint.Y+Sy[LastOperation];
- IF ( (SerchPoint.X < 0)
- OR (SerchPoint.X > Max_X_Width)
- OR (SerchPoint.Y < NextPoint.Y)
- OR (SerchPoint.Y > Y_Width) ) THEN GOTO L;
- IF (SerchPoint.X=NextPoint.X) AND (SerchPoint.Y=NextPoint.Y) THEN
- BEGIN
- Start:=TRUE ;
- Found:=TRUE ;
- END
- ELSE
- BEGIN
- FoundColor:=GetPixel(SerchPoint.X,SerchPoint.Y) ;
- IF FoundColor = 0 THEN
- BEGIN
- FoundColor:= CalcMandel (SerchPoint,Zm) ;
- Putpixel (SerchPoint.X,SerchPoint.Y,FoundColor) ;
- IF Flag THEN PutPixel (SerchPoint.X,Max_Y_Width-SerchPoint.Y,
- FoundColor) ;
- END ;
- IF FoundColor=LastColor THEN
- BEGIN
- IF ActualPoint.Y <> SerchPoint.Y THEN
- BEGIN
- IF SerchPoint.Y = MerkY THEN LineY[ActualPoint.Y]:=LineY[ActualPoint.Y]-1;
- MerkY:= ActualPoint.Y ;
- LineY[SerchPoint.Y]:=LineY[SerchPoint.Y]+1;
- END ;
- LineX[LineY[SerchPoint.Y],SerchPoint.Y]:=SerchPoint.X ;
- IF SerchPoint.Y > Ymax THEN Ymax:= SerchPoint.Y ;
- Found:=TRUE ;
- ActualPoint:=SerchPoint ;
- END;
- L:
- KK:=KK+1;
- IF KK > 8 THEN
- BEGIN
- Start:=TRUE ;
- NotFound:=TRUE ;
- END;
- END;
- UNTIL Found OR (KK > 8);
- UNTIL Start ;
- IF not NotFound THEN Fill(NextPoint.Y,Ymax,LastColor) ;
- UNTIL NOT BlackScan(NextPoint);
- END ;
- {------------------------------------------------------------------------------}
- {-----------------------}
- { MAINROUTINE }
- {-----------------------}
- BEGIN
- gm:=$103;
- gd:=$ff;
- {$IFDEF TURBO}
- gd:=detect;
- {$ENDIF}
- InitGraph(gd,gm,'D:\bp\bgi');
- IF GraphResult <> grOk THEN Halt(1);
- Max_X_Width:=GetMaxX;
- Max_y_Width:=GetMaxY;
- Max_Color:=GetMaxColor-1;
- ClearViewPort;
- x1:=-0.9;
- x2:= 2.2;
- y1:= 1.25;
- y2:=-1.25;
- zm:=90;
- dx:=(x1 - x2) / Max_X_Width ;
- dy:=(y1 - y2) / Max_Y_Width ;
- IF ABS(y1) = ABS(y2) THEN
- BEGIN
- flag:=TRUE ; Y_Width:=Max_Y_Width shr 1;
- END
- ELSE
- BEGIN
- flag:=FALSE ; Y_Width:=Max_Y_Width;
- END;
- NextPoint.X:=0; NextPoint.Y:=0;
- LastColor:=CalcMandel(SerchPoint,zm);
- CalcBounds ;
- readln;
- CloseGraph;
- END.
|