27 #define _USE_MATH_DEFINES 33 const float PI = 3.14159265358979323846f;
38 #pragma region helpers 50 bool OpenSVG(FILE*& output,
const std::string& fname,
size_t w,
size_t h){
51 const std::string s = fname +
".svg";
53 #ifdef _MSC_VER //Visual Studio 54 fopen_s(&output, s.c_str(),
"wt");
56 output = fopen(s.c_str(),
"wt");
59 if(output !=
nullptr){
60 fprintf(output,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
62 fprintf(output,
"<svg width=\"%lu\" height=\"%lu\" ", w, w);
63 fprintf(output,
"viewBox=\"0 0 %lu %lu\" ", w, w);
64 fprintf(output,
"xmlns=\"http://www.w3.org/2000/svg\">\n");
66 fprintf(output,
"<!-- Created by Ian Parberry -->\n");
80 if(output !=
nullptr){
81 fprintf(output,
"</svg>\n");
87 #pragma endregion helpers 92 #pragma region Illusion1 114 size_t sw,
bool parity)
117 const size_t n = (size_t)ceil((2*
PI*r)/(1.5f*sw)) & 0xFFFFFFFE;
119 const float dtheta = 2*
PI/n;
122 for(
size_t i=0; i<n; i++){
123 const float x = r*cosf(theta);
124 const float y = r*sinf(theta);
125 const float phi = 12*(parity? 1: -1) + 180*theta/
PI;
127 fprintf(output,
"<g transform=\"translate(%0.1f %0.1f)", x + sw/2, y + sw/2);
128 fprintf(output,
"rotate(%0.1f %lu %lu)\">", phi, cx, cy);
129 fprintf(output,
"<rect width=\"%lu\" height=\"%lu\" ", sw, sw);
130 if(i&1)fprintf(output,
"class=\"b\"");
131 else fprintf(output,
"class=\"w\"");
132 fprintf(output,
"/>");
133 fprintf(output,
"</g>\n");
160 float r0,
float dr,
size_t sw,
const char dark[],
const char light[],
163 const size_t cx = w/2 - sw/2;
164 const size_t cy = cx;
165 FILE* output =
nullptr;
167 if(
OpenSVG(output, fname, w, w)){
169 fprintf(output,
"<style>");
170 fprintf(output,
"rect{fill:none;stroke-width:3}");
171 fprintf(output,
"rect.b{x:%lu;y:%lu;stroke:%s;}", cx, cy, dark);
172 fprintf(output,
"rect.w{x:%lu;y:%lu;stroke:%s;}", cx, cy, light);
173 fprintf(output,
"</style>\n");
176 fprintf(output,
"<rect width=\"%lu\" height=\"%lu\" ", w, w);
177 fprintf(output,
"style=\"fill:%s\"/>\n", bgclr);
179 for(
size_t i=0; i<n; i++)
186 #pragma endregion Illusion1 191 #pragma region Illusion2 205 const size_t j = i%4;
206 if((parity && j == 0) || (!parity && j == 2))
207 fprintf(output,
"class=\"b\"");
208 else if((parity && j == 2) || (!parity && j == 0))
209 fprintf(output,
"class=\"w\"");
233 float r0,
float r1,
size_t n,
float theta,
float dtheta,
bool parity,
236 for(
size_t i=0; i<n; i++){
237 const float x = r*cosf(theta);
238 const float y = r*sinf(theta);
239 const float phi = 90 + 180*theta/
PI;
241 fprintf(output,
"<g transform=\"translate(%0.1f %0.1f)", x, y);
242 fprintf(output,
"rotate(%0.1f %lu %lu)\">", phi, cx, cy);
243 fprintf(output,
"<ellipse cx=\"400\" cy=\"400\" ");
244 fprintf(output,
"rx=\"%0.1f\" ry=\"%0.1f\" ", r0, r1);
248 fprintf(output,
"/>");
249 fprintf(output,
"</g>\n");
252 if(i == flip)parity = !parity;
294 float r0,
float r1,
size_t n,
bool flip=
false)
296 const float dtheta =
PI/n;
297 float theta = (flip?
PI: -
PI)/2;
302 theta + dtheta, dtheta,
true, n/2 - 1);
304 theta + dtheta, dtheta,
false, n/2 - 2);
328 float r,
float r0,
float r1,
const char dark[],
const char light[],
331 const size_t cx = w/2;
332 const size_t cy = cx;
333 FILE* output =
nullptr;
335 if(
OpenSVG(output, fname, w, w)){
337 fprintf(output,
"<style>");
338 fprintf(output,
"ellipse{fill:none;stroke-width:3}");
339 fprintf(output,
"ellipse.b{cx:%lu;cy:%lu;stroke:none;fill:%s;}",
341 fprintf(output,
"ellipse.w{cx:%lu;cy:%lu;stroke:none;fill:%s;}",
343 fprintf(output,
"</style>\n");
346 fprintf(output,
"<rect width=\"%lu\" height=\"%lu\" ", w, w);
347 fprintf(output,
"style=\"fill:%s\"/>\n", bgclr);
356 #pragma region Illusion2 369 "black",
"white",
"gray");
371 "blue",
"yellow",
"forestgreen");
373 "black",
"white",
"gray");
375 "blue",
"yellow",
"forestgreen");
void DrawCircleOfSquares(FILE *output, size_t cx, size_t cy, float r, size_t sw, bool parity)
Draw a circle of squares to a file in SVG format.
void DrawTripleCircle(FILE *output, size_t cx, size_t cy, float r, float r0, float r1, size_t n, bool flip=false)
Draw 3 concentric circles of ellipses to a file in SVG format.
void OpticalIllusion1(const std::string &fname, size_t w, size_t n, float r0, float dr, size_t sw, const char dark[], const char light[], const char bgclr[])
Draw the first optical illusion to a file in SVG format.
void OpticalIllusion2(const std::string &fname, size_t w, size_t n, float r, float r0, float r1, const char dark[], const char light[], const char bgclr[])
Draw the second optical illusion to a file in SVG format.
bool OpenSVG(FILE *&output, const std::string &fname, size_t w, size_t h)
Open SVG file.
void SelectEllipseColor(FILE *output, size_t i, bool parity)
Select ellipse color based on index.
void DrawCircleOfEllipses(FILE *output, size_t cx, size_t cy, float r, float r0, float r1, size_t n, float theta, float dtheta, bool parity, size_t flip=999999)
Draw circle of ellipses to a file in SVG format.
void CloseSVG(FILE *&output)
Close SVG file.