Skip to content

Instantly share code, notes, and snippets.

@nestarz
Created April 2, 2020 23:22
Show Gist options
  • Save nestarz/4dc43ef4ca8991d5c5217243144577e7 to your computer and use it in GitHub Desktop.
Save nestarz/4dc43ef4ca8991d5c5217243144577e7 to your computer and use it in GitHub Desktop.
Returns a random point on the surface of a sphere with radius 1.
// Fastest
// Marsaglia (1972)
// https://stackoverflow.com/a/5408344
const randomOnUnitSphere = N => {
const vectors = new Float32Array(N * 3);
for (let i = 0; i < N; i++) {
let x, y, z, norm;
while (true) {
x = 0.5 - Math.random();
y = 0.5 - Math.random();
z = 0.5 - Math.random();
norm = (x ** 2 + y ** 2 + z ** 2) ** 0.5;
if (norm < 1) break;
}
vectors[i * 3 + 0] = x / norm;
vectors[i * 3 + 1] = y / norm;
vectors[i * 3 + 2] = z / norm;
}
return vectors;
};
// Alternative
// https://mathworld.wolfram.com/SpherePointPicking.html
const randomOnUnitSphere = N => {
const vectors = new Float32Array(N * 3);
for (let i = 0; i < N; i++) {
const u = Math.random();
const v = Math.random();
const theta = u * Math.PI * 2;
const phi = Math.acos(2 * v - 1);
const x = (1 - Math.cos(phi) ** 2) ** 0.5 * Math.cos(theta);
const y = (1 - Math.cos(phi) ** 2) ** 0.5 * Math.sin(theta);
const z = Math.cos(phi);
const norm = (x ** 2 + y ** 2 + z ** 2) ** 0.5;
vectors[i * 3 + 0] = x / norm;
vectors[i * 3 + 1] = y / norm;
vectors[i * 3 + 2] = z / norm;
}
return vectors;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment