/* makebore.c */

#include <stdio.h>

typedef enum {
  initial, Spiraling, finishing
} States_type;

typedef enum {
  linear, arc
} Interp_type;

double CenterX, CenterY, ToolDia, BoreDia, BoreRadius, FeedRate,
	      WidthOfCut, FinishWOC, FinishFeed, Offset, CurRadius,
              X, Y, Z, I, DepthPerPass, BoreDepth,
	      J, NX, NY, NR, CurX, CurY, CurZ, CentDist, ToolRadius;
double ArcCent, ArcRadius, OldRadius;
int Quadrant, FinQuadrant;
int true =1;
int false =0;
double LineNo;
States_type State;
Interp_type Interp;
char FileName[256];
int Done;
FILE *OutFile;
int FeedonLine;
int EXIT_SUCCESS=1;
int EXIT_FAILURE=0;

void OutNum(RealNum, SigFrac)
double RealNum;
long SigFrac;
{
  double i;
  int j;
  char format[8];

  for (i = 1.0, j = 0; j <= 6 && i<= fabs(RealNum); i *= 10.0, j++)
    {}
  j += SigFrac-1;  /* J <= # int digits + 1 for decimal pt + #frac digits */
  if (RealNum < 0.0 )
    j += 1;          /* add a position for the minus sign */
  sprintf(format,"%%%d.%dlf",j,SigFrac);
    fprintf(OutFile, format, (RealNum));
}


void WriteLineNo()
{
  putc('N', OutFile);
  OutNum(LineNo, 0L);
  LineNo += 10.0;
  putc(' ', OutFile);
}


main(argc, argv)
int argc;
char *argv[];
{
  OutFile = NULL;
  printf("Enter Starting X,Y (real):");
  scanf("%lf %lf", &CenterX, &CenterY);
  getchar();
  printf("\nEnter Tool Diameter, Bore Diameter (real):");
  scanf("%lf %lf", &ToolDia, &BoreDia);
  getchar();
  printf("\nEnter Feed Rate (IPM), Width of Cut (real):");
  scanf("%lf %lf", &FeedRate, &WidthOfCut);
  getchar();
  printf("\nEnter Finish Feed Rate, Width of Cut (real):");
  scanf("%lf %lf", &FinishFeed, &FinishWOC);
  getchar();
  printf("\nEnter Z Depth per Pass, Bore Depth:");
  scanf("%lf %lf", &DepthPerPass, &BoreDepth);
  getchar();
  printf("\nEnter File Name for CAM output:");
  scanf("%s",FileName);
  putchar('\n');
  OutFile = fopen(FileName,"w");
  if (OutFile != NULL)
    rewind(OutFile);
  else
    OutFile = tmpfile();
  if (OutFile == NULL)
    exit(EXIT_FAILURE);
  LineNo = 10.0;
  ToolRadius = ToolDia / 2.0;
  BoreRadius = BoreDia / 2.0;
  /* safety test on Width of cut */
  if (BoreRadius - ToolRadius - FinishWOC <= WidthOfCut)
    {
      printf("Width of Cut too large to spiral out to requested bore.\n");
      exit(EXIT_FAILURE);
    }
  /* loop to cut spiral path at each depth increment */
  for (CurZ = -DepthPerPass;
          CurZ >= -BoreDepth-DepthPerPass+0.001; CurZ -= DepthPerPass)
    {
    if (CurZ < -BoreDepth)
      {
      CurZ = -BoreDepth;
      /*  State = LastLevel;  */
      }
    WriteLineNo();
    fprintf(OutFile, "G01 ");   /* Linear Interpolation */
    Interp = linear;
    putc('F', OutFile);   /*set feedrate */
    OutNum(FeedRate, 3L);
    CurX = CenterX;
    CurY = CenterY;
    putc(' ', OutFile);
    putc('X', OutFile);    /* Move to Center */
    OutNum(CurX, 4L);
    fprintf(OutFile, " Y");
    OutNum(CurY, 4L);
    putc('\n', OutFile);

    WriteLineNo();
    fprintf(OutFile, "F");
    OutNum(FeedRate/6.0, 3L);
    fprintf(OutFile, " Z");  /* LOWER tool */
    OutNum(CurZ,4L);
    putc('\n', OutFile);
    WriteLineNo();
    fprintf(OutFile, "F");
    OutNum(FeedRate, 3L);
    CurRadius = WidthOfCut/4.0;
    CurX += CurRadius;
    OldRadius = CurRadius;
    fprintf(OutFile, " X");
    OutNum(CurX, 4L);
    putc('\n', OutFile);
    /*    WriteLineNo(); */
    /*    fprintf(OutFile, "G03\n");   CCW Circular Interpolation */
    Quadrant = 1;
    FinQuadrant = 0;
    State = initial;
    Done = false;
    FeedonLine = false;
    /*  loop to spiral out in quadrants */
    do {
      if (State == finishing) {
        CentDist = CurRadius;
	ArcRadius = CurRadius; }
      else {
        CentDist = CurRadius + WidthOfCut / 4.0;
      /* compute where to put center of arc */
      ArcCent=(OldRadius*OldRadius - CurRadius*CurRadius)/(-2.0*CurRadius);
      ArcRadius = CurRadius - ArcCent;
      OldRadius = CurRadius; }
      switch (Quadrant) {

      case 1:
        NX = CenterX;
        NY = CenterY + CurRadius;
        NR = ArcRadius;
        break;

      case 2:
        NX = CenterX - CurRadius;
        NY = CenterY;
        NR = ArcRadius;
        break;

      case 3:
        NX = CenterX;
        NY = CenterY - CurRadius;
        NR = ArcRadius;
        break;

      case 4:
        NX = CenterX + CurRadius;
        NY = CenterY;
        NR = ArcRadius;
        break;
    }               /* switch */
    if (FeedonLine == false) {
	WriteLineNo();
    }
	FeedonLine = false;
      if (Interp == linear)
	{
	  Interp = arc;
	  fprintf(OutFile, "G03 ");
	}
      putc('X', OutFile);
      OutNum(NX, 4L);
      fprintf(OutFile, " Y");
      OutNum(NY, 4L);
      fprintf(OutFile, " R");
      OutNum(NR, 4L);
      putc('\n', OutFile);
      if (State == finishing) {
        FinQuadrant++;
        if (FinQuadrant >= 5)
	  Done = true;
      }
      if (State == Spiraling) {
        if (CurRadius <= BoreRadius - ToolRadius - FinishWOC - 0.001)
	  CurRadius += WidthOfCut / 4.0;
        else {
/*	  printf("Cur Z = %12.4f BoreDepth = %12.4f\n",CurZ,BoreDepth); */
	  if (CurZ-.001 <= -(BoreDepth))
	  {
/*	    printf("State is finishing\n");   /* bore to finish diameter */
  	  State = finishing;
	  CurRadius = BoreRadius - ToolRadius;
	  FinQuadrant = 0;
	  WriteLineNo();
	  putc('F', OutFile);   /*set finish feedrate */
	  OutNum(FinishFeed, 3L);
	  putc(' ', OutFile);
	  FeedonLine = true;
          }
	  else {
	    State = finishing; /* Bore to true circle, leaving FinishWOC */
	    CurRadius = BoreRadius - ToolRadius - FinishWOC;
	    FinQuadrant = 0;
	  }
	}
      }
      if (State == initial) {
        if (CurRadius > WidthOfCut)
	  State = Spiraling;
        CurRadius += WidthOfCut / 4.0;
      }
      Quadrant++;
      if (Quadrant > 4)
        Quadrant = 1;
    } while (!Done);
    }       /* for CurZ ... */
   WriteLineNo();
   fprintf(OutFile,"G01 X");     /* return to center */
   OutNum(CenterX,4L);
   fprintf(OutFile," Y");        /* return to center */
   OutNum(CenterY,4L);
   fprintf(OutFile,"\n");
   WriteLineNo();
   fprintf(OutFile, "G01 F50 Z0.1\n");   /* raise spindle above work */
  WriteLineNo();
  fprintf(OutFile, "M02\n");   /*End of Program */
  if (OutFile != NULL)
    fclose(OutFile);
  OutFile = NULL;
  if (OutFile != NULL)
    fclose(OutFile);
  exit(EXIT_SUCCESS);
}

/* End. */










