mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-03 18:38:56 +02:00
253 lines
6.9 KiB
ObjectPascal
253 lines
6.9 KiB
ObjectPascal
{ 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.
|