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

📄 calcfrac.c

📁 frasr200的win 版本源码(18.21),使用make文件,使用的vc版本较低,在我的环境下编译有问题! 很不错的分形程序代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (new.x < 0)
      {
	 ++temp;
	 new.x = -new.x;
      }
      if (decomp[0] >= 8)
      {
	 temp <<= 1;
	 if (new.x < new.y)
	 {
	    ++temp;
	    alt.x = new.x; /* just */
	    new.x = new.y; /* swap */
	    new.y = alt.x; /* them */
	 }
	 if (decomp[0] >= 16)
	 {
	    temp <<= 1;
	    if (new.x*tan22_5 < new.y)
	    {
	       ++temp;
	       alt = new;
	       new.x = alt.x*cos45 + alt.y*sin45;
	       new.y = alt.x*sin45 - alt.y*cos45;
	    }

	    if (decomp[0] >= 32)
	    {
	       temp <<= 1;
	       if (new.x*tan11_25 < new.y)
	       {
		  ++temp;
		  alt = new;
		  new.x = alt.x*cos22_5 + alt.y*sin22_5;
		  new.y = alt.x*sin22_5 - alt.y*cos22_5;
	       }

	       if (decomp[0] >= 64)
	       {
		  temp <<= 1;
		  if (new.x*tan5_625 < new.y)
		  {
		     ++temp;
		     alt = new;
		     new.x = alt.x*cos11_25 + alt.y*sin11_25;
		     new.y = alt.x*sin11_25 - alt.y*cos11_25;
		  }

		  if (decomp[0] >= 128)
		  {
		     temp <<= 1;
		     if (new.x*tan2_8125 < new.y)
		     {
			++temp;
			alt = new;
			new.x = alt.x*cos5_625 + alt.y*sin5_625;
			new.y = alt.x*sin5_625 - alt.y*cos5_625;
		     }

		     if (decomp[0] == 256)
		     {
			temp <<= 1;
			if ((new.x*tan1_4063 < new.y))
			   ++temp;
		     }
		  }
	       }
	    }
	 }
      }
   }
   for (i = 1; temp > 0; ++i)
   {
      if (temp & 1)
	 color = (1 << i) - 1 - color;
      temp >>= 1;
   }
   if (decomp[0] == 2)
      color &= 1;
   if (colors > decomp[0])
      color++;
}

/******************************************************************/
/* Continuous potential calculation for Mandelbrot and Julia	  */
/* Reference: Science of Fractal Images p. 190. 		  */
/* Special thanks to Mark Peterson for his "MtMand" program that  */
/* beautifully approximates plate 25 (same reference) and spurred */
/* on the inclusion of similar capabilities in FRACTINT.	  */
/*								  */
/* The purpose of this function is to calculate a color value	  */
/* for a fractal that varies continuously with the screen pixels  */
/* locations for better rendering in 3D.			  */
/*								  */
/* Here "magnitude" is the modulus of the orbit value at          */
/* "iterations". The potparms[] are user-entered paramters        */
/* controlling the level and slope of the continuous potential	  */
/* surface. Returns color.  - Tim Wegner 6/25/89		  */
/*								  */
/*		       -- Change history --			  */
/*								  */
/* 09/12/89   - added floatflag support and fixed float underflow */
/*								  */
/******************************************************************/

static int _fastcall potential(double mag, int iterations)
{
   float f_mag,f_tmp,pot;
   double d_tmp;
   int i_pot;
   long l_pot;
   extern char floatflag;

   if(iterations < maxit)
   {
      pot = i_pot = iterations+2;
      if(i_pot <= 0 || mag <= 1.0)
	 pot = 0.0;
      else /* pot = log(mag) / pow(2.0, (double)pot); */
      {
	 if(i_pot < 120 && !floatflag) /* empirically determined limit of fShift */
	 {
	    f_mag = mag;
	    fLog14(f_mag,f_tmp); /* this SHOULD be non-negative */
	    fShift(f_tmp,(char)-i_pot,pot);
	 }
	 else
	 {
	    d_tmp = log(mag)/(double)pow(2.0,(double)pot);
	    if(d_tmp > FLT_MIN) /* prevent float type underflow */
	       pot = d_tmp;
	    else
	       pot = 0.0;
	 }
      }
      /* following transformation strictly for aesthetic reasons */
      /* meaning of parameters:
	    potparam[0] -- zero potential level - highest color -
	    potparam[1] -- slope multiplier -- higher is steeper
	    potparam[2] -- rqlim value if changeable (bailout for modulus) */

      if(pot > 0.0)
      {
	 if(floatflag)
	    pot = (float)sqrt((double)pot);
	 else
	 {
	    fSqrt14(pot,f_tmp);
	    pot = f_tmp;
	 }
	 pot = potparam[0] - pot*potparam[1] - 1.0;
      }
      else
	 pot = potparam[0] - 1.0;
      if(pot < 1.0)
	 pot = 1.0; /* avoid color 0 */
   }
   else if(inside >= 0)
      pot = inside;
   else /* inside < 0 implies inside=maxit, so use 1st pot param instead */
      pot = potparam[0];

   i_pot = (l_pot = pot * 256) >> 8;
   if(i_pot >= colors)
   {
      i_pot = colors - 1;
      l_pot = 255;
   }

   if(pot16bit)
   {
      if (dotmode != 11) /* if putcolor won't be doing it for us */
	 writedisk(col+sxoffs,row+syoffs,i_pot);
      writedisk(col+sxoffs,row+sydots+syoffs,(int)l_pot);
   }

   return(i_pot);
}


/******************* boundary trace method ***************************
Fractint's original btm was written by David Guenther.  There were a few
rare circumstances in which the original btm would not trace or fill
correctly, even on Mandelbrot Sets.  The code below was adapted from
"Mandelbrot Sets by Wesley Loewer" (see calmanfp.asm) which was written
before I was introduced to Fractint.  It should be noted that without
David Guenther's implimentation of a btm, I doubt that I would have been
able to impliment my own code into Fractint.  There are several things in
the following code that are not original with me but came from David
Guenther's code.  I've noted these places with the initials DG.

					Wesley Loewer 3/8/92
*********************************************************************/
#define bkcolor 0  /* I have some ideas for the future with this. -Wes */
#define advance_match()     coming_from = ((going_to = (going_to - 1) & 0x03) - 1) & 0x03
#define advance_no_match()  going_to = (going_to + 1) & 0x03

static
int  bound_trace_main()
    {
    enum direction coming_from;
    unsigned int match_found, continue_loop;
    int trail_color, fillcolor_used, last_fillcolor_used;
    int max_putline_length;
    int right, left, length;

    if (inside == 0 || outside == 0)
	{
	static char far msg[]=
	    "Boundary tracing cannot be used with inside=0 or outside=0.";
	stopmsg(0,msg);
	return(-1);
	}
    if (colors < 16)
	{
	static char far msg[]=
	    "Boundary tracing cannot be used with < 16 colors.";
	stopmsg(0,msg);
	return(-1);
	}

    got_status = 2;
    max_putline_length = 0; /* reset max_putline_length */
    for (currow = iystart; currow <= iystop; currow++)
	{
	reset_periodicity = 1; /* reset for a new row */
	color = bkcolor;
	for (curcol = ixstart; curcol <= ixstop; curcol++)
	    {
	    if (getcolor(curcol, currow) != bkcolor)
		continue;

	    trail_color = color;
	    row = currow;
	    col = curcol;
	    if ((*calctype)()== -1) /* color, row, col are global */
		{
		if (iystop != yystop)  /* DG */
		   iystop = yystop - (currow - yystart); /* allow for sym */
		add_worklist(xxstart,xxstop,currow,iystop,currow,0,worksym);
		return -1;
		}
	    reset_periodicity = 0; /* normal periodicity checking */

	    /*
	    This next line may cause a few more pixels to be calculated,
	    but at the savings of quite a bit of overhead
	    */
	    if (color != trail_color)  /* DG */
		continue;

	    /* sweep clockwise to trace outline */
	    trail_row = currow;
	    trail_col = curcol;
	    trail_color = color;
	    fillcolor_used = fillcolor > 0 ? fillcolor : trail_color;
	    coming_from = West;
	    going_to = East;
	    match_found = 0;
	    continue_loop = TRUE;
	    do
		{
		step_col_row();
		if (row >= currow
			&& col >= ixstart
			&& col <= ixstop
			&& row <= iystop)
		    {
		    /* the order of operations in this next line is critical */
		    if ((color = getcolor(col, row)) == bkcolor && (*calctype)()== -1)
				/* color, row, col are global for (*calctype)() */
			{
			if (iystop != yystop)  /* DG */
			   iystop = yystop - (currow - yystart); /* allow for sym */
			add_worklist(xxstart,xxstop,currow,iystop,currow,0,worksym);
			return -1;
			}
		    else if (color == trail_color)
			{
			if (match_found < 4) /* to keep it from overflowing */
				match_found++;
			trail_row = row;
			trail_col = col;
			advance_match();
			}
		    else
			{
			advance_no_match();
			continue_loop = going_to != coming_from || match_found;
			}
		    }
		else
		    {
		    advance_no_match();
		    continue_loop = going_to != coming_from || match_found;
		    }
		} while (continue_loop && (col != curcol || row != currow));

	    if (match_found <= 3)  /* DG */
		{ /* no hole */
		color = bkcolor;
		reset_periodicity = 1;
		continue;
		}

/*
Fill in region by looping around again, filling lines to the left
whenever going_to is South or West
*/
	    trail_row = currow;
	    trail_col = curcol;
	    coming_from = West;
	    going_to = East;
	    do
		{
		match_found = FALSE;
		do
		    {
		    step_col_row();
		    if (row >= currow
			    && col >= ixstart
			    && col <= ixstop
			    && row <= iystop
			    && getcolor(col,row) == trail_color)
			      /* getcolor() must be last */
			{
			if (going_to == South
				|| (going_to == West && coming_from != East))
			    { /* fill a row, but only once */
			    right = col;
			    while (--right >= ixstart && (color = getcolor(right,row)) == trail_color)
				; /* do nothing */
			    if (color == bkcolor) /* check last color */
				{
				left = right;
				while (getcolor(--left,row) == bkcolor)
				      /* Should NOT be possible for left < ixstart */
				    ; /* do nothing */
				left++; /* one pixel too far */
				if (right == left) /* only one hole */
				    (*plot)(left,row,fillcolor_used);
				else
				    { /* fill the line to the left */
				    length=right-left+1;
				    if (fillcolor_used != last_fillcolor_used || length > max_putline_length)
					{ /* only reset dstack if necessary */
					memset(dstack,fillcolor_used,length);
					last_fillcolor_used = fillcolor_used;
					max_putline_length = length;
					}
				    put_line(row,left,right,dstack);
				    /* here's where all the symmetry goes */
				    if (plot == putcolor)
					kbdcount -= length >> 4; /* seems like a reasonable value */
				    else if (plot == symplot2) /* X-axis symmetry */
					{
					put_line(yystop-(row-yystart),left,right,dstack);
					kbdcount -= length >> 3;
					}
				    else if (plot == symplot2Y) /* Y-axis symmetry */
					{
					put_line(row,xxstop-(right-xxstart),xxstop-(left-xxstart),dstack);
					kbdcount -= length >> 3;
					}
				    else if (plot == symplot2J)  /* Origin symmetry */
					{
					put_line(yystop-(row-yystart),xxstop-(right-xxstart),xxstop-(left-xxstart),dstack);
					kbdcount -= length >> 3;
					}
				    else if (plot == symplot4) /* X-axis and Y-axis symmetry */
					{
					put_line(yystop-(row-yystart),left,right,dstack);
					put_line(row,xxstop-(right-xxstart),xxstop-(left-xxstart),dstack);
					put_line(yystop-(row-yystart),xxstop-(right-xxstart),xxstop-(left-xxstart),dstack);
					kbdcount -= length >> 2;
					}
				    else    /* cheap and easy way out */
					{
					int c;
					for (c = left; c <= right; c++)  /* DG */
					    (*plot)(c,row,fillcolor_used);
					kbdcount -= length >> 1;
					}
				    }
				} /* end of fill line */

			    if(--kbdcount<=0)
				{
				if(check_key())
				    {
				    if (iystop != yystop)
				       iystop = yystop - (currow - yystart); /* allow for sym */
				    add_worklist(xxstart,xxstop,currow,iystop,currow,0,worksym);
				    return(-1);
				    }
				kbdcount=max_kbdcount;
				}
			    }
			trail_row = row;
			trail_col = col;
			advance_match();
			match_found = TRUE;
			}
		    else
			advance_no_match();
		    } while (!match_found && going_to != coming_from);

		if (!match_found)
		    { /* next one has to be a match */
		    step_col_row();
		    trail_row = row;
		    trail_col = col;
		    advance_match();
		    }
		} while (trail_col != curcol || trail_row != currow);
	    reset_periodicity = 1; /* reset after a trace/fill */
	    color = bkcolor;
	    }
	}
    return 0;
    }

/*******************************************************************/
/* take one step in the direction of going_to */
static void step_col_row()
    {
    switch (going_to)
	{
	case North:
	    col = trail_col;
	    row = trail_row - 1;
	    break;
	case East:
	    col = trail_col + 1;
	    row = trail_row;
	    break;
	case South:
	    col = trail_col;
	    row = trail_row + 1;
	    break;

⌨️ 快捷键说明

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