3 ms·
I thought this was kinda fun, and I was trying to figure out why you couldn't just take a random x and use it to find a y that preserves x²+y²=r² (ie by setting
by sgentle 8y ago
I thought this was kinda fun, and I was trying to figure out why you couldn't just take a random x and use it to find a y that preserves x²+y²=r² (ie by setting y to a random number between 0 and ±√(r²-x²)). In the end I figured out that you need to generate x the same way, but if you have, say: n=rand(r), x=rand(±√(r²-n²)), y=rand(±√(r²-x²)) it seems to work.
Here's a version I extended to three dimensions, designed to be run in the JS console of the original article (it'll show up underneath the first sphere):
new SphereSimulation(document.getElementById("spheres1"), () => {
const rand = Math.random
const root = (x) => rand() < 0.5 ? Math.sqrt(x) : -Math.sqrt(x)
const invdist = (a=0, b=0) => root(RADIUS*RADIUS - a*a - b*b)
const x1 = rand() * invdist()
const x2 = rand() * invdist(x1)
const y2 = rand() * invdist(x2)
const x3 = rand() * invdist(x2, y2)
const y3 = rand() * invdist(x3, y2)
const z3 = rand() * invdist(x3, y3)
return new THREE.Vector3(x3, y3, z3)
})
It looks okay to me - am I missing something? Is this a reasonable approach?
- goldenkey 8y agoI posted a comment where I described this method as my preferred solution. You did not need to patch it up though..its fine to just generate the 3 numbers and then choose a random assignment from them to x y and z. This fixes the bias that would be present if you always generated x first.
- jpeanuts 8y agoYour missing the requirement that the random sample be uniform in the sphere. That is, if the sphere is cut into any number of pieces of equal volume, the sample is equally likely to appear in any piece. Your approach samples uniformly from the radius, so you're going to end up with far too many samples close to the center.
- sgentle 8y agoInteresting... thanks for the pointer. I did some testing and the points definitely do seem to cluster along the axis... just increasing the number of iterations of √(r²-n²) seemed to improve it though. At 5, I can't tell the difference anymore: https://codepen.io/anon/pen/xJJOEq https://codepen.io/anon/pen/xJJOEq
- deleted 8y ago[deleted]