#include #include #include #include #define RAD (PI * 2) #define DEG (PI / 180.0) Image *bg,*fg; int frametime; double spr; int wings; double wingrads; double turns; vlong starttime; void usage(void) { fprint(2,"usage: %s [-f framerate] [-r rpm] [-w wings] [-t turns]\n", argv0); exits("usage"); } Point SPt(int x, int y) { return addpt(Pt(x, y), screen->r.min); } Rectangle SRect(int x0, int y0, int x1, int y1) { return rectaddpt(Rect(x0, y0, x1, y1), screen->r.min); } Point imagecenter(Image* img) { return divpt(addpt(img->r.min, img->r.max), 2); } double imageradius(Image* img) { Point dims; dims = divpt(subpt(img->r.max, img->r.min), 2); return 1.4 + sqrt(dims.x*dims.x + dims.y*dims.y); } Point vecpt(double radians, double radius) { double x,y; x = sin(radians) * radius; y = cos(radians) * radius; return Pt(x + 1, y + 1); } void drawframe(double ts) { double radians, radius, spiralrads, spiralx, spiraly; uint numpoints, iradius; int i, j, k; Point center; Point *wingpoints; radians = fmod(ts / spr, spr) * RAD; radius = imageradius(screen) * 1.4; iradius = radius + 1; center = imagecenter(screen); numpoints = iradius + iradius; wingpoints = malloc(sizeof(Point) * numpoints); wingpoints[0] = center; wingpoints[numpoints - 1] = center; draw(screen, screen->r, bg, nil, SPt(0, 0)); for(i = 0; i < wings; i++){ for(j = 0; j < iradius; j++){ spiralrads = (double)j / (double)iradius * turns * RAD; spiralx = sin(radians + spiralrads) * j; spiraly = cos(radians + spiralrads) * j; k = j; wingpoints[k] = addpt(center, Pt(spiralx, spiraly)); } radians += wingrads; for(j = 0; j < iradius; j++){ spiralrads = (double)(iradius - j) / (double)iradius * turns * RAD; spiralx = sin(radians + spiralrads) * (iradius - j); spiraly = cos(radians + spiralrads) * (iradius - j); // weird syntax issue k = j + iradius; wingpoints[k] = addpt(center, Pt(spiralx, spiraly)); } fillpoly(screen, wingpoints, numpoints, ~0, fg, Pt(0,0)); radians += wingrads; } free(wingpoints); } double ftime(void) { return ((double)(nsec() - starttime)) / 1000000000.0; } void eresized(int new) { if(new && getwindow(display, Refnone) < 0) fprint(2,"can't reattach to window\n"); drawframe(ftime()); } void main(int argc, char* argv[]) { int timer,etype; Event e; frametime = 1.0 / 30.0 * 1000; wings = 3; spr = 2; turns = 1.0 / 6.0; ARGBEGIN{ case 'f': frametime = 1.0 / atof(EARGF(usage())) * 1000; break; case 'r': spr = 1.0 / (atof(EARGF(usage())) / 60.0); break; case 'w': wings = atoi(EARGF(usage())); break; case 't': turns = atof(EARGF(usage())); break; default: usage(); }ARGEND fprint(2,"turns: %f\n", turns); if(wings < 1) wings = 1; wingrads = PI / (double) wings; if(initdraw(nil, nil, "spiral") < 0) sysfatal("initdraw: %r"); fg = allocimage(display, Rect(0,0, 1,1), GREY1, 1, DBlack); if(!fg) sysfatal("couldn't allocimage!"); bg = allocimage(display, Rect(0,0, 1,1), GREY1, 1, DWhite); if(!bg) sysfatal("couldn't allocimage!"); starttime = nsec(); einit(Emouse); timer = etimer(0, frametime); for(;;){ etype = event(&e); if (etype == timer) drawframe(ftime()); } }