X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fnerverot.c;h=3c058c6dd806d8020ba3ec8247386df7a9c68d5b;hp=16bd267040e822e70fcb58088f1cedab6b3f7451;hb=8eb2873d7054e705c4e83f22d18c40946a9e2529;hpb=a1d41b2aa6e18bf9a49b914a99dda8232c5d7762 diff --git a/hacks/nerverot.c b/hacks/nerverot.c index 16bd2670..3c058c6d 100644 --- a/hacks/nerverot.c +++ b/hacks/nerverot.c @@ -1,4 +1,4 @@ -/* nerverot, nervous rotation of random thingies, v1.3 +/* nerverot, nervous rotation of random thingies, v1.4 * by Dan Bornstein, danfuzz@milk.com * Copyright (c) 2000-2001 Dan Bornstein. All rights reserved. * @@ -162,7 +162,7 @@ static int itersTillNext; /* - * blot setup stuff + * generic blot setup and manipulation */ /* initialize a blot with the given coordinates and random display offsets */ @@ -231,6 +231,58 @@ static void randomlyReorderBlots (void) } } +/* randomly rotate the blots around the origin */ +static void randomlyRotateBlots (void) +{ + int n; + + /* random amounts to rotate about each axis */ + FLOAT xRot = RAND_FLOAT_PM1 * M_PI; + FLOAT yRot = RAND_FLOAT_PM1 * M_PI; + FLOAT zRot = RAND_FLOAT_PM1 * M_PI; + + /* rotation factors */ + FLOAT sinX = sin (xRot); + FLOAT cosX = cos (xRot); + FLOAT sinY = sin (yRot); + FLOAT cosY = cos (yRot); + FLOAT sinZ = sin (zRot); + FLOAT cosZ = cos (zRot); + + for (n = 0; n < blotCount; n++) + { + FLOAT x1 = blots[n].x; + FLOAT y1 = blots[n].y; + FLOAT z1 = blots[n].z; + FLOAT x2, y2, z2; + + /* rotate on z axis */ + x2 = x1 * cosZ - y1 * sinZ; + y2 = x1 * sinZ + y1 * cosZ; + z2 = z1; + + /* rotate on x axis */ + y1 = y2 * cosX - z2 * sinX; + z1 = y2 * sinX + z2 * cosX; + x1 = x2; + + /* rotate on y axis */ + z2 = z1 * cosY - x1 * sinY; + x2 = z1 * sinY + x1 * cosY; + y2 = y1; + + blots[n].x = x2; + blots[n].y = y2; + blots[n].z = z2; + } +} + + + +/* + * blot configurations + */ + /* set up the initial array of blots to be a at the edge of a sphere */ static void setupBlotsSphere (void) { @@ -266,8 +318,6 @@ static void setupBlotsSphere (void) } } - - /* set up the initial array of blots to be a simple cube */ static void setupBlotsCube (void) { @@ -322,20 +372,26 @@ static void setupBlotsCube (void) scaleBlotsToRadius1 (); randomlyReorderBlots (); + randomlyRotateBlots (); } - - /* set up the initial array of blots to be a cylinder */ static void setupBlotsCylinder (void) { int i, j, n; - - /* derive blotsPerEdge from blotCount, but then do the reverse - * since roundoff may have changed blotCount */ - int blotsPerEdge = requestedBlotCount / 32; FLOAT distBetween; + /* derive blotsPerEdge and blotsPerRing from blotCount, but then do the + * reverse since roundoff may have changed blotCount */ + FLOAT reqRoot = sqrt ((FLOAT) requestedBlotCount); + int blotsPerRing = ceil (RAND_FLOAT_PM1 * reqRoot) / 2 + reqRoot; + int blotsPerEdge = requestedBlotCount / blotsPerRing; + + if (blotsPerRing < 2) + { + blotsPerRing = 2; + } + if (blotsPerEdge < 2) { blotsPerEdge = 2; @@ -343,15 +399,15 @@ static void setupBlotsCylinder (void) distBetween = 2.0 / (blotsPerEdge - 1); - blotCount = blotsPerEdge * 32; + blotCount = blotsPerEdge * blotsPerRing; blots = calloc (sizeof (Blot), blotCount); n = 0; /* define the edges */ - for (i = 0; i < 32; i++) + for (i = 0; i < blotsPerRing; i++) { - FLOAT x = sin (2 * M_PI / 32 * i); - FLOAT y = cos (2 * M_PI / 32 * i); + FLOAT x = sin (2 * M_PI / blotsPerRing * i); + FLOAT y = cos (2 * M_PI / blotsPerRing * i); for (j = 0; j < blotsPerEdge; j++) { initBlot (&blots[n], x, y, j * distBetween - 1); @@ -361,10 +417,9 @@ static void setupBlotsCylinder (void) scaleBlotsToRadius1 (); randomlyReorderBlots (); + randomlyRotateBlots (); } - - /* set up the initial array of blots to be a squiggle */ static void setupBlotsSquiggle (void) { @@ -426,8 +481,6 @@ static void setupBlotsSquiggle (void) randomlyReorderBlots (); } - - /* set up the initial array of blots to be near the corners of a * cube, distributed slightly */ static void setupBlotsCubeCorners (void) @@ -451,10 +504,9 @@ static void setupBlotsCubeCorners (void) } scaleBlotsToRadius1 (); + randomlyRotateBlots (); } - - /* set up the initial array of blots to be randomly distributed * on the surface of a tetrahedron */ static void setupBlotsTetrahedron (void) @@ -511,9 +563,78 @@ static void setupBlotsTetrahedron (void) initBlot (&blots[n + c], x, y, z); } } + + randomlyRotateBlots (); +} + +/* set up the initial array of blots to be an almost-evenly-distributed + * square sheet */ +static void setupBlotsSheet (void) +{ + int x, y; + + int blotsPerDimension = floor (sqrt (requestedBlotCount)); + FLOAT spaceBetween; + + if (blotsPerDimension < 2) + { + blotsPerDimension = 2; + } + + spaceBetween = 2.0 / (blotsPerDimension - 1); + + blotCount = blotsPerDimension * blotsPerDimension; + blots = calloc (sizeof (Blot), blotCount); + + for (x = 0; x < blotsPerDimension; x++) + { + for (y = 0; y < blotsPerDimension; y++) + { + FLOAT x1 = x * spaceBetween - 1.0; + FLOAT y1 = y * spaceBetween - 1.0; + FLOAT z1 = 0.0; + + x1 += RAND_FLOAT_PM1 * spaceBetween / 3; + y1 += RAND_FLOAT_PM1 * spaceBetween / 3; + z1 += RAND_FLOAT_PM1 * spaceBetween / 2; + + initBlot (&blots[x + y * blotsPerDimension], x1, y1, z1); + } + } + + scaleBlotsToRadius1 (); + randomlyReorderBlots (); + randomlyRotateBlots (); } +/* set up the initial array of blots to be a swirlycone */ +static void setupBlotsSwirlyCone (void) +{ + FLOAT radSpace = 1.0 / (requestedBlotCount - 1); + FLOAT zSpace = radSpace * 2; + FLOAT rotAmt = RAND_FLOAT_PM1 * M_PI / 10; + + int n; + FLOAT rot = 0.0; + + blotCount = requestedBlotCount; + blots = calloc (sizeof (Blot), blotCount); + + for (n = 0; n < blotCount; n++) + { + FLOAT radius = n * radSpace; + FLOAT x = cos (rot) * radius; + FLOAT y = sin (rot) * radius; + FLOAT z = n * zSpace - 1.0; + + rot += rotAmt; + initBlot (&blots[n], x, y, z); + } + scaleBlotsToRadius1 (); + randomlyReorderBlots (); + randomlyRotateBlots (); +} /* forward declaration for recursive use immediately below */ static void setupBlots (void); @@ -598,6 +719,10 @@ static void setupBlotsDuo (void) +/* + * main blot setup + */ + /* free the blots, in preparation for a new shape */ static void freeBlots (void) { @@ -620,12 +745,10 @@ static void freeBlots (void) } } - - /* set up the initial arrays of blots */ static void setupBlots (void) { - int which = RAND_FLOAT_01 * 8; + int which = RAND_FLOAT_01 * 11; freeBlots (); @@ -650,14 +773,19 @@ static void setupBlots (void) setupBlotsTetrahedron (); break; case 6: + setupBlotsSheet (); + break; case 7: + setupBlotsSwirlyCone (); + break; + case 8: + case 9: + case 10: setupBlotsDuo (); break; } } - - /* set up the segments arrays */ static void setupSegs (void) {