/**************************************************************************/
/* film3D.c                                                    28.12.87   */
/* Version 1.0                                                            */
/*                                                                        */
/*                                                                        */
/*                                                                        */
/* fuer Markt+Technik gesc/**************************************************************************/
/* film3D.c                                                    28.12.87   */
/* Version 1.0                                                            */
/*                                                                        */
/*                                                                        */
/*                                                                        */
/* fuer Markt+Technik gesc/**************************************************************************/
/* film3D.c                                                    28.12.87   */
/* Version 1.0                                                            */
/*                                                                        */
/*                                                                        */
/*                                                                        */
/* fuer Markt+Technik gesc        */
int   anz,bild;              /* Anzahl der Bilder                   */
float emin=.001,emax=100000; /* Abbruchkriterium                    */
float rmin=-1.5,rmax=2.5;    /* Grenzen des Bildes                  */
float imin=-1.2,imax=1.2;
float r1min,r1max,i1min,i1max,r2min,r2max,i2min,i2max;
float rst,ist,r1st,i1st,r2st,i2st;
float re,im,re1,re2,im1,im2,cre,cim;
                             /* re,im laufender Re- und Im-Teil     */
                             /* re1,re2,im1,im2  -> Folgenglieder   */
float d;                     /* Abstand zu dem Bezugspunkt          */
int   i,j,k;
short land[N][N];            /* Feld mit den Punktwerten            */
short x[4],y[4];             /* 4 Eckpunkte der Flaechen            */
short stx,sty;
UWORD buffer[5*10];          /* Variablen fuer AreaFill             */
long  *speicher;
char  file_name[20]="pic",num[10];


/***********************/
/* Hauptprogramm       */
/***********************/

main(argc,argv)
int argc;
char *argv[];
{
 if(argc!=2)
 {
    printf("Eingabe: %s <nmax,anz,r1min,r1max,i1min,i1max,",argv[0]);
    printf("r2min,r2max,i2min,i2max>\n");
    printf(" nmax: maximale Anzahl der Duerchlaeufe\n");
    printf(" anz:  Anzahl der Bilder\n");
    printf(" [r1min,r1max][i1min,i1max]: Wertebereich des 1. Bildes\n");
    printf(" [r2min,r2max][i2min,i2max]: Wertebereich des letzten Bildes\n");
    close_things();
 }
 if(sscanf(argv[1],"%d,%d,%f,%f,%f,%f,%f,%f,%f,%f",&nmax,&anz,
    &r1min,&r1max,&i1min,&i1max,&r2min,&r2max,&i2min,&i2max)!=10)
 {
    printf("falsche Eingabe\n");
    close_things();
 }
 printf("\nParameter:\n emin=%f emax=%f\n",emin,emax);
 printf(" nmax=%d\n",nmax);
 printf(" erstes Bild:  [%f,%f] [%f,%f]\n",r1min,r1max,i1min,i1max);
 printf(" letztes Bild: [%f,%f] [%f,%f]\n",r2min,r2max,i2min,i2max);
 printf(" %d Bilder werden berechnet.\n",anz);
 emin*=emin;  /* mit dem Quadrat zu vergleichen erspart Wurzeln zu */
 emax*=emax;  /* berechnen -> Schnelligkeit                        */
 if(anz<=1) anz=2;
 open_things();
 r1st=(r2max-r1max)/(anz-1),i1st=(i2max-i1max)/(anz-1);
 r2st=(r2min-r1min)/(anz-1),i2st=(i2min-i1min)/(anz-1);
 rmin=r1min,rmax=r1max,imin=i1min,imax=i1max;
 for(bild=0;bild<anz;++bild,rmin+=r2st,rmax+=r1st,imin+=i2st,imax+=i1st)
 {
    itoa(bild,num);
    strcpy(file_name+3,num);
    printf("Berechnung Bild: %d -> %s\n      [%f,%f][%f,%f]\n",
           bild,file_name,rmin,rmax,imin,imax);
    apfel();
    ausgabe();
    if(save(file_name,1,MyScreen)!=TRUE) break; /* Fehler? */
 }
 close_things();
}

/* Hilfsfunktion (int nach ASCII) */
itoa(wert,buff)
int wert;
char buff[];
{
 int i,j,sign;
 char c;

 if((sign=wert)<0)
    wert=-wert;
 i=0;
 do
 {
    buff[i++]=wert%10+'0';
 }
 while((wert/=10)>0);
 if(sign<0)
    buff[i++]='-';
 buff[i]=0;
 for(i=0,j=strlen(buff)-1;i<j;i++,j--)
 {
    c=buff[i];
    buff[i]=buff[j];
    buff[j]=c;
 }
}


/***********************/
/* Initialisierung     */
/***********************/

open_things()
{
 if((IntuitionBase=OpenLibrary("intuition.library",0))==0)
    close_things();
 if((GfxBase=OpenLibrary("graphics.library",0))==0)
    close_things();
 if((MyScreen=OpenScreen(&MyNewScreen))==0)
    close_things();
 MyRastPort=&(MyScreen->RastPort);
 init_colors();
 init_fill();
} 

init_fill()
{
 if((speicher=AllocRaster(WIDTH,HEIGHT))==0)
    close_things();
 MyRastPort->AreaInfo=&MyAreaInfo;
 MyRastPort->TmpRas=InitTmpRas(&MyTmpRas,speicher,RASSIZE(WIDTH,HEIGHT));
 InitArea(&MyAreaInfo,&buffer[0],10);
}

close_things()
{
 if(speicher!=0) FreeRaster(speicher,WIDTH,HEIGHT);
 if(IntuitionBase!=0) CloseLibrary(IntuitionBase);
 if(GfxBase!=0) CloseLibrary(GfxBase);
 if(MyScreen!=0) CloseScreen(MyScreen);
 exit(0);
} 

init_colors()
{
 SetRGB4(&(MyScreen->ViewPort),0,0,0,0);
 SetRGB4(&(MyScreen->ViewPort),1,15,15,15);
}


/***********************/
/* Berechnung der      */
/* Stuetzpunkte        */
/***********************/

apfel()
{
 rst=(rmax-rmin)/N;
 ist=(imax-imin)/N;
 for(i=0;i<N;++i) /* in x-Richtung */
 {
    re=rmin+i*rst;
    for(j=0;j<N;++j) /* in y-Richtung */
    {
       im=imin+j*ist;
       for(n=re1=im1=0,cre=re,cim=im;n<nmax;++n)
       {
          im2=2*re1*im1-cim,re2=re1*re1-im1*im1-cre;
          im1=im2,re1=re2;
          d=im1*im1+re1*re1;
          /* Ist der Attraktor erreicht?                       */
          if(d<emin)  break;
          /* Attraktor Unendlich?                              */
          if(d>emax)  break;
       }
       land[i][j]=n;
    }
 }
}


/***********************/
/* Ausgabe             */
/***********************/

ausgabe()
{
 SetRast(MyRastPort,0); /* Bild loeschen */
 stx=FWIDTH/N,sty=FHEIGHT/N;
 for(i=0;i<N-1;++i)
 {
     for(j=0;j<N-1;++j)
     {
        /* Berechnung der Eckpunkte der Flaechen */
        x[0]=FXOFF+stx*i-sty*j,y[0]=FYOFF-land[i][j]+sty*j;
        x[1]=FXOFF+stx*(i+1)-sty*j,y[1]=FYOFF-land[i+1][j]+sty*j;
        x[2]=FXOFF+stx*(i+1)-sty*(j+1),y[2]=FYOFF-land[i+1][j+1]+sty*(j+1);
        x[3]=FXOFF+stx*i-sty*(j+1),y[3]=FYOFF-land[i][j+1]+sty*(j+1);
        for(k=0;k<4;++k)
           if(y[k]<0) y[k]=0;
        zeich();
     }
 }
}

zeich()
{
 SetAPen(MyRastPort,0);  /* Flaeche / Umgrenzung zeichnen */
 SetOPen(MyRastPort,1);
 AreaMove(MyRastPort,x[0],y[0]); AreaDraw(MyRastPort,x[1],y[1]);
 AreaDraw(MyRastPort,x[2],y[2]); AreaDraw(MyRastPort,x[3],y[3]);
 AreaEnd(MyRastPort);
}
