static void randomBlots (struct nerverotstate *st) { int which = RAND_FLOAT_01 * 11; freeBlots (st); setupBlots(st,which); st->cur_num=which; }
/* set up the system */ static void setup (struct state *st) { XWindowAttributes xgwa; XGetWindowAttributes (st->dpy, st->window, &xgwa); st->windowWidth = xgwa.width; st->windowHeight = xgwa.height; st->centerX = st->windowWidth / 2; st->centerY = st->windowHeight / 2; st->baseScale = (xgwa.height < xgwa.width) ? xgwa.height : xgwa.width; if (st->doubleBuffer) { st->drawable = XCreatePixmap (st->dpy, st->window, xgwa.width, xgwa.height, xgwa.depth); } else { st->drawable = st->window; } setupColormap (st, &xgwa); setupBlots (st); setupSegs (st); /* set up the initial rotation, scale, and light values as random, but * with the targets equal to where it is */ st->xRot = st->xRotTarget = RAND_FLOAT_01 * M_PI; st->yRot = st->yRotTarget = RAND_FLOAT_01 * M_PI; st->zRot = st->zRotTarget = RAND_FLOAT_01 * M_PI; st->curScale = st->scaleTarget = RAND_FLOAT_01 * (st->maxScale - st->minScale) + st->minScale; st->lightX = st->lightXTarget = RAND_FLOAT_PM1; st->lightY = st->lightYTarget = RAND_FLOAT_PM1; st->lightZ = st->lightZTarget = RAND_FLOAT_PM1; st->itersTillNext = RAND_FLOAT_01 * st->maxIters; }
static void commandBlots (struct nerverotstate *st) { freeBlots (st); setupBlots(st, st->please_num); st->cur_num=st->please_num; }
/* update blots, adjusting the offsets and rotation factors. */ static void updateWithFeeling (struct state *st) { int n, i, j; /* pick a new model if the time is right */ st->itersTillNext--; if (st->itersTillNext < 0) { st->itersTillNext = RAND_FLOAT_01 * st->maxIters; setupBlots (st); setupSegs (st); renderSegs (st); } /* update the rotation factors by moving them a bit toward the targets */ st->xRot = st->xRot + (st->xRotTarget - st->xRot) * st->iterAmt; st->yRot = st->yRot + (st->yRotTarget - st->yRot) * st->iterAmt; st->zRot = st->zRot + (st->zRotTarget - st->zRot) * st->iterAmt; /* similarly the scale factor */ st->curScale = st->curScale + (st->scaleTarget - st->curScale) * st->iterAmt; /* and similarly the light position */ st->lightX = st->lightX + (st->lightXTarget - st->lightX) * st->iterAmt; st->lightY = st->lightY + (st->lightYTarget - st->lightY) * st->iterAmt; st->lightZ = st->lightZ + (st->lightZTarget - st->lightZ) * st->iterAmt; /* for each blot... */ for (n = 0; n < st->blotCount; n++) { /* add a bit of random jitter to xoff/yoff */ for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { FLOAT newOff; newOff = st->blots[n].xoff[i][j] + RAND_FLOAT_PM1 * st->nervousness; if (newOff < -1) newOff = -(newOff + 1) - 1; else if (newOff > 1) newOff = -(newOff - 1) + 1; st->blots[n].xoff[i][j] = newOff; newOff = st->blots[n].yoff[i][j] + RAND_FLOAT_PM1 * st->nervousness; if (newOff < -1) newOff = -(newOff + 1) - 1; else if (newOff > 1) newOff = -(newOff - 1) + 1; st->blots[n].yoff[i][j] = newOff; } } } /* depending on random chance, update one or more factors */ if (RAND_FLOAT_01 <= st->eventChance) { int which = RAND_FLOAT_01 * 14; switch (which) { case 0: { st->xRotTarget = RAND_FLOAT_PM1 * M_PI * 2; break; } case 1: { st->yRotTarget = RAND_FLOAT_PM1 * M_PI * 2; break; } case 2: { st->zRotTarget = RAND_FLOAT_PM1 * M_PI * 2; break; } case 3: { st->xRotTarget = RAND_FLOAT_PM1 * M_PI * 2; st->yRotTarget = RAND_FLOAT_PM1 * M_PI * 2; break; } case 4: { st->xRotTarget = RAND_FLOAT_PM1 * M_PI * 2; st->zRotTarget = RAND_FLOAT_PM1 * M_PI * 2; break; } case 5: { st->yRotTarget = RAND_FLOAT_PM1 * M_PI * 2; st->zRotTarget = RAND_FLOAT_PM1 * M_PI * 2; break; } case 6: { st->xRotTarget = RAND_FLOAT_PM1 * M_PI * 2; st->yRotTarget = RAND_FLOAT_PM1 * M_PI * 2; st->zRotTarget = RAND_FLOAT_PM1 * M_PI * 2; break; } case 7: { st->centerXOff = RAND_FLOAT_PM1 * st->maxRadius; break; } case 8: { st->centerYOff = RAND_FLOAT_PM1 * st->maxRadius; break; } case 9: { st->centerXOff = RAND_FLOAT_PM1 * st->maxRadius; st->centerYOff = RAND_FLOAT_PM1 * st->maxRadius; break; } case 10: { st->scaleTarget = RAND_FLOAT_01 * (st->maxScale - st->minScale) + st->minScale; break; } case 11: { st->curScale = RAND_FLOAT_01 * (st->maxScale - st->minScale) + st->minScale; break; } case 12: { st->lightX = RAND_FLOAT_PM1; st->lightY = RAND_FLOAT_PM1; st->lightZ = RAND_FLOAT_PM1; break; } case 13: { st->lightXTarget = RAND_FLOAT_PM1; st->lightYTarget = RAND_FLOAT_PM1; st->lightZTarget = RAND_FLOAT_PM1; break; } } } }
/* set up the blots to be two of the other choices, placed next to * each other */ static void setupBlotsDuo (struct state *st) { int origRequest = st->requestedBlotCount; FLOAT tx, ty, tz, radius; Blot *blots1, *blots2; int count1, count2; int n; if (st->requestedBlotCount < 15) { /* special case bottom-out */ setupBlotsSphere (st); return; } tx = RAND_FLOAT_PM1; ty = RAND_FLOAT_PM1; tz = RAND_FLOAT_PM1; radius = sqrt (tx * tx + ty * ty + tz * tz); tx /= radius; ty /= radius; tz /= radius; /* recursive call to setup set 1 */ st->requestedBlotCount = origRequest / 2; setupBlots (st); if (st->blotCount >= origRequest) { /* return immediately if this satisfies the original count request */ st->requestedBlotCount = origRequest; return; } blots1 = st->blots; count1 = st->blotCount; st->blots = NULL; st->blotCount = 0; /* translate to new position */ for (n = 0; n < count1; n++) { blots1[n].x += tx; blots1[n].y += ty; blots1[n].z += tz; } /* recursive call to setup set 2 */ st->requestedBlotCount = origRequest - count1; setupBlots (st); blots2 = st->blots; count2 = st->blotCount; /* translate to new position */ for (n = 0; n < count2; n++) { blots2[n].x -= tx; blots2[n].y -= ty; blots2[n].z -= tz; } /* combine the two arrays */ st->blotCount = count1 + count2; st->blots = calloc (sizeof (Blot), st->blotCount); memcpy (&st->blots[0], blots1, sizeof (Blot) * count1); memcpy (&st->blots[count1], blots2, sizeof (Blot) * count2); free (blots1); free (blots2); scaleBlotsToRadius1 (st); randomlyReorderBlots (st); /* restore the original requested count, for future iterations */ st->requestedBlotCount = origRequest; }