#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
// Max Number of steps
#define maxs 10
int main(void)
{
int i, w;
int steps = 9; // Number of steps
int xbits = 8;
int nkbits_w = 3; // bits after the decimal point for the angle
int nkbits_r = 2; // bits after the decimal point for the radius, x, y
int x, y, xnew, ynew;
int ati[maxs]; // the angle steps as integers
float const pi = 3.1415926;
float tn, tw, min, max;
float at[maxs]; // the angle steps
float r[maxs]; // radius factor for different steps
int maxy, miny, maxx, minx;
tn = 2;
tw = 0;
// Generate the arctan values (angles) for the steps
for (i=0; i<maxs; i++)
{
tn = tn / 2;
if (i > 0) r[i] = r[i-1] * (1 + tn*tn);
else r[i] = 1 + tn*tn;
at[i] = atan(tn)*180/pi;
ati[i] = (1 << nkbits_w)*at[i]+0.5;
tw = tw + at[i];
cout << "# " << dec << i << " " << setw(10) << fixed << setprecision(3) << at[i] << " "
<< " " << tw << " " << sqrt(r[i]) << dec << " " << ati[i] << endl;
}
cout << "# Radius = " << setprecision(3) << sqrt(r[steps-1]) << endl;
min = 0;
max = 0;
miny = 0;
maxy = 0;
minx = 0;
maxx = 0;
// Calculate the deviations for angles from 0 to 90 degree
for (w = 0; w < 91; w++)
{
tw = (1 << nkbits_w)*w;
x = ((1 << (xbits+nkbits_r)) - 1)/sqrt(r[steps-1])+0.5;
x = 620;
if (w == 0) cout << "# x = " << x << endl;
y = 0;
for (i = 0; i < steps; i++)
{
if (tw > 0)
{
tw = tw - ati[i];
xnew = x - y/(1 << i);
ynew = y + x/(1 << i);
}
else
{
tw = tw + ati[i];
xnew = x + y/(1 << i);
ynew = y - x/(1 << i);
}
x = xnew;
y = ynew;
if (y > maxy) maxy = y;
if (y < miny) miny = y;
if (x > maxx) maxx = x;
if (x < minx) minx = x;
// dump all steps for one angle (here for w=1)
if (w == 1) cout << "# \t" << dec << setw(6) << i << " " << setw(9) << setprecision(2) << fixed << tw
<< dec << " " << setw(7) << xnew << " " << setw(7) << ynew << endl;
}
//calculate the exact sin
ynew = ((1 << xbits) - 1)*sin(w*pi/180);
// dump the resulst for angle w
cout << dec << setw(5) << w << " " << setprecision(2) << fixed << setw(5) << tw << " " <<
dec << fixed << setw(5) << (x >> nkbits_r) << " " <<
fixed << setw(5) << (y >> nkbits_r) << " " <<
fixed << setw(5) << ynew << endl;
if (tw > max) max = tw; // max rest angle
if (tw < min) min = tw;
}
cout << "# min " << setw(5) << setprecision(2) << fixed << min << endl;
cout << "# max " << setw(5) << setprecision(2) << fixed << max << endl;
cout << "# maxy " << maxy << " miny " << miny << endl;
cout << "# maxx " << maxx << " minx " << minx << endl;
}