/* From input file "dragon.pas" */

#include <math.h>
#include <stdio.h>
/* from April 1986 BYTE */

/*  typedef Char one_char;  */

static double angle, xcoord, ycoord, stepsize;
static long out_dev, order, lin_num, num_pts, num_ptr, i, PointCount;
static FILE *cam;
static double xmin, xmax, ymin, ymax, xlim, ylim, xscale, yscale, xoffset,
	      yoffset, xbuf, ybuf;
static double x, y;
static int plotCode, OutRun;
static char FileName[256];

int true =1;
int false =0;

static void move_()
{
  /*moves stepsize in present direction*/
  xcoord += stepsize * cos(angle);
  ycoord += stepsize * sin(angle);
  if (!OutRun) {
    if (xcoord < xmin)
      xmin = xcoord;
    if (xcoord > xmax)
      xmax = xcoord;
    if (ycoord < ymin)
      ymin = ycoord;
    if (ycoord > ymax)
      ymax = ycoord;
    return;
  }
  xbuf = xcoord * xscale + xoffset;
  ybuf = ycoord * yscale + yoffset;
  if (xbuf < xmin)
    xmin = xbuf;
  if (xbuf > xmax)
    xmax = xbuf;
  if (ybuf < ymin)
    ymin = ybuf;
  if (ybuf > ymax)
    ymax = ybuf;
  if (PointCount == 1) {
    x = (long)floor(xbuf + 0.5);
    y = (long)floor(ybuf + 0.5);
    if (plotCode)
      fprintf(cam, "X%ld Y%ldD02*\n", x, y);
    else {
      fprintf(cam, "N%ld X%#6.4lf Y%#6.4lf F50\n", lin_num, xbuf, ybuf);
      lin_num++;
      fprintf(cam, "N%ld G01 Z-0.01 F10\n", lin_num);
      lin_num++;
      /* dummy move follows to set feed rate */
      fprintf(cam, "N%ld X%#6.4lf Y%#6.4lf F25\n", lin_num, xbuf, ybuf);
      lin_num++;
    }
  }  /* if PointCount */
  if (PointCount > 1) {
    x = (long)floor(xbuf + 0.5);
    y = (long)floor(ybuf + 0.5);
    if (plotCode)
      fprintf(cam, "X%ldY%ldD01*\n", x, y);
    else {
      fprintf(cam, "N%ld X%#6.4lf Y%#6.4lf\n", lin_num, xbuf, ybuf);
      lin_num++;
    }
  }
  PointCount++;
}


static void turn(delta)
double delta;
{
  /* turn the turtle */
  angle += delta / 57.3;   /*convert degrees to radians */
  /*    writeln(log,'TURN   ',angle*57.3:12:4);*/
}


static void rec_dragon(sign, level)
double sign;
long level;
{
  /*the recursive part */
  /*    writeln(log,'DRAGON  ',level);*/
  if (level <= 0) {
    move_();
    return;
  }
  turn(sign * 45.0);
  rec_dragon(1.0, level - 1);
  turn(-sign * 90.0);
  rec_dragon(-1.0, level - 1);
  turn(sign * 45.0);
}


main(argc, argv)
int argc;
char *argv[];
{  /* main program */
  cam = NULL;
  OutRun = false;
  xmin = 100000.0;
  xmax = -100000.0;
  ymin = 100000.0;
  ymax = -100000.0;
  xcoord = 1.0;
  ycoord = 1.0;
  angle = 2160.0;
  printf("Enter 1 for milling codes, 2 for photoplotter codes:");
  scanf("%d%*[^\n]", &i);
  getchar();
  if (i > 1)
    plotCode = true;
  else
    plotCode = false;
  printf("Enter order (2..16) integer");
  scanf("%d%*[^\n]", &order);
  getchar();
  stepsize = 1.0;
  xbuf = (long)floor(xcoord + 0.5);
  ybuf = (long)floor(ycoord + 0.5);
  rec_dragon(1.0, order);   /* run it once to gauge limits */
  printf("initial limits :\n");
  printf("xmin,xmax %9.4f%9.4f\n", xmin, xmax);
  printf("ymin,ymax %9.4f%9.4f\n", ymin, ymax);
  printf("Enter dimensions of material, x,y (real)");
  scanf("%lg%lg%*[^\n]", &xlim, &ylim);
  getchar();
  xscale = xlim * 1.0000 / (xmax - xmin) * 0.9;
  yscale = ylim * 1.0000 / (ymax - ymin) * 0.9;
  if (fabs(xscale) < fabs(yscale)) {  /* make 'tightest' dimension */
    yscale = xscale;   /* control the scale */
    ylim = xlim;
  } else {
    xscale = yscale;
    xlim = ylim;
  }
  xoffset = xlim * 1.0000 / 2.0 - (xmax + xmin) / 2.0 * xscale;
  yoffset = ylim * 1.0000 / 2.0 - (ymax + ymin) / 2.0 * yscale;
  printf(" scale factor %12.4f\n", xscale);
  printf("Xoffset,Yoffset %12.4f%12.4f\n", xoffset, yoffset);
  /* now repeat whole process for output */
  OutRun = true;
  PointCount = 1;
  printf("Enter File Name for CAM output:");
  scanf("%s",FileName);
  printf("\n");
  cam = fopen(FileName,"w");
  if (cam != NULL)
    rewind(cam);
  else
    cam = tmpfile();
  if (cam == NULL)
    {
    printf("FileNotFound\n");
      exit(1);
    }
  xmin = 100000.0;
  xmax = -100000.0;
  ymin = 100000.0;
  ymax = -100000.0;
  xcoord = 1.0;
  ycoord = 1.0;
  angle = 2160.0;
  stepsize = 1.0;
  lin_num = 1;
  if (plotCode) {
    fprintf(cam, "*%%FSLAX44Y44*\n");
    fprintf(cam, "SFA1.0B1.0*%%\n");
    fprintf(cam, "G70*\n");
    fprintf(cam, "G90*\n");
    fprintf(cam, "G01*\n");
    fprintf(cam, "D02*\n");
    fprintf(cam, "D10*\n");
  }
  lin_num++;
  xbuf = (long)floor(xcoord * xscale + xoffset + 0.5);
  ybuf = (long)floor(ycoord * yscale + yoffset + 0.5);
  rec_dragon(1.0, order);
  if (plotCode)
    fprintf(cam, "D02M02*\n");
  else {
    fprintf(cam, "N%d Z0.0500\n", lin_num);
    lin_num++;
    fprintf(cam, "N%d X%#6.4f Y%#6.4f F50\n", lin_num, 0.300, 0.700);
    lin_num++;
    fprintf(cam, "N%d (XMIN,MAX = %8.2f %8.2f)\n", lin_num, xmin, xmax);
    lin_num++;
    fprintf(cam, "N%d (YMIN,MAX = %8.2f %8.2f)\n", lin_num, ymin, ymax);
    lin_num++;
    fprintf(cam, "N%d M02\n", lin_num);
  }
  if (cam != NULL)
    fclose(cam);
  cam = NULL;
  printf(" final drawing limits :\n");
  printf("Xmin %8.2f       Xmax %8.2f\n", xmin, xmax);
  printf("Ymin %8.2f       Ymax %8.2f\n", ymin, ymax);
  if (cam != NULL)
    fclose(cam);
  exit(0);
}

/* End. */

