typedef int xT; /* x coordinate */ typedef int yT; /* y coordinate */ #define pmWd ((xT)2000) #define pmHg ((yT)2000) #define pmX0 ((xT)pmWd/2) #define pmY0 ((yT)pmHg/2) static Pixmap pm; static GC gcBlack; static GC gcWhite; static GC gcGrey; static inline void rotatePoint( xT *xd, yT *yd, double al, xT xs, yT ys) { double const s = sin(al); double const c = cos(al); *xd = (xT)(xs * c - ys * s); *yd = (yT)(xs * s + ys * c); } static inline void doPinnaCircles(void) { /* circle radiuses */ double const rMin = 300.0; double const rInc = 200.0; double const rMax = 950; double r; /* square side length */ double const S = 100.0; double const s = S * 0.7; double alInc = 2 * M_PI * 15 / 360; int i; XFillRectangle(dpy,pm,gcGrey,0,0,pmWd,pmHg); for (r=rMin; r <=rMax; r+=rInc) { /* currect radius such that an integer multiple of squares fits */ double const p = 2.0 * M_PI * r; int const cnt = floor(p/S/2.0) * 2; double const pc = cnt * S; xT const rc = (xT)(pc / 2.0 / M_PI); alInc = - alInc; for (i=0; i<cnt; i+=1) { /* angle to midpoint of i.th square */ double const Al = 2.0 * M_PI * i / cnt; /* mid point of i.th square */ xT const xx = pmX0 + (xT)(sin(Al) * rc); yT const yy = pmY0 + (yT)(cos(Al) * rc); /* edge angle of i.th square */ double const al = Al + alInc; xT xa, xb, xc, xd; yT ya, yb, yc, yd; rotatePoint(&xa,&ya,-al,+s/2.0,+s/2.0); rotatePoint(&xb,&yb,-al,-s/2.0,+s/2.0); rotatePoint(&xc,&yc,-al,-s/2.0,-s/2.0); rotatePoint(&xd,&yd,-al,+s/2.0,-s/2.0); GC const gc = (i % 2 == 0 ? gcWhite : gcBlack); XDrawLine(dpy,pm,gc,xx+xa,yy+ya,xx+xb,yy+yb); XDrawLine(dpy,pm,gc,xx+xb,yy+yb,xx+xc,yy+yc); XDrawLine(dpy,pm,gc,xx+xc,yy+yc,xx+xd,yy+yd); XDrawLine(dpy,pm,gc,xx+xd,yy+yd,xx+xa,yy+ya); } } XImage * const im = XGetImage(dpy,pm,0,0,pmWd,pmHg,-1,ZPixmap); writePpmFile(stdout,"",im); /* library function to print XImage to FILE*, code not included here */ } /* main() initializes Pixmap pm, and GC gcBlack, gcWhite, gcGrey using library functions, then calls doPinnaCircles(), code not included here */