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

📄 lsys.c

📁 frasr200的win 版本源码(18.21),使用make文件,使用的vc版本较低,在我的环境下编译有问题! 很不错的分形程序代码!
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifdef __TURBOC__
#include <alloc.h>
#elif !defined(__386BSD__)
#include <malloc.h>
#endif
#include "fractint.h"
#include "prototyp.h"

#define size	ssize
/* Needed for use of asm -- helps decide which pointer to function
 * to put into the struct lsys_cmds.
 */
extern int cpu;
extern int fpu;
extern int debugflag;
extern int xdots,ydots;
extern int colors;
extern char LFileName[];
extern char LName[];
extern double param[];
extern int overflow;
extern float  screenaspect;

struct lsys_cmd {
  char ch;
  void (*f)(long n);
  long n;
};

static double	  _fastcall getnumber(char far **);
static struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *,struct lsys_cmd far **,int);
static int	  _fastcall findscale(struct lsys_cmd far *, struct lsys_cmd far **, int);
static struct lsys_cmd far * _fastcall drawLSys(struct lsys_cmd far *, struct lsys_cmd far **, int);
static int	  _fastcall readLSystemFile(char *);
static void	  _fastcall free_rules_mem(void);
static int	  _fastcall save_rule(char *,char far **);
static struct lsys_cmd far *SizeTransform(char far *s);
static struct lsys_cmd far *DrawTransform(char far *s);
static void free_lcmds();

static long aspect; /* aspect ratio of each pixel, ysize/xsize */

/* Some notes to Adrian from PB, made when I integrated with v15:
     printfs changed to work with new user interface
     bug at end of readLSystemFile, the line which said rulind=0 fixed
       to say *rulind=0
     the calloc was not worthwhile, it was just for a 54 byte area, cheaper
       to keep it as a static;	but there was a static 201 char buffer I
       changed to not be static
     use of strdup was a nono, caused problems running out of space cause
       the memory allocated each time was never freed; I've changed to
       use far memory and to free when done
   */

long sins[50];
long coss[50];
/* dmaxangle is maxangle - 1. */
char maxangle,dmaxangle,curcolor;
long size;
unsigned long realangle;
long xpos,ypos;
char counter,angle,reverse,stackoflow;
long lsys_Xmin, lsys_Xmax, lsys_Ymin, lsys_Ymax;

/* Macro to take an FP number and turn it into a
 * 16/16-bit fixed-point number.
 */
#define FIXEDMUL	524288L
#define FIXEDPT(x)	((long) (FIXEDMUL * (x)))

/* The number by which to multiply sines, cosines and other
 * values with magnitudes less than or equal to 1.
 * sins and coss are a 3/29 bit fixed-point scheme (so the
 * range is +/- 2, with good accuracy.	The range is to
 * avoid overflowing when the aspect ratio is taken into
 * account.
 */
#define FIXEDLT1	536870912.0

/* Multiply by this number to convert an unsigned 32-bit long
 * to an angle from 0-2PI.
 */
#define ANGLE2DOUBLE	(2*PI / 4294967296.)

static int ispow2(long n)
{
  return (n == (n & -n));
}


#ifdef XFRACT
static void lsys_doplus(long n)
{
  if (reverse) {
    if (++angle == maxangle)
      angle = 0;
  }
  else {
    if (angle)
      angle--;
    else
      angle = dmaxangle;
  }
}
#endif


#ifdef XFRACT
/* This is the same as lsys_doplus, except maxangle is a power of 2. */
static void lsys_doplus_pow2(long n)
{
  if (reverse) {
    angle++;
    angle &= dmaxangle;
  }
  else {
    angle--;
    angle &= dmaxangle;
  }
}
#endif


#ifdef XFRACT
static void lsys_dominus(long n)
{
  if (reverse) {
    if (angle)
      angle--;
    else
      angle = dmaxangle;
  }
  else {
    if (++angle == maxangle)
      angle = 0;
  }
}
#endif


#ifdef XFRACT
static void lsys_dominus_pow2(long n)
{
  if (reverse) {
    angle--;
    angle &= dmaxangle;
  }
  else {
    angle++;
    angle &= dmaxangle;
  }
}
#endif

static void lsys_doslash(long n)
{
  if (reverse)
    realangle -= n;
  else
    realangle += n;
}
#ifdef XFRACT
#define lsys_doslash_386 lsys_doslash
#endif

static void lsys_dobslash(long n)
{
  if (reverse)
    realangle += n;
  else
    realangle -= n;
}

#ifdef XFRACT
#define lsys_dobslash_386 lsys_dobslash
#endif

static void lsys_doat(long n)
{
  size = multiply(size, n, 19);
}

#ifdef XFRACT
#define lsys_doat_386 lsys_doat
#endif

static void lsys_dopipe(long n)
{
  angle += maxangle / 2;
  angle %= maxangle;
}


#ifdef XFRACT
static void lsys_dopipe_pow2(long n)
{
  angle += maxangle >> 1;
  angle &= dmaxangle;
}
#endif


#ifdef XFRACT
static void lsys_dobang(long n)
{
  reverse = ! reverse;
}
#endif

static void lsys_dosizedm(long n)
{
  double angle = (double) realangle * ANGLE2DOUBLE;
  double s, c;
  long fixedsin, fixedcos;
  FPUsincos(&angle, &s, &c);
  fixedsin = (long) (s * FIXEDLT1);
  fixedcos = (long) (c * FIXEDLT1);

  xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  ypos += multiply(size, fixedsin, 29);

/* xpos+=size*aspect*cos(realangle*PI/180);  */
/* ypos+=size*sin(realangle*PI/180);         */
  if (xpos>lsys_Xmax) lsys_Xmax=xpos;
  if (ypos>lsys_Ymax) lsys_Ymax=ypos;
  if (xpos<lsys_Xmin) lsys_Xmin=xpos;
  if (ypos<lsys_Ymin) lsys_Ymin=ypos;
}

static void lsys_dosizegf(long n)
{
  xpos += multiply(size, (long) coss[angle], 29);
  ypos += multiply(size, (long) sins[angle], 29);
/* xpos+=size*coss[angle];                   */
/* ypos+=size*sins[angle];                   */
  if (xpos>lsys_Xmax) lsys_Xmax=xpos;
  if (ypos>lsys_Ymax) lsys_Ymax=ypos;
  if (xpos<lsys_Xmin) lsys_Xmin=xpos;
  if (ypos<lsys_Ymin) lsys_Ymin=ypos;
}

#ifdef XFRACT
#define lsys_dosizegf_386 lsys_dosizegf
#endif

static void lsys_dodrawd(long n)
{
  double angle = (double) realangle * ANGLE2DOUBLE;
  double s, c;
  long fixedsin, fixedcos;
  int lastx, lasty;
  FPUsincos(&angle, &s, &c);
  fixedsin = (long) (s * FIXEDLT1);
  fixedcos = (long) (c * FIXEDLT1);

  lastx=(int) (xpos >> 19);
  lasty=(int) (ypos >> 19);
  xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  ypos += multiply(size, fixedsin, 29);
/* xpos+=size*aspect*cos(realangle*PI/180);   */
/* ypos+=size*sin(realangle*PI/180);          */
  draw_line(lastx,lasty,(int)(xpos >> 19),(int)(ypos>>19),curcolor);
}

static void lsys_dodrawm(long n)
{
  double angle = (double) realangle * ANGLE2DOUBLE;
  double s, c;
  long fixedsin, fixedcos;
  FPUsincos(&angle, &s, &c);
  fixedsin = (long) (s * FIXEDLT1);
  fixedcos = (long) (c * FIXEDLT1);

/* xpos+=size*aspect*cos(realangle*PI/180);   */
/* ypos+=size*sin(realangle*PI/180);          */
  xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  ypos += multiply(size, fixedsin, 29);
}

static void lsys_dodrawg(long n)
{
  xpos += multiply(size, (long) coss[angle], 29);
  ypos += multiply(size, (long) sins[angle], 29);
/* xpos+=size*coss[angle];                    */
/* ypos+=size*sins[angle];                    */
}

#ifdef XFRACT
#define  lsys_dodrawg_386 lsys_dodrawg
#endif

static void lsys_dodrawf(long n)
{
  int lastx = (int) (xpos >> 19);
  int lasty = (int) (ypos >> 19);
  xpos += multiply(size, (long) coss[angle], 29);
  ypos += multiply(size, (long) sins[angle], 29);
/* xpos+=size*coss[angle];                    */
/* ypos+=size*sins[angle];                    */
  draw_line(lastx,lasty,(int)(xpos>>19),(int)(ypos>>19),curcolor);
}

static void lsys_dodrawc(long n)
{
  curcolor = ((int) n) % colors;
}

static void lsys_dodrawgt(long n)
{
  curcolor -= n;
  if ((curcolor &= colors-1) == 0)
    curcolor = colors-1;
}

static void lsys_dodrawlt(long n)
{
  curcolor += n;
  if ((curcolor &= colors-1) == 0)
    curcolor = 1;
}

static double _fastcall getnumber(char far **str)
{
   char numstr[30];
   float ret;
   int i,root,inverse;

   root=0;
   inverse=0;
   strcpy(numstr,"");
   (*str)++;
   switch (**str)
   {
   case 'q':
      root=1;
      (*str)++;
      break;
   case 'i':
      inverse=1;
      (*str)++;
      break;
   }
   switch (**str)
   {
   case 'q':
      root=1;
      (*str)++;
      break;
   case 'i':
      inverse=1;
      (*str)++;
      break;
   }
   i=0;
   while (**str<='9' && **str>='0' || **str=='.')
   {
      numstr[i++]= **str;
      (*str)++;
   }
   (*str)--;
   numstr[i]=0;
   ret=atof(numstr);
   if (root)
     ret=sqrt(ret);
   if (inverse)
     ret = 1/ret;
   return ret;
}

static struct lsys_cmd far * _fastcall findsize(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++)) {
	 /* let user know we're not dead */
	 if (thinking(1,"L-System thinking (higher orders take longer)")) {
	    counter--;
	    return NULL;
	 }
      }
      tran=0;
      if (depth) {
	 for(rulind=rules;*rulind;rulind++)
	    if ((*rulind)->ch==command->ch) {
	       tran=1;
	       if (findsize((*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;
	  long savesize,savex,savey;
	  unsigned long saverang;

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

static int _fastcall findscale(struct lsys_cmd far *command, struct lsys_cmd far **rules, int depth)
{
   float horiz,vert;
   double xmin, xmax, ymin, ymax;
   double locsize;
   double locaspect;
   int i;
   struct lsys_cmd far *fsret;
   locaspect=screenaspect*xdots/ydots;
   aspect = FIXEDPT(locaspect);
   for(i=0;i<maxangle;i++) {
      sins[i]=(long) ((sin(2*i*PI/maxangle)) * FIXEDLT1);
      coss[i]=(long) ((locaspect * cos(2*i*PI/maxangle)) * FIXEDLT1);
   }

⌨️ 快捷键说明

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