home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 352.lha / DistanceEstimatorMethod / DEM.c < prev    next >
C/C++ Source or Header  |  1990-03-04  |  8KB  |  347 lines

  1. #include <exec/types.h>
  2. #include <graphics/gfxbase.h>
  3. #include <intuition/intuition.h>
  4. #include <math.h>
  5. #include <libraries/iff.h>
  6. #include <ctype.h>
  7. #include <stdio.h>
  8.  
  9. #define BITS2SHIFT 27
  10.  
  11. double atof();
  12. long atol();
  13. int height=256;
  14. void *OpenLibrary(),*GetBMHD(),*OpenIFF(),*AllocRaster();
  15. struct Window *OpenWindow();
  16. struct Screen *OpenScreen();
  17. struct IntuiMessage *GetMsg();
  18. struct IntuitionBase *IntuitionBase;
  19. struct GfxBase *GfxBase;
  20. struct Library *IFFBase=NULL;
  21.  
  22. struct Window *w;
  23. struct Screen *s;
  24. struct IntuiMessage *msg;
  25. struct BitMap *SBitMap=NULL;
  26.  
  27. struct NewScreen ns = {0,0,640,512,1,0,0,HIRES|LACE,CUSTOMSCREEN,NULL,NULL,NULL,NULL};
  28.  
  29. struct NewWindow nw = {
  30.     0,1,640,511,-1,-1,VANILLAKEY|CLOSEWINDOW,WINDOWCLOSE|NOCAREREFRESH|SIMPLE_REFRESH|
  31.     ACTIVATE,NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN};
  32.  
  33. short ColorMap[32] = {     /* format 0x0RGB */
  34.  /*  0-7  */  0x0000,0x0FFF,0x0EEE,0x0DDD,0x0CCC,0x0BBB,0x0AAA,0x0999 ,
  35.  /*  8-15 */  0x0888,0x0777,0x0666,0x0555,0x0444,0x0333,0x0222,0x0111 ,
  36.  /* 16-23 */  0x066F,0x0FFF,0x0EEE,0x0DDD,0x0CCC,0x0BBB,0x0AAA,0x0999 ,
  37.  /* 24-31 */  0x0888,0x0777,0x0666,0x0555,0x0444,0x0333,0x0222,0x0111 };
  38.  
  39. OpenAll()
  40. {
  41.     if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0L)))
  42.         abort("No Intuition");
  43.     if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L)))
  44.         abort("No GFXBase");
  45.     ns.Height=height=GfxBase->NormalDisplayRows;
  46.     nw.Height=height-1;
  47.     
  48.     if (!(IFFBase = (struct Library *) OpenLibrary(IFFNAME,IFFVERSION)))
  49.         abort("Somebody's using IFF-library - or it is absent");
  50.     if ((s=(struct Screen *)OpenScreen(&ns))==NULL)
  51.         abort("No screen here");
  52.  
  53.     LoadRGB4(&s->ViewPort,&ColorMap[0],(long)1<<s->BitMap.Depth);
  54.     nw.Screen=s;
  55.     if ((w = (struct Window *) OpenWindow(&nw)) == NULL)
  56.         abort("Can't (and won't) open window");
  57. }
  58.  
  59. abort(exitcode)
  60. char *exitcode;
  61. {
  62.     if (exitcode) puts(exitcode);
  63.     if (w) CloseWindow(w);
  64.     if (s) CloseScreen(s);
  65.     if (IFFBase) CloseLibrary(IFFBase);
  66.     if (GfxBase) CloseLibrary(GfxBase);
  67.         OpenWorkBench();
  68.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  69.     exit(0);
  70. }
  71.  
  72. max(x,y)
  73. double x,y;
  74. {
  75.     if (x>y) return(x); else return(y);
  76. }
  77.  
  78. long LoadPicture(filename)
  79. char *filename;
  80. {
  81.     APTR ifffile = NULL;
  82.     struct BitMapHeader *bmhd;
  83.     long count,bd,bw,bh;
  84.     register long x,y,inity;
  85.     UWORD colortable[128];
  86.     char *iffinfile=":Pics/WBBackPic.ILBM";
  87.     
  88.     if(!(ifffile=OpenIFF(filename))) {
  89.         return(0L);
  90.     }
  91.     if(!(bmhd=GetBMHD(ifffile)))
  92.     {
  93.         abort("Bad BitMap Header on IFF file");
  94.     }
  95.     count = GetColorTab(ifffile,colortable);
  96. /*     LoadRGB4(&(s->ViewPort),colortable,count); */
  97.  
  98.     if(!(DecodePic(ifffile,&s->BitMap)))
  99.     {
  100.         abort("Decoding IFF - bad things happened!");
  101.     }
  102.     CloseIFF(ifffile);
  103.     printf("Analyzing picture for resume...");
  104.     fflush(stdout);
  105.     for (y=0,x=0;(y<w->Height)&&(x<w->Height);y++)
  106.         for (x=0;(x<w->Width)&&(ReadPixel(w->RPort,x,y)==0);x++);
  107.     if (y>1) y-=2;
  108.     else y=0;
  109.     printf(" resuming at line %ld.\n",y);
  110.     DisplayBeep(0L);
  111.     return(y);
  112. }
  113.  
  114. double xorbit[2001],yorbit[2001];
  115.  
  116. double MSetDist(cx,cy,maxiter)
  117. double cx,cy;
  118. long maxiter;
  119. {
  120.     long iter=0,i,flag;
  121.     double huge=100000.0;
  122.     double x=0.0,y=0.0,x2=0.0,y2=0.0,temp,xder,yder;
  123.     double dist=0.0;
  124.  
  125.     xorbit[0]=yorbit[0]=0.0;
  126.     do
  127.     {
  128.         temp=x2-y2+cx;
  129.         y=2*x*y+cy;
  130.         x=temp;
  131.         x2=x*x;
  132.         y2=y*y;
  133.         iter++;
  134.         xorbit[iter]=x;
  135.         yorbit[iter]=y;
  136.     }
  137.     while ((iter<maxiter)&&(x2+y2<huge));
  138.  
  139.     if (x2+y2>huge)
  140.     {
  141.         xder=yder=0.0;
  142.         i=flag=0;
  143.         do
  144.         {
  145.             temp=2*(xorbit[i]*xder-yorbit[i]*yder)+1;
  146.             yder=2*(yorbit[i]*xder+xorbit[i]*yder);
  147.             xder=temp;
  148.             if ((max(abs(xder),abs(yder)))>10000000.0) flag=1;
  149.             i++;
  150.         }
  151.         while ((i<iter)&&(!flag));
  152.         if ((!flag)&&((xder!=0)||(yder!=0)))
  153.             dist=log(x2+y2)*sqrt(x2+y2)/sqrt(xder*xder+yder*yder);
  154.     }
  155.     return(dist);
  156. }
  157.  
  158. MSetDEM(inity,xmin,xmax,ymin,ymax,maxiter,treshold,savefile)
  159. long inity;
  160. double xmin,xmax,ymin,ymax;
  161. long maxiter;
  162. double treshold;
  163. char *savefile;
  164. {
  165.     long ix,iy;
  166.     double delta,cx,cy,dist;
  167.  
  168.     delta=treshold*(xmax-xmin)/s->Width;
  169.     ymax=ymin+(w->Width/w->Height)*(xmax-xmin);
  170.     SetAPen(w->RPort,1L);
  171.     msg=GetMsg(w->UserPort);
  172.     for (iy=inity;(iy<w->Height)&&(msg->Code!=27)&&(msg->Class!=CLOSEWINDOW);iy++)
  173.     {
  174.         cy=ymin+iy*(ymax-ymin)/s->Width;
  175.         for (ix=0;(ix<s->Width)&&(msg->Code!=27)&&(msg->Class!=CLOSEWINDOW);ix++)
  176.         {
  177.             cx=xmin+ix*(xmax-xmin)/s->Width;
  178.             dist=(double)MSetDist(cx,cy,maxiter);
  179.             if (dist>=delta) WritePixel(w->RPort,ix,iy);
  180.             msg=GetMsg(w->UserPort);
  181.             if (msg->Code==115) SaveBitMap(savefile,&s->BitMap,&s->ViewPort.ColorMap->ColorTable[0],1L);
  182.         }
  183.     }
  184. }
  185.  
  186.  
  187. getdoub(doub,datafile)
  188. double *doub;
  189. FILE *datafile;
  190. {
  191.     int i;
  192.     char doublebuf[30];
  193.  
  194.     i=-1;
  195.     doublebuf[0]=0;
  196.     do fread(&doublebuf[++i],1,1,datafile);
  197.     while ((doublebuf[i]!=';')&&(i<30));
  198.     doublebuf[i]=0;
  199.     *doub=atof(&doublebuf[0]);
  200. }
  201.  
  202. getlong(lon,datafile)
  203. long *lon;
  204. FILE *datafile;
  205. {
  206.     int i;
  207.     char doublebuf[30];
  208.  
  209.     i=-1;
  210.     doublebuf[0]=0;
  211.     do fread(&doublebuf[++i],1,1,datafile);
  212.     while ((doublebuf[i]!=';')&&(i<30));
  213.     *lon=atol(&doublebuf[0]);
  214. }
  215.  
  216. DisplayUsage(FromCLI)
  217. int FromCLI;
  218. {
  219.     puts("DEM - B & W MandelBrot generator using Distance Estimator Method");
  220.     puts("      Algorithm from 'The Science of Fractal Images.");
  221.     puts("(c) 1989 by Lars R. Clausen (2:230/22.34)");
  222.     puts("Usage: DEM [datafilename] or");
  223.     puts("       DEM xmin xmax ymin ymax maxit [L|W|H|G|F] savefilename");
  224.     puts("This program is PD (no fun for hackers).");
  225.     puts("Improvements, bugreports and $$$ are welcome.");
  226.     if (!FromCLI) gets();
  227.     exit(0);
  228. }
  229.  
  230. DoSize(size)
  231. char size;
  232. {
  233.     switch (size)
  234.     {
  235.     case 'L':    ns.Height=height; ns.Width=320;
  236.                 nw.Height=height-1; nw.Width=320;
  237.                 ns.ViewModes=0;
  238.                 break;
  239.     case 'W':    ns.Height=height; ns.Width=640;
  240.                 nw.Height=height-1; nw.Width=640;
  241.                 ns.ViewModes=HIRES;
  242.                 break;
  243.     case 'H':    ns.Height=2*height; ns.Width=640;
  244.                 nw.Height=2*height-1; nw.Width=640;
  245.                 ns.ViewModes=HIRES|LACE;
  246.                 break;
  247.     case 'G':   ns.Height=1024; ns.Width=960;
  248.                 nw.Height=1023; nw.Width=960;
  249.                 ns.ViewModes=HIRES|LACE;
  250.                 break;
  251.     case 'F':    ns.Height=ns.Width=nw.Width=1024;
  252.                 nw.Height=1023;
  253.                 ns.ViewModes=HIRES|LACE;
  254.                 break;
  255.     default:     puts("Illegal screen type");
  256.     }
  257. }
  258.  
  259. main(argc,argv)
  260. int argc;
  261. char *argv[];
  262. {
  263.     long i,end=0,fromfile=1,maxit,inity;
  264.     FILE *datafile=NULL;
  265.     double xmin,xmax,ymin,ymax;
  266.     char size,oldsize='H',savefile[200],*dataname="DEMDataFile";
  267.  
  268.     if ((argc==2)&&(strcmp(argv[1],"?")==0)) DisplayUsage(1);
  269.     switch (argc)
  270.     {
  271.         case 1: break;
  272.         case 2: dataname=argv[1]; break;
  273.         case 8:
  274.             xmin=atof(argv[1]);
  275.             xmax=atof(argv[2]);
  276.             ymin=atof(argv[3]);
  277.             ymax=atof(argv[4]);
  278.             maxit=atoi(argv[5]);
  279.             size=*argv[6];
  280.             strcpy(savefile,argv[7]);
  281.             fromfile=0;
  282.             size=toupper(size);
  283.             if (size!='H') DoSize(size);
  284.             oldsize=size;
  285.             break;
  286.         default: DisplayUsage(argc);
  287.     }
  288.     OpenAll();
  289.     if (GfxBase->DisplayFlags&NTSC) height=200;
  290.  
  291. /* format xmin;xmax;ymin;ymax;maxit;size;savefile[EOL] */
  292.     if (fromfile)
  293.     {
  294.         datafile=fopen(dataname,"r");
  295.         if (datafile==NULL) abort("Can't open file");
  296.     }
  297.     do
  298.     {
  299.         if (fromfile)
  300.         {
  301.             getdoub(&xmin,datafile);
  302.             getdoub(&xmax,datafile);
  303.             getdoub(&ymin,datafile);
  304.             getdoub(&ymax,datafile);
  305.             getlong(&maxit,datafile);
  306.             do
  307.                 fread(&size,1,1,datafile);
  308.             while (!(isalpha(size)));
  309.             size=toupper(size);
  310.             if (oldsize!=size)
  311.             {
  312.                 CloseWindow(w);
  313.                 CloseScreen(s);
  314.                 DoSize(size);
  315.                 if ((s=(struct Screen *)OpenScreen(&ns))==NULL)
  316.                     abort("No screen here");
  317.  
  318.                 LoadRGB4(&s->ViewPort,&ColorMap[0],1L);
  319.                 nw.Screen=s;
  320.                 if ((w = (struct Window *) OpenWindow(&nw)) == NULL)
  321.                     abort("Can't (and won't) open window");
  322.             }
  323.             i=-1;
  324.             fread(&savefile[0],1,1,datafile);
  325.             do
  326.                 fread(&savefile[++i],1,1,datafile);
  327.             while ((savefile[i]!=EOF)&&(savefile[i]!='\n')&&(i<200));
  328.             if (savefile[i]==EOF) end=1;
  329.             savefile[i]=0;
  330.             if (i==200) {fclose(datafile);abort("filename too long");}
  331.         }
  332.         oldsize=size;
  333.         Move(w->RPort,0L,0L);
  334.         ClearScreen(w->RPort);
  335.         inity=LoadPicture(savefile);
  336.         printf("Doing: %s Maxit %ld Size %c\n",savefile,maxit,size);
  337.         MSetDEM(inity,xmin,xmax,ymin,ymax,maxit,0.5,savefile);
  338.         if (msg==NULL) SaveBitMap(savefile,&s->BitMap,&s->ViewPort.ColorMap->ColorTable[0],1L);
  339.         if (msg->Class==CLOSEWINDOW) end=1;
  340.         for (msg=GetMsg(w->UserPort);msg!=NULL;ReplyMsg(msg),msg=GetMsg(w->UserPort));
  341.         msg=NULL;
  342.     }
  343.     while ((end==0)&&(fromfile==1));
  344.     if (fromfile) fclose(datafile);
  345.     abort(NULL);
  346. }
  347.