-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmakeCircles.c
103 lines (81 loc) · 3.79 KB
/
makeCircles.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
///////////////////////////////////////////
// build table chordVec[d] of circle 1/2 widths at distances d from center
// Code adapted from RobG's EduKit
// Uses Bresenham's circle algorithm
// Modified from RobG's EduKit by Eric Freudenthal and David Pruitt 2016
///////////////////////////////////////////
void computeChordVec(unsigned char chordVec[], unsigned char radius)
{
int col = radius, row = 0; /* first coordinate (radius, 0) */
// key insight: (col+1)**2 - col**2 = 2col+1
int dColSquared = 2 * col - 1; // change in col**2 for a unit decrease in col
int dRowSquared = 1; // change in row**2 for a unit increase in row
int radiusSqErr = 0; /* (radius, 0) is on the circle */
int colPrev = 0; /* initially bogus value to force first entry*/
while (col >= row) { /* only sweep first octant */
chordVec[row] = col; /* row always changes in first octant */
/* mirror into 2nd octant */
if (colPrev != col) /* col sometimes repeats in first octant */
chordVec[col] = row; /* only save first (max) col for row */
colPrev = col;
row++; /* move vertically (slope <= -1 for first octant) */
radiusSqErr += dRowSquared; /* current radiusSqErr */
dRowSquared += 2; /* next dRowSquared */
if ((2 * radiusSqErr) > dColSquared) { /* only update col if error reduced */
col--; /* move horizontally */
radiusSqErr -= dColSquared; /* current radiusSqErr */
dColSquared -= 2; /* next dColSquared */
}
}
}
#include "stdio.h"
#include "assert.h"
// Generate circles as source files
// (c) Eric Freudenthal, 2016
int main()
{
int radius;
char chordVec[151];
FILE *circleIncludeFile = fopen("abCircle_decls.h", "w");
FILE *chordIncludeFile = fopen("chordVec.h", "w");
assert(chordIncludeFile); assert(circleIncludeFile);
fprintf(circleIncludeFile, "// Automatically generated by makeCircles. (c) Eric Freudenthal, 2016\n");
fprintf(circleIncludeFile, "#ifndef abCircle_decls_included\n#define abCircle_decls_included\n\n");
fprintf(chordIncludeFile, "// Automatically generated by makeCircles. (c) Eric Freudenthal, 2016\n");
fprintf(chordIncludeFile, "#ifndef chordVec_included\n#define chordVec_included\n\n");
for (radius = 2; radius <= 150; radius++) {
char filename[100];
unsigned char chordIndex;
computeChordVec(chordVec, radius);
{ /* chordVecN.c */
sprintf(filename, "circles/chordVec%d.c", radius);
FILE *fp = fopen(filename, "w");
assert(fp);
fprintf(fp, "// Automatically generated by makeCircles. (c) Eric Freudenthal, 2016\n");
fprintf(fp, "#include \"chordVec.h\"\n\n");
fprintf(fp, "const unsigned char chordVec%d[%d] = {\n", radius, radius+1);
for (chordIndex = 0; chordIndex <= radius; chordIndex ++)
fprintf(fp, " %d, // dist along axis = %d\n", chordVec[chordIndex], chordIndex);
fprintf(fp, "};\n\n");
fclose(fp);
} { /* abCircleN.c */
sprintf(filename, "circles/abCircle%d.c", radius);
FILE *fp = fopen(filename, "w");
assert(fp);
fprintf(fp, "// Automatically generated by makeCircles. (c) Eric Freudenthal, 2016\n");
fprintf(fp, "#include \"abCircle.h\"\n\n");
fprintf(fp, "#include \"chordVec.h\"\n\n");
fprintf(fp, "const AbCircle circle%d = {" , radius);
fprintf(fp, " abCircleGetBounds, abCircleCheck, chordVec%d, %d", radius, radius);
fprintf(fp, "};\n");
fclose(fp);
}
/* includes */
fprintf(chordIncludeFile, "extern const unsigned char chordVec%d[%d];\n", radius, radius+1);
fprintf(circleIncludeFile, "extern const AbCircle circle%d;\n" , radius);
}
fprintf(circleIncludeFile, "\n#endif // included \n");
fprintf(chordIncludeFile, "\n#endif // included \n");
fclose(chordIncludeFile);
fclose(circleIncludeFile);
}