⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calcfrac.c

📁 frasr200的win 版本源码(18.21),使用make文件,使用的vc版本较低,在我的环境下编译有问题! 很不错的分形程序代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
	case West:
	    col = trail_col - 1;
	    row = trail_row;
	    break;
	}
    }

/******************* end of boundary trace method *******************/


/************************ super solid guessing *****************************/

/*
   I, Timothy Wegner, invented this solidguessing idea and implemented it in
   more or less the overall framework you see here.  I am adding this note
   now in a possibly vain attempt to secure my place in history, because
   Pieter Branderhorst has totally rewritten this routine, incorporating
   a *MUCH* more sophisticated algorithm.  His revised code is not only
   faster, but is also more accurate. Harrumph!
*/

static int solidguess()
{
   int i,x,y,xlim,ylim,blocksize;
   unsigned int *pfxp0,*pfxp1;
   unsigned int u;

   guessplot=(plot!=putcolor && plot!=symplot2 && plot!=symplot2J);
   /* check if guessing at bottom & right edges is ok */
   bottom_guess = (plot == symplot2 || (plot == putcolor && iystop+1 == ydots));
   right_guess	= (plot == symplot2J
       || ((plot == putcolor || plot == symplot2) && ixstop+1 == xdots));

   i = maxblock = blocksize = ssg_blocksize();
   totpasses = 1;
   while ((i >>= 1) > 1) ++totpasses;

   /* ensure window top and left are on required boundary, treat window
	 as larger than it really is if necessary (this is the reason symplot
	 routines must check for > xdots/ydots before plotting sym points) */
   ixstart &= -1 - (maxblock-1);
   iystart = yybegin;
   iystart &= -1 - (maxblock-1);

   got_status = 1;

   if (workpass == 0) /* otherwise first pass already done */
   {
      /* first pass, calc every blocksize**2 pixel, quarter result & paint it */
      curpass = 1;
      if (iystart <= yystart) /* first time for this window, init it */
      {
	 currow = 0;
	 memset(&prefix[1][0][0],0,maxxblk*maxyblk*2); /* noskip flags off */
	 reset_periodicity = 1;
	 row=iystart;
	 for(col=ixstart; col<=ixstop; col+=maxblock)
	 { /* calc top row */
	    if((*calctype)()== -1)
	    {
	       add_worklist(xxstart,xxstop,yystart,yystop,yybegin,0,worksym);
	       goto exit_solidguess;
	    }
	    reset_periodicity = 0;
	 }
      }
      else
	 memset(&prefix[1][0][0],-1,maxxblk*maxyblk*2); /* noskip flags on */
      for(y=iystart; y<=iystop; y+=blocksize)
      {
	 currow = y;
	 i = 0;
	 if(y+blocksize<=iystop)
	 { /* calc the row below */
	    row=y+blocksize;
	    reset_periodicity = 1;
	    for(col=ixstart; col<=ixstop; col+=maxblock)
	    {
	       if((i=(*calctype)()) == -1)
		  break;
	       reset_periodicity = 0;
	    }
	 }
	 reset_periodicity = 1;
	 if (i == -1 || guessrow(1,y,blocksize) != 0) /* interrupted? */
	 {
	    if (y < yystart)
	       y = yystart;
	    add_worklist(xxstart,xxstop,yystart,yystop,y,0,worksym);
	    goto exit_solidguess;
	 }
      }

      if (num_worklist) /* work list not empty, just do 1st pass */
      {
	 add_worklist(xxstart,xxstop,yystart,yystop,yystart,1,worksym);
	 goto exit_solidguess;
      }
      ++workpass;
      iystart = yystart & (-1 - (maxblock-1));

      /* calculate skip flags for skippable blocks */
      xlim=(ixstop+maxblock)/maxblock+1;
      ylim=((iystop+maxblock)/maxblock+15)/16+1;
      if(right_guess==0) /* no right edge guessing, zap border */
	 for(y=0;y<=ylim;++y)
	    prefix[1][y][xlim]= -1;
      if(bottom_guess==0) /* no bottom edge guessing, zap border */
      {
	 i=(iystop+maxblock)/maxblock+1;
	 y=i/16+1;
	 i=1<<(i&15);
	 for(x=0;x<=xlim;++x)
	    prefix[1][y][x]|=i;
      }
      /* set each bit in prefix[0] to OR of it & surrounding 8 in prefix[1] */
      for(y=0;++y<ylim;)
      {
	 pfxp0= &prefix[0][y][0];
	 pfxp1= &prefix[1][y][0];
	 for(x=0;++x<xlim;)
	 {
	    ++pfxp1;
	    u= *(pfxp1-1)|*pfxp1|*(pfxp1+1);
	    *(++pfxp0)=u|(u>>1)|(u<<1)
	       |((*(pfxp1-(maxxblk+1))|*(pfxp1-maxxblk)|*(pfxp1-(maxxblk-1)))>>15)
		  |((*(pfxp1+(maxxblk-1))|*(pfxp1+maxxblk)|*(pfxp1+(maxxblk+1)))<<15);
	 }
      }
   }
   else /* first pass already done */
      memset(&prefix[0][0][0],-1,maxxblk*maxyblk*2); /* noskip flags on */

   /* remaining pass(es), halve blocksize & quarter each blocksize**2 */
   i = workpass;
   while (--i > 0) /* allow for already done passes */
      blocksize = blocksize>>1;
   reset_periodicity = 1;
   while((blocksize=blocksize>>1)>=2)
   {
      curpass = workpass + 1;
      for(y=iystart; y<=iystop; y+=blocksize)
      {
	 currow = y;
	 if(guessrow(0,y,blocksize)!=0)
	 {
	    if (y < yystart)
	       y = yystart;
	    add_worklist(xxstart,xxstop,yystart,yystop,y,workpass,worksym);
	    goto exit_solidguess;
	 }
      }
      ++workpass;
      if (num_worklist /* work list not empty, do one pass at a time */
      && blocksize>2) /* if 2, we just did last pass */
      {
	 add_worklist(xxstart,xxstop,yystart,yystop,yystart,workpass,worksym);
	 goto exit_solidguess;
      }
      iystart = yystart & (-1 - (maxblock-1));
   }

   exit_solidguess:
   return(0);
}

#define calcadot(c,x,y) { col=x; row=y; if((c=(*calctype)())== -1) return -1; }

static int _fastcall guessrow(int firstpass,int y,int blocksize)
{
   int x,i,j,color;
   int xplushalf,xplusblock;
   int ylessblock,ylesshalf,yplushalf,yplusblock;
   int	   c21,c31,c41; 	/* cxy is the color of pixel at (x,y) */
   int c12,c22,c32,c42; 	/* where c22 is the topleft corner of */
   int c13,c23,c33;		/* the block being handled in current */
   int	   c24,    c44; 	/* iteration			      */
   int guessed23,guessed32,guessed33,guessed12,guessed13;
   int prev11,fix21,fix31;
   unsigned int *pfxptr,pfxmask;

   halfblock=blocksize>>1;
   i=y/maxblock;
   pfxptr= &prefix[firstpass][(i>>4)+1][ixstart/maxblock];
   pfxmask=1<<(i&15);
   ylesshalf=y-halfblock;
   ylessblock=y-blocksize; /* constants, for speed */
   yplushalf=y+halfblock;
   yplusblock=y+blocksize;
   prev11= -1;
   c24=c12=c13=c22=getcolor(ixstart,y);
   c31=c21=getcolor(ixstart,(y>0)?ylesshalf:0);
   if(yplusblock<=iystop)
      c24=getcolor(ixstart,yplusblock);
   else if(bottom_guess==0)
      c24= -1;
   guessed12=guessed13=0;

   for(x=ixstart; x<=ixstop;)  /* increment at end, or when doing continue */
   {
      if((x&(maxblock-1))==0)  /* time for skip flag stuff */
      {
	 ++pfxptr;
	 if(firstpass==0 && (*pfxptr&pfxmask)==0)  /* check for fast skip */
	 {
	    /* next useful in testing to make skips visible */
	    /*
			   if(halfblock==1)
			   {
			      (*plot)(x+1,y,0); (*plot)(x,y+1,0); (*plot)(x+1,y+1,0);
			      }
			 */
	    x+=maxblock;
	    prev11=c31=c21=c24=c12=c13=c22;
	    guessed12=guessed13=0;
	    continue;
	 }
      }

      if(firstpass)  /* 1st pass, paint topleft corner */
	 plotblock(0,x,y,c22);
      /* setup variables */
      xplusblock=(xplushalf=x+halfblock)+halfblock;
      if(xplushalf>ixstop)
      {
	 if(right_guess==0)
	    c31= -1;
      }
      else if(y>0)
	 c31=getcolor(xplushalf,ylesshalf);
      if(xplusblock<=ixstop)
      {
	 if(yplusblock<=iystop)
	    c44=getcolor(xplusblock,yplusblock);
	 c41=getcolor(xplusblock,(y>0)?ylesshalf:0);
	 c42=getcolor(xplusblock,y);
      }
      else if(right_guess==0)
	 c41=c42=c44= -1;
      if(yplusblock>iystop)
	 c44=(bottom_guess)?c42:-1;

      /* guess or calc the remaining 3 quarters of current block */
      guessed23=guessed32=guessed33=1;
      c23=c32=c33=c22;
      if(yplushalf>iystop)
      {
	 if(bottom_guess==0)
	    c23=c33= -1;
	 guessed23=guessed33= -1;
      }
      if(xplushalf>ixstop)
      {
	 if(right_guess==0)
	    c32=c33= -1;
	 guessed32=guessed33= -1;
      }
      while(1) /* go around till none of 23,32,33 change anymore */
      {
	 if(guessed33>0
	     && (c33!=c44 || c33!=c42 || c33!=c24 || c33!=c32 || c33!=c23))
	 {
	    calcadot(c33,xplushalf,yplushalf);
	    guessed33=0;
	 }
	 if(guessed32>0
	     && (c32!=c33 || c32!=c42 || c32!=c31 || c32!=c21
	     || c32!=c41 || c32!=c23))
	 {
	    calcadot(c32,xplushalf,y);
	    guessed32=0;
	    continue;
	 }
	 if(guessed23>0
	     && (c23!=c33 || c23!=c24 || c23!=c13 || c23!=c12 || c23!=c32))
	 {
	    calcadot(c23,x,yplushalf);
	    guessed23=0;
	    continue;
	 }
	 break;
      }

      if(firstpass) /* note whether any of block's contents were calculated */
	 if(guessed23==0 || guessed32==0 || guessed33==0)
	    *pfxptr|=pfxmask;

      if(halfblock>1) /* not last pass, check if something to display */
	 if(firstpass)	/* display guessed corners, fill in block */
	 {
	    if(guessplot)
	    {
	       if(guessed23>0)
		  (*plot)(x,yplushalf,c23);
	       if(guessed32>0)
		  (*plot)(xplushalf,y,c32);
	       if(guessed33>0)
		  (*plot)(xplushalf,yplushalf,c33);
	    }
	    plotblock(1,x,yplushalf,c23);
	    plotblock(0,xplushalf,y,c32);
	    plotblock(1,xplushalf,yplushalf,c33);
	 }
	 else  /* repaint changed blocks */
	 {
	    if(c23!=c22)
	       plotblock(-1,x,yplushalf,c23);
	    if(c32!=c22)
	       plotblock(-1,xplushalf,y,c32);
	    if(c33!=c22)
	       plotblock(-1,xplushalf,yplushalf,c33);
	 }

      /* check if some calcs in this block mean earlier guesses need fixing */
      fix21=((c22!=c12 || c22!=c32)
	  && c21==c22 && c21==c31 && c21==prev11
	  && y>0
	  && (x==ixstart || c21==getcolor(x-halfblock,ylessblock))
	  && (xplushalf>ixstop || c21==getcolor(xplushalf,ylessblock))
	  && c21==getcolor(x,ylessblock));
      fix31=(c22!=c32
	  && c31==c22 && c31==c42 && c31==c21 && c31==c41
	  && y>0 && xplushalf<=ixstop
	  && c31==getcolor(xplushalf,ylessblock)
	  && (xplusblock>ixstop || c31==getcolor(xplusblock,ylessblock))
	  && c31==getcolor(x,ylessblock));
      prev11=c31; /* for next time around */
      if(fix21)
      {
	 calcadot(c21,x,ylesshalf);
	 if(halfblock>1 && c21!=c22)
	    plotblock(-1,x,ylesshalf,c21);
      }
      if(fix31)
      {
	 calcadot(c31,xplushalf,ylesshalf);
	 if(halfblock>1 && c31!=c22)
	    plotblock(-1,xplushalf,ylesshalf,c31);
      }
      if(c23!=c22)
      {
	 if(guessed12)
	 {
	    calcadot(c12,x-halfblock,y);
	    if(halfblock>1 && c12!=c22)
	       plotblock(-1,x-halfblock,y,c12);
	 }
	 if(guessed13)
	 {
	    calcadot(c13,x-halfblock,yplushalf);
	    if(halfblock>1 && c13!=c22)
	       plotblock(-1,x-halfblock,yplushalf,c13);
	 }
      }
      c22=c42;
      c24=c44;
      c13=c33;
      c31=c21=c41;
      c12=c32;
      guessed12=guessed32;
      guessed13=guessed33;
      x+=blocksize;
   } /* end x loop */

   if(firstpass==0 || guessplot) return 0;

   /* paint rows the fast way */
   for(i=0;i<halfblock;++i)
   {
      if((j=y+i)<=iystop)
	 put_line(j,xxstart,ixstop,&dstack[xxstart]);
      if((j=y+i+halfblock)<=iystop)
	 put_line(j,xxstart,ixstop,&dstack[xxstart+MAXPIXELS]);
      if(keypressed()) return -1;
   }
   if(plot!=putcolor)  /* symmetry, just vertical & origin the fast way */
   {
      if(plot==symplot2J) /* origin sym, reverse lines */
	 for(i=(ixstop+xxstart+1)/2;--i>=xxstart;)
	 {
	    color=dstack[i];
	    dstack[i]=dstack[j=ixstop-(i-xxstart)];
	    dstack[j]=color;
	    j+=MAXPIXELS;
	    color=dstack[i+MAXPIXELS];
	    dstack[i+MAXPIXELS]=dstack[j];
	    dstack[j]=color;
	 }
      for(i=0;i<halfblock;++i)
      {
	 if((j=yystop-(y+i-yystart))>iystop && j<ydots)
	    put_line(j,xxstart,ixstop,&dstack[xxstart]);
	 if((j=yystop-(y+i+halfblock-yystart))>iystop && j<ydots)
	    put_line(j,xxstart,ixstop,&dstack[xxstart+MAXPIXELS]);
	 if(keypressed()) return -1;
      }
   }
   return 0;
}

static void _fastcall plotblock(int buildrow,int x,int y,int color)
{
   int i,xlim,ylim;
   if((xlim=x+halfblock)>ixstop)
      xlim=ixstop+1;
   if(buildrow>=0 && guessplot==0) /* save it for later put_line */
   {
      if(buildrow==0)
	 for(i=x;i<xlim;++i)
	    dstack[i]=color;
      else
	 for(i=x;i<xlim;++i)
	    dstack[i+MAXPIXELS]=color;
      if (x>=xxstart) /* when x reduced for alignment, paint those dots too */
	 return; /* the usual case */
   }
   /* paint it */
   if((ylim=y+halfblock)>iystop)
   {
      if(y>iystop)
	 return;
      ylim=iystop+1;
   }
   for(i=x;++i<xlim;)
      (*plot)(i,y,color); /* skip 1st dot on 1st row */
   while(++y<ylim)
      for(i=x;i<xlim;++i)
	 (*plot)(i,y,color);
}


/************************* symmetry plot setup ************************/

static int _fastcall xsym_split(int xaxis_row,int xaxis_between)
{
   int i;
   if ((worksym&0x11) == 0x10) /* already decided not sym */
      return(1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -