/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.MLLUSITFU0I/rev.1646
*
* authors:
*
* vs
* ben
* ben
*
*
*
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
float[] locs = new float[900];
void setup(){
size(400,400,P3D);
newSphere(119.055); // only needed for testing radius; 119.055 has half volume of 150
target = 119.055; // test only
newSphere(150);
// println(counter / MAX);
}
// R is sphere radius
void newSphere(float R){
average_distance = 0.0; // test only
for (int i=0; i<locs.length; i+=3) {
float theta = random(0.0, TWO_PI); // angle
float v = random(-1.0, 1.0); // 3d offset
float phi = acos(v); // 3d angle
// the magic number
//float n = 1.0 - (random(0.0, 1.0)*random(0.0575,1.0)); // this looks pretty good? agree
float n = pow(random(0.0, 1.0), 0.33333333); // testing
// maybe getting the average 3d distance would help (to diagnose)
// I don't know what weight the distribution should have
// in order to aesthetically or mathematically fill a given volume within the sphere
// with a similar # of points
// but this looks damn close
// :D
// ^ tests show that it is very slightly too close to the edge using random(0,1) * random(0,1)
// this can be tweaked very slightly by doing random(0,1) * random(0.044, 1), or instead using rand(0,1) * rand(0.0575, 1)
// using 0.044 for just one of the random calls looks about the same, but seems more equally distributed.
// 0.044 seems to line up well with random()'s faults in distribution
// 0.0575 seems to behave much better when the RNG is better
// there seem to be issues when the random number generator is vanilla random()
// LCG-type random will limit results when sampled in some tuple of size so that all points will fall...
// on specific parallel (hyper)planes, sometimes noticeably in 3d
// above, rand() and splitMix32() implement a 32-bit random number generator that's rather fast and better-distributed
float r = R * n; // random dist within radius
float x = r*cos(theta)*sin(phi);
float y = r*sin(theta)*sin(phi);
float z = r*cos(phi);
locs[i]=x;
locs[i+1]=y;
locs[i+2]=z;
//float d = sqrt(x * x + y * y + z * z); // test only
//average_distance += d; // test only
// if(d < target) { // test only
// counter+=1; // test only
// } // test only
}
}
void draw() {
background(0,0,30);
// rect(0,0,width,height);
fill(230);
stroke(0);
translate(width/2, height/2);
for (int i=0; i<locs.length; i+=3) {
pushMatrix();
rotateY(mouseX*PI/(float)width);
rotateX(mouseY*PI/(float)height);
translate(locs[i], locs[i+1], locs[i+2]);
box(5, 5, 5);
popMatrix();
}
stroke(100);
//sphere(150);
}
void keyPressed() {
if (key=='r'){
//counter = 0;
newSphere(150);
//println(counter / MAX);
}
}