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

     This program plots a parabola using two endpoints and one control
     point.
     
     Lc -Lm Listing2 to compile.
*/



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

void doConicFloat(int);            /*  function prototypes            */
void doConicFixed(int);            

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);
     }
     
     doConicFloat(N);
     doConicFixed(N);
}



void doConicFloat(int N)
/*
**        This routine will use regular floating point math to plot the
**        parabola.  Watch yourself, this could get ugly!
*/
{
     float t, xp, yp, px, py, rx, ry, sx, sy;
     
     puts("\nFloating Point:");
     
     px = (float) (x3+x1-2*x2);  py = (float) (y3+y1-2*y2);
     rx = (float) (2*(x2-x1));  ry = (float) (2*(y2-y1));
     sx = (float) x1;  sy = (float) y1;

     for (t = 0.0; t <= 1.0; t += 1.0/(1<<N)) {
          xp = px*t*t + rx*t + sx;
          yp = py*t*t + ry*t + sy;
          
          printf("XPos: %f  YPos: %f\n", xp, yp);
     }
}



void doConicFixed(int N)
/*
**        This version of the routine uses fixed-point math, so the math
**        library doesn't need to be linked to the program.  The actual
**        statements look pretty grisly, but the shifts are very simple
**        for the computer, so they take very little time.
*/
{
     long int t, px, py, rx, ry, sx, sy, xp, yp;
     
     puts("\nFixed-Point:");
     
     px = (x3+x1-(x2<<1)<<N);  py = (y3+y1-(y2<<1)<<N);
     rx = (x2-x1)<<(N+1);  ry = (y2-y1)<<(N+1);
     sx = x1<<(N<<1);  sy = y1<<(N<<1);
     
     for (t = 0; t <= (1<<N); t++) {
          xp = ((((px*t)>>N)*t)>>N) + ((rx*t)>>N) + sx;
          yp = ((((py*t)>>N)*t)>>N) + ((ry*t)>>N) + sy;

          printf("XPos: %d  YPos: %d\n", xp>>N, yp>>N);
     }
}
