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

📄 lsys.c

📁 frasr200的win 版本源码(18.21),使用make文件,使用的vc版本较低,在我的环境下编译有问题! 很不错的分形程序代码!
💻 C
📖 第 1 页 / 共 2 页
字号:
   xpos=ypos=lsys_Xmin=lsys_Xmax=lsys_Ymax=lsys_Ymin=angle=reverse=realangle=counter=0;
   size=FIXEDPT(1);
   fsret = findsize(command,rules,depth);
   thinking(0, NULL); /* erase thinking message if any */
   xmin = (double) lsys_Xmin / FIXEDMUL;
   xmax = (double) lsys_Xmax / FIXEDMUL;
   ymin = (double) lsys_Ymin / FIXEDMUL;
   ymax = (double) lsys_Ymax / FIXEDMUL;
   locsize = (double) size / FIXEDMUL;
   if (fsret == NULL)
      return 0;
   if (xmax == xmin)
      horiz = 1E37;
   else
      horiz = (xdots-10)/(xmax-xmin);
   if (ymax == ymin)
      vert = 1E37;
   else
      vert = (ydots-6) /(ymax-ymin);
   locsize = (vert<horiz) ? vert : horiz;

   if (horiz == 1E37)
      xpos = FIXEDPT(xdots/2);
   else
      xpos = FIXEDPT(-xmin*(locsize)+5+((xdots-10)-(locsize)*(xmax-xmin))/2);
   if (vert == 1E37)
      ypos = FIXEDPT(ydots/2);
   else
      ypos = FIXEDPT(-ymin*(locsize)+3+((ydots-6)-(locsize)*(ymax-ymin))/2);
   size = FIXEDPT(locsize);
   return 1;
}

static struct lsys_cmd far * _fastcall drawLSys(struct lsys_cmd far *command,struct lsys_cmd far **rules,int depth)
{
   struct lsys_cmd far **rulind;
   int tran;

if (overflow)     /* integer math routines overflowed */
    return NULL;

#ifndef __TURBOC__
   if (stackavail() < 400) { /* leave some margin for calling subrtns */
      stackoflow = 1;
      return NULL;
      }
#endif

   while (command->ch && command->ch !=']') {
      if (!(counter++)) {
	 if (check_key()) {
	    counter--;
	    return NULL;
	 }
      }
      tran=0;
      if (depth) {
	 for(rulind=rules;*rulind;rulind++)
	    if ((*rulind)->ch == command->ch) {
	       tran=1;
	       if (drawLSys((*rulind)+1,rules,depth-1) == NULL)
		  return NULL;
	    }
      }
      if (!depth||!tran) {
	if (command->f)
	  (*command->f)(command->n);
	else if (command->ch == '[') {
	  char saveang,saverev,savecolor;
	  long savesize,savex,savey;
	  unsigned long saverang;

	  saveang=angle;
	  saverev=reverse;
	  savesize=size;
	  saverang=realangle;
	  savex=xpos;
	  savey=ypos;
	  savecolor=curcolor;
	  if ((command=drawLSys(command+1,rules,depth)) == NULL)
	     return(NULL);
	  angle=saveang;
	  reverse=saverev;
	  size=savesize;
	  realangle=saverang;
	  xpos=savex;
	  ypos=savey;
	  curcolor=savecolor;
	}
      }
      command++;
   }
   return command;
}

#define MAXRULES 27 /* this limits rules to 25 */
static char far *ruleptrs[MAXRULES];
static struct lsys_cmd far *rules2[MAXRULES];

static int _fastcall readLSystemFile(char *str)
{
   int c;
   char far **rulind;
   int err=0;
   int linenum,check=0;
   char inline[161],fixed[161],*word;
   FILE *infile;
   char msgbuf[481]; /* enough for 6 full lines */

   if (find_file_item(LFileName,str,&infile) < 0)
      return -1;
   while ((c = fgetc(infile)) != '{')
      if (c == EOF) return -1;

   maxangle=0;
   for(linenum=0;linenum<MAXRULES;++linenum) ruleptrs[linenum]=NULL;
   rulind= &ruleptrs[1];
   msgbuf[0]=linenum=0;

   while(fgets(inline,160,infile))  /* Max line length 160 chars */
   {
      linenum++;
      if ((word = strchr(inline,';'))) /* strip comment */
	 *word = 0;
      strlwr(inline);

      if (strspn(inline," \t\n") < strlen(inline)) /* not a blank line */
      {
	 word=strtok(inline," =\t\n");
	 if (!strcmp(word,"axiom"))
	 {
	    save_rule(strtok(NULL," \t\n"),&ruleptrs[0]);
	    check=1;
	 }
	 else if (!strcmp(word,"angle"))
	 {
	    maxangle=atoi(strtok(NULL," \t\n"));
	    dmaxangle = maxangle - 1;
	    check=1;
	 }
	 else if (!strcmp(word,"}"))
	    break;
	 else if (strlen(word)==1)
	 {
	    char *tok;
	    tok = strtok(NULL, " \t\n");
	    strcpy(fixed, word);
	    if (tok != NULL) {     /* Some strcat's die if they cat with NULL */
		strcat(fixed, tok);
	    }
	    save_rule(fixed, rulind++);
	    check=1;
	 }
	 else
	    if (err<6)
	    {
	       sprintf(&msgbuf[strlen(msgbuf)],
		       "Syntax error line %d: %s\n",linenum,word);
	       ++err;
	    }
	 if (check)
	 {
	    check=0;
	    if(word=strtok(NULL," \t\n"))
	       if (err<6)
	       {
		  sprintf(&msgbuf[strlen(msgbuf)],
			 "Extra text after command line %d: %s\n",linenum,word);
		  ++err;
	       }
	 }
      }
   }
   fclose(infile);
   if (!ruleptrs[0] && err<6)
   {
      strcat(msgbuf,"Error:  no axiom\n");
      ++err;
   }
   if ((maxangle<3||maxangle>50) && err<6)
   {
      strcat(msgbuf,"Error:  illegal or missing angle\n");
      ++err;
   }
   if (err)
   {
      msgbuf[strlen(msgbuf)-1]=0; /* strip trailing \n */
      stopmsg(0,msgbuf);
      return -1;
   }
   *rulind=NULL;
   return 0;
}

static char loaded=0;

int Lsystem()
{
   int order;
   char far **rulesc;
   struct lsys_cmd far **sc;

   if ( (!loaded) && LLoad())
     return -1;

   overflow = 0;		/* reset integer math overflow flag */

   order=param[0];
   if (order<=0)
     order=0;
   stackoflow = 0;

   sc = rules2;
   for (rulesc = ruleptrs; *rulesc; rulesc++)
     *sc++ = SizeTransform(*rulesc);
   *sc = NULL;

   if (findscale(rules2[0], &rules2[1], order)) {
      realangle = angle = reverse = 0;

      free_lcmds();
      sc = rules2;
      for (rulesc = ruleptrs; *rulesc; rulesc++)
	*sc++ = DrawTransform(*rulesc);
      *sc = NULL;

      /* !! HOW ABOUT A BETTER WAY OF PICKING THE DEFAULT DRAWING COLOR */
      if ((curcolor=15) > colors) curcolor=colors-1;
      drawLSys(rules2[0], &rules2[1], order);
   }
   if (stackoflow)
   {
      static char far msg[]={"insufficient memory, try a lower order"};
      stopmsg(0,msg);
   }
   if (overflow) {
      static char far msg[]={"Integer math routines failed, try a lower order"};
      stopmsg(0,msg);
      }
   free_rules_mem();
   free_lcmds();
   loaded=0;
   return 0;
}

int LLoad()
{
   char i;
   if (readLSystemFile(LName)) { /* error occurred */
      free_rules_mem();
      loaded=0;
      return -1;
   }
   for(i=0;i<maxangle;i++) {
      sins[i]=(long) ((sin(2*i*PI/maxangle)) * FIXEDLT1);
      coss[i]=(long) (((double) aspect / (double) FIXEDMUL * cos(2*i*PI/maxangle)) * FIXEDLT1);
   }
   loaded=1;
   return 0;
}

static void _fastcall free_rules_mem()
{
   int i;
   for(i=0;i<MAXRULES;++i)
      if(ruleptrs[i]) farmemfree(ruleptrs[i]);
}

static int _fastcall save_rule(char *rule,char far **saveptr)
{
   int i;
   char far *tmpfar;
   i=strlen(rule)+1;
   if((tmpfar=farmemalloc((long)i))==NULL) {
       stackoflow = 1;
       return -1;
       }
   *saveptr=tmpfar;
   while(--i>=0) *(tmpfar++)= *(rule++);
   return 0;
}

static struct lsys_cmd far *SizeTransform(char far *s)
{
  struct lsys_cmd far *ret;
  struct lsys_cmd far *doub;
  int maxval = 10;
  int n = 0;
  void (*f)(long);
  long num;

  void (*plus)(long) = (ispow2(maxangle)) ? lsys_doplus_pow2 : lsys_doplus;
  void (*minus)(long) = (ispow2(maxangle)) ? lsys_dominus_pow2 : lsys_dominus;
  void (*pipe)(long) = (ispow2(maxangle)) ? lsys_dopipe_pow2 : lsys_dopipe;

  void (*slash)(long) =  (cpu == 386) ? lsys_doslash_386 : lsys_doslash;
  void (*bslash)(long) = (cpu == 386) ? lsys_dobslash_386 : lsys_dobslash;
  void (*at)(long) =     (cpu == 386) ? lsys_doat_386 : lsys_doat;
  void (*dogf)(long) =   (cpu == 386) ? lsys_dosizegf_386 : lsys_dosizegf;

  ret = (struct lsys_cmd far *) farmemalloc((long) maxval * sizeof(struct lsys_cmd));
  if (ret == NULL) {
       stackoflow = 1;
       return NULL;
       }
  while (*s) {
    f = NULL;
    num = 0;
    ret[n].ch = *s;
    switch (*s) {
      case '+': f = plus;            break;
      case '-': f = minus;           break;
      case '/': f = slash;           num = (long) (getnumber(&s) * 11930465L);    break;
      case '\\': f = bslash;         num = (long) (getnumber(&s) * 11930465L);    break;
      case '@': f = at;              num = FIXEDPT(getnumber(&s));    break;
      case '|': f = pipe;            break;
      case '!': f = lsys_dobang;     break;
      case 'd':
      case 'm': f = lsys_dosizedm;   break;
      case 'g':
      case 'f': f = dogf;       break;
      case '[': num = 1;        break;
      case ']': num = 2;        break;
      default:
	num = 3;
	break;
    }
    ret[n].f = f;
    ret[n].n = num;
    if (++n == maxval) {
      doub = (struct lsys_cmd far *) farmemalloc((long) maxval*2*sizeof(struct lsys_cmd));
      if (doub == NULL) {
         farmemfree(ret);
         stackoflow = 1;
         return NULL;
         }
      far_memcpy(doub, ret, maxval*sizeof(struct lsys_cmd));
      farmemfree(ret);
      ret = doub;
      maxval <<= 1;
    }
    s++;
  }
  ret[n].ch = 0;
  ret[n].f = NULL;
  ret[n].n = 0;
  n++;

  doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd));
  if (doub == NULL) {
       farmemfree(ret);
       stackoflow = 1;
       return NULL;
       }
  far_memcpy(doub, ret, n*sizeof(struct lsys_cmd));
  farmemfree(ret);
  return doub;
}

static struct lsys_cmd far *DrawTransform(char far *s)
{
  struct lsys_cmd far *ret;
  struct lsys_cmd far *doub;
  int maxval = 10;
  int n = 0;
  void (*f)(long);
  long num;

  void (*plus)(long) = (ispow2(maxangle)) ? lsys_doplus_pow2 : lsys_doplus;
  void (*minus)(long) = (ispow2(maxangle)) ? lsys_dominus_pow2 : lsys_dominus;
  void (*pipe)(long) = (ispow2(maxangle)) ? lsys_dopipe_pow2 : lsys_dopipe;

  void (*slash)(long) =  (cpu == 386) ? lsys_doslash_386 : lsys_doslash;
  void (*bslash)(long) = (cpu == 386) ? lsys_dobslash_386 : lsys_dobslash;
  void (*at)(long) =     (cpu == 386) ? lsys_doat_386 : lsys_doat;
  void (*drawg)(long) =  (cpu == 386) ? lsys_dodrawg_386 : lsys_dodrawg;

  ret = (struct lsys_cmd far *) farmemalloc((long) maxval * sizeof(struct lsys_cmd));
  if (ret == NULL) {
       stackoflow = 1;
       return NULL;
       }
  while (*s) {
    f = NULL;
    num = 0;
    ret[n].ch = *s;
    switch (*s) {
      case '+': f = plus;            break;
      case '-': f = minus;           break;
      case '/': f = slash;           num = (long) (getnumber(&s) * 11930465L);    break;
      case '\\': f = bslash;         num = (long) (getnumber(&s) * 11930465L);    break;
      case '@': f = at;              num = FIXEDPT(getnumber(&s));    break;
      case '|': f = pipe;            break;
      case '!': f = lsys_dobang;     break;
      case 'd': f = lsys_dodrawd;    break;
      case 'm': f = lsys_dodrawm;    break;
      case 'g': f = drawg;           break;
      case 'f': f = lsys_dodrawf;    break;
      case 'c': f = lsys_dodrawc;    num = getnumber(&s);    break;
      case '<': f = lsys_dodrawlt;   num = getnumber(&s);    break;
      case '>': f = lsys_dodrawgt;   num = getnumber(&s);    break;
      case '[': num = 1;        break;
      case ']': num = 2;        break;
      default:
	num = 3;
	break;
    }
    ret[n].f = f;
    ret[n].n = num;
    if (++n == maxval) {
      doub = (struct lsys_cmd far *) farmemalloc((long) maxval*2*sizeof(struct lsys_cmd));
      if (doub == NULL) {
           farmemfree(ret);
           stackoflow = 1;
           return NULL;
           }
      far_memcpy(doub, ret, maxval*sizeof(struct lsys_cmd));
      farmemfree(ret);
      ret = doub;
      maxval <<= 1;
    }
    s++;
  }
  ret[n].ch = 0;
  ret[n].f = NULL;
  ret[n].n = 0;
  n++;

  doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd));
  if (doub == NULL) {
       farmemfree(ret);
       stackoflow = 1;
       return NULL;
       }
  far_memcpy(doub, ret, n*sizeof(struct lsys_cmd));
  farmemfree(ret);
  return doub;
}

static void free_lcmds()
{
  struct lsys_cmd far **sc = rules2;

  while (*sc)
    farmemfree(*sc++);
}

⌨️ 快捷键说明

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