+/* set up the initial array of blots to be near the corners of a
+ * cube, distributed slightly */
+static void setupBlotsCubeCorners (void)
+{
+ int n;
+
+ blotCount = requestedBlotCount;
+ blots = calloc (sizeof (Blot), blotCount);
+
+ for (n = 0; n < blotCount; n++)
+ {
+ FLOAT x = rint (RAND_FLOAT_01) * 2 - 1;
+ FLOAT y = rint (RAND_FLOAT_01) * 2 - 1;
+ FLOAT z = rint (RAND_FLOAT_01) * 2 - 1;
+
+ x += RAND_FLOAT_PM1 * 0.3;
+ y += RAND_FLOAT_PM1 * 0.3;
+ z += RAND_FLOAT_PM1 * 0.3;
+
+ initBlot (&blots[n], x, y, z);
+ }
+
+ scaleBlotsToRadius1 ();
+}
+
+
+
+/* forward declaration for recursive use immediately below */
+static void setupBlots (void);
+
+/* set up the blots to be two of the other choices, placed next to
+ * each other */
+static void setupBlotsDuo (void)
+{
+ int origRequest = requestedBlotCount;
+ FLOAT tx, ty, tz, radius;
+ Blot *blots1, *blots2;
+ int count1, count2;
+ int n;
+
+ if (requestedBlotCount < 15)
+ {
+ /* special case bottom-out */
+ setupBlotsSphere ();
+ 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 */
+ requestedBlotCount = origRequest / 2;
+ setupBlots ();
+
+ if (blotCount >= origRequest)
+ {
+ /* return immediately if this satisfies the original count request */
+ return;
+ }
+
+ blots1 = blots;
+ count1 = blotCount;
+ blots = NULL;
+ 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 */
+ requestedBlotCount = origRequest - count1;
+ setupBlots ();
+ blots2 = blots;
+ count2 = 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 */
+ blotCount = count1 + count2;
+ blots = calloc (sizeof (Blot), blotCount);
+ memcpy (&blots[0], blots1, sizeof (Blot) * count1);
+ memcpy (&blots[count1], blots2, sizeof (Blot) * count2);
+ free (blots1);
+ free (blots2);
+
+ scaleBlotsToRadius1 ();
+ randomlyReorderBlots ();
+
+ /* restore the original requested count, for future iterations */
+ requestedBlotCount = origRequest;
+}
+
+
+