/**************************************************************************/
/* feigenbaum1.c                                               01.11.87   */
/* Version 1.1                                                            */
/*                                                                        */
/*                                                                        */
/* Demonstration eines Feigenbaums                                        */
/* mit Eingabemoeglichkeit der Pararmeter aus dem CLI.                    */
/*                                                                        */
/* fuer Markt+Technik geschrieben von Heiko Knappe                        */
/*                                                                        */
/* Komplexe Dynamische Systeme                                            */
/* Feigenbaeume - ein Wachstumsproblem                                    */
/**************************************************************************/


#include <exec/types.h>
#include <intuition/intuition.h>

#define WIDTH  640     /* Screen Modus */
#define HEIGHT 500
#define DEPTH  2
#define FLAGS  HIRES+LACE

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Screen *MyScreen;
struct RastPort *rp;
struct NewScreen MyNewScreen=
 {0,0,WIDTH,HEIGHT,DEPTH,1,0,FLAGS,CUSTOMSCREEN,0,0,0,0};

int n0=50,n1=100;          /* Offsets fuer die Iteration       */
float p0=.1,p;             /* Start-Population                 */
float kmin=1.9,kmax=3;     /* Relative Wachstums-Rate min/max  */
float st;
float k;                   /* Relative Wachstums-Rate          */
int f,n;                   /* Anzahl der Iterationen           */
BOOL flag=TRUE;            /* dieses Flag wird verwendet um    */
                           /* noch waehrend der Berechnung das */
                           /* Programm beenden zu koennen.     */
                          

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

main(argc,argv)
int argc;
char *argv[];
{
 if((argc!=2)&&(argc!=1))
 {
    printf("Eingabe: %s <n0,n1,kmin,kmax>\n",argv[0]);
    printf(" n0: Anzahl der zu unterdrueckenden Werte\n");
    printf(" n1: Anzahl der auszugebenden Werte\n");
    printf(" [kmin,kmax]: zu untersuchender Bereich\n");
    printf(" p0: Anfangspopulation\n");
    close_things();
 }
 if(argc==2)
    if(sscanf(argv[1],"%d,%d,%f,%f,%f",&n0,&n1,&kmin,&kmax,&p0)!=5)
    {
       printf("falsche Eingabe\n");
       close_things();
    }
 printf("Parameter:\n n0=%d n1=%d\n",n0,n1);
 printf(" kmin=%f kmax=%f p0=%f\n",kmin,kmax,p0);
 st=(kmax-kmin)/WIDTH;
 k=kmin;
 open_things();
 feigenbaum();
 while(MyScreen->TopEdge<100);
 close_things();
}


/***********************/
/* 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();
 rp=&(MyScreen->RastPort);
 init_colors();
 Move(rp,10,10);
 Text(rp,"Komplexe Dynamische Systeme",27);
 Move(rp,10,21);
 Text(rp,"p=p*(1+k*(1-p))",15);
} 


close_things()
{
 if(IntuitionBase!=0) CloseLibrary(IntuitionBase);
 if(GfxBase!=0) CloseLibrary(GfxBase);
 if(MyScreen!=0) CloseScreen(MyScreen);
 exit();
} 


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


/***********************/
/* Berechnung          */
/***********************/

feigenbaum()
{
 int x,y;

 for(k=kmin;k<kmax;k+=st)
 {
    x=(k-kmin)/st;
    p=p0;
    if(MyScreen->TopEdge>100)
       return(0);
    for(n=1;n<(n0+n1);++n)
    {
       p=p*(1+k*(1-p));
       if(n>n0)
       { 
          y=HEIGHT*(1-p/2);
          if(y<HEIGHT&&y>0) WritePixel(rp,x,y);
       }
    }
 }
}
