static unsigned long whirlygig_draw (Display *dpy, Window window, void *closure) { struct state *st = (struct state *) closure; int wcount; /* wcount is a counter incremented for every whirly take note of internal_time before you mess with it */ int change_time = 4000; if (st->explaining == 1) { XClearWindow (st->dpy, st->window); draw_explain_string(st, st->xmode, st->info->half_height-100, st->dpy, st->window, st->fgc); st->explaining++; return 3000000; } else if (st->explaining == 2) { XClearWindow (st->dpy, st->window); st->explaining = 0; } if (! strcmp (st->xmode_str, "change") && ! strcmp (st->ymode_str, "change")) { if ((st->current_time - st->start_time) > change_time) { st->start_time = st->current_time; st->xmode = 1 + (random() % 4); st->ymode = 1 + (random() % 4); } } else if (! strcmp (st->xmode_str, "change")) { if ((st->current_time - st->start_time) > change_time) { st->start_time = st->current_time; st->xmode = 1 + (random() % 4); } } else if (! strcmp (st->ymode_str, "change")) { if ((st->current_time - st->start_time) > change_time) { st->start_time = st->current_time; st->ymode = 1 + (random() % 3); printf("Changing ymode to %d\n", st->ymode); } } if (++st->current_color >= NCOLORS) st->current_color = 0; for (wcount = 0; wcount < st->info->whirlies; wcount++) { int lcount; /* lcount is a counter for every line -- take note of the offsets changing */ int internal_time = 0; int color_offset = (st->current_color + (st->info->color_modifier * wcount)) % NCOLORS; if (st->current_time != 0) /* I want the distance between whirlies to increase more each whirly */ internal_time = st->current_time + (10 * wcount) + (wcount * wcount); switch (st->xmode) { /* All these functions expect an int time, the struct info, a pointer to an array of positions, and the index that the the function will fill of the array */ case spin_mode: spin(st, internal_time, st->info, st->pos, 0); break; case funky_mode: funky(st, internal_time, st->info, st->pos, 0); break; case circle_mode: circle(st, internal_time, st->info, st->pos, 0); break; case linear_mode: linear(st, internal_time, st->info, st->pos, 0); break; case fun_mode: fun(st, internal_time, st->info, st->pos, 0); break; case test_mode: test(st, internal_time, st->info, st->pos, 0); break; case innie_mode: innie(st, internal_time, st->info, st->pos, 0, st->modifier); break; case lissajous_mode: lissajous(st, internal_time, st->info, st->pos, 0); break; default: spin(st, internal_time, st->info, st->pos, 0); break; } /* End of the switch for the x position*/ switch (st->ymode) { case spin_mode: spin(st, internal_time, st->info, st->pos, 1); break; case funky_mode: funky(st, internal_time, st->info, st->pos, 1); break; case circle_mode: circle(st, internal_time, st->info, st->pos, 1); break; case linear_mode: linear(st, internal_time, st->info, st->pos, 1); break; case fun_mode: fun(st, internal_time, st->info, st->pos, 1); break; case test_mode: test(st, internal_time, st->info, st->pos, 1); break; case innie_mode: innie(st, internal_time, st->info, st->pos, 1, st->modifier); break; case lissajous_mode: lissajous(st, internal_time, st->info, st->pos, 1); break; default: spin(st, internal_time, st->info, st->pos, 1); break; } /* End of the switch for the y position*/ for (lcount = 0; lcount < st->info->nlines; lcount++) { double arg = (double)((internal_time * st->info->offset_period) / 90.0); double line_offset = 20.0 * (double)lcount * sin(arg); int size; size = (int)(15.0 + 5.0 * sin((double)internal_time / 180.0)); /* First delete the old circle... */ if (!st->info->trail #ifdef HAVE_DOUBLE_BUFFER_EXTENSION && ( !st->dbeclear_p || !st->backb) #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ ) { XSetForeground(st->dpy, st->bgc, BlackPixel(st->dpy, st->screen)); XFillArc(st->dpy, st->b, st->bgc, st->last_x[wcount][lcount], st->last_y[wcount][lcount], st->last_size[wcount][lcount], st->last_size[wcount][lcount], START_ARC, END_ARC); } /* Now, lets draw in the new circle */ { /* Starting new scope for local x_pos and y_pos */ int xpos, ypos; if (st->wrap) { xpos = preen((int)(st->info->xoffset*line_offset)+st->pos[0], st->info->half_width * 2); ypos = preen((int)(st->info->yoffset*line_offset)+st->pos[1], st->info->half_height * 2); } else { xpos = (int)(st->info->xoffset*line_offset)+st->pos[0]; ypos = (int)(st->info->yoffset*line_offset)+st->pos[1]; } if (st->start_time == st->current_time) { /* smoothen should move from one mode to another prettily... */ /* Note: smoothen has not been modified to take the double buffering code into account, and needs to be hacked on before uncommenting. */ /* smoothen(xpos, last_x[wcount][lcount], ypos, last_y[wcount][lcount], size, color_offset, colors, dpy, window, bgc, screen, info); */ } st->last_x[wcount][lcount] = xpos; st->last_y[wcount][lcount] = ypos; st->last_size[wcount][lcount] = size; XSetForeground(st->dpy, st->bgc, st->colors[color_offset].pixel); XFillArc(st->dpy, st->b, st->bgc, xpos, ypos, size, size, START_ARC, END_ARC); } /* End of my temporary scope for xpos and ypos */ } /* End of the for each line in nlines */ } /* End of the for each whirly in whirlies */ #ifdef HAVE_DOUBLE_BUFFER_EXTENSION if (st->backb) { XdbeSwapInfo info[1]; info[0].swap_window = st->window; info[0].swap_action = (st->dbeclear_p ? XdbeBackground : XdbeUndefined); XdbeSwapBuffers (st->dpy, info, 1); } else #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ if (st->dbuf) { XCopyArea (st->dpy, st->b, st->window, st->bgc, 0, 0, st->xgwa.width, st->xgwa.height, 0, 0); } if (st->current_time == FULL_CYCLE) st->current_time = 1; else st->current_time = st->current_time + st->info->speed; return 10000; }
int main (int argc, char * const argv[]) { int opt; double xc, yc; double maxx, maxy; double height; double radius; while ((opt = getopt (argc, argv, "no:p:s:t:v:")) != -1) { switch (opt) { case 'n': case 'o': case 'p': case 's': case 't': case 'v': plotopt (opt, optarg); break; default: /* '?' */ fprintf (stderr, "Usage: %s [-p pen] [-s <size>] [-t title]\n", argv[0]); fprintf (stderr, " <size> ::= A1 | A2 | A3 | A4 | A5\n"); // exit (EXIT_FAILURE); } } plotbegin (0); getplotsize (&maxx, &maxy); xc = maxx / 2.0; yc = maxy / 2.0; height = maxy; /* Draw square border */ rectangle (xc - (height / 2.0), 0.0, xc + (height / 2.0), maxy); /* Draw central Lissajous curve */ radius = lissajous (xc, yc, 38.0 * 40.0, 3.0, 4.0, 0.0, 144); /* Plot ring of ellipses around Lissajous */ circle (xc, yc, radius); radius = ellipsering (xc, yc, radius + (1.0 * 40.0), radius + (9.0 * 40.0), 3); circle (xc, yc, radius + (1.0 * 40.0)); circle (xc, yc, radius + (51.0 * 40.0)); /* Plot radial lines */ radius = radials (xc, yc, radius + (1.0 * 40.0), 5.0 * 40.0, 63); /* Plot two rings of zigzags */ radius = zigzagring (xc, yc, radius, radius + (20.0 * 40.0), 63, 4, 0); radius = zigzagring (xc, yc, radius, radius + (25.0 * 40.0), 63, 8, 1); /* Plot ring of boxes within boxes */ ringoboxes (xc, yc, radius + (1.0 * 40.0), 48, 3); radius = ringofcircles (xc, yc, radius + (12.0 * 40.0), 96); radius = sqwavering (xc, yc, radius + (1.0 * 40.0), 10.0 * 40.0, 24); radius = sqwavering (xc, yc, radius + (1.0 * 40.0), 10.0 * 40.0, 25); plotend (); return (0); }