-/* 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.
*
/*
- * blot setup stuff
+ * generic blot setup and manipulation
*/
/* initialize a blot with the given coordinates and random display offsets */
}
}
+/* 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)
{
}
}
-
-
/* set up the initial array of blots to be a simple cube */
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;
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);
scaleBlotsToRadius1 ();
randomlyReorderBlots ();
+ randomlyRotateBlots ();
}
-
-
/* set up the initial array of blots to be a squiggle */
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)
}
scaleBlotsToRadius1 ();
+ randomlyRotateBlots ();
}
-
-
/* set up the initial array of blots to be randomly distributed
* on the surface of a tetrahedron */
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);
+/*
+ * main blot setup
+ */
+
/* free the blots, in preparation for a new shape */
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 ();
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)
{