/*   Listing3.c
     © 1/9/91  Peter Heinrich and Nathan Dwyer

     This program is the revised and optimized version of Listing2.  Note
     that only the fixed-point version of the doConic() routine is here;
     the whole object was to get rid of the floating point!
     
     Lc -L Listing3 to compile.
*/



#include <stdio.h>
#include <stdlib.h>

void doConicFixed(int);            /*  function prototype             */

int  x1=0,  y1=0,                  /*  define endpoints to be (0, 0)  */
     x2=10, y2=30,                 /*  and (30, 0); control point to  */
     x3=30, y3=0;                  /*  be (10, 30)                    */



main(int argc, char *argv[])
{
     int N;
     
     if (argc != 2) {
          printf("Usage: %s <resolution>\n", argv[0]);
          exit(0);
     }

     N = atoi(argv[1]);
     if (N < 0 || N > 16) {
          puts("Keep the resolution between 0 and 16, ok?");
          exit(20);
     }
     
     doConicFixed(N);
}



void doConicFixed(int N)
/*
**        This routine has been optimized in several ways, some of them
**        subtle or confusing.  Better read the article before going over
**        this code.
*/
{
     long int px, py, rx, ry;
     register int t, c;
     register long int nx, ny;
     
     puts("\nFixed-Point:");
     
     px = x3+x1-(x2<<1);  py = y3+y1-(y2<<1);
     rx = (x2-x1)<<(N+1);  ry = (y2-y1)<<(N+1);
     nx = x1<<N;  ny = y1<<N;

     c = 1<<N;
     for (t = 0; t <= c; t++) {
          printf("XPos: %d  YPos: %d\n", nx>>(N<<1), ny>>(N<<1));
          
          nx += (rx+(t*2+1)*px); ny += (ry+(t*2+1)*py);
     }
}
