Uniform Point Distributions for Surfaces and Volumes Uniform Point Distributions for Surfaces and Volumes

Uniform Point Distributions for Surfaces and Volumes

This article is currently a work in progress, come back later!

Flipping points outside of the unit triangle back inside

(x,y)={(x,y)if x+y1,(1x,1y)if x+y>1. (x', y') = \begin{cases} (x, y) & \text{if } x + y \leq 1, \\ (1-x, 1-y) & \text{if } x + y > 1. \end{cases}

Mapping points to triangle space

Δan=ana0\Delta a_n = a_n - a_0
an=xn,yn,zna_n = x_n, y_n, z_n
n=0,1,2n = 0,1,2

2D

[xy]=[Δx1Δx2x0Δy1Δy2y0]×[uv1] \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} \Delta x_1 & \Delta x_2 & x_0 \\ \Delta y_1 & \Delta y_2 & y_0 \end{bmatrix} \times \begin{bmatrix} u \\ v \\ 1 \end{bmatrix}
x=Δx1u+Δx2v+x0x=\Delta x_1 u + \Delta x_2 v + x_0
y=Δy1u+Δy2v+y0y=\Delta y_1 u + \Delta y_2 v + y_0

3D

[xyz]=[Δx1Δx2x0Δy1Δy2y0Δz1Δz2z0]×[uv1] \begin{bmatrix} x \\ y \\ z \end{bmatrix} = \begin{bmatrix} \Delta x_1 & \Delta x_2 & x_0 \\ \Delta y_1 & \Delta y_2 & y_0 \\ \Delta z_1 & \Delta z_2 & z_0 \end{bmatrix} \times \begin{bmatrix} u \\ v \\ 1 \end{bmatrix}
x=Δx1u+Δx2v+x0x=\Delta x_1 u + \Delta x_2 v + x_0
y=Δy1u+Δy2v+y0y=\Delta y_1 u + \Delta y_2 v + y_0
z=Δz1u+Δz2v+z0z=\Delta z_1 u + \Delta z_2 v + z_0
SphericalParticleDistribution.jsx
let sampleNormalDistribution = () => {
// Using the Box-Muller transform to generate a normal distribution
let u = Math.random();
let v = Math.random();
let r = Math.sqrt(-2 * Math.log(u));
let theta = 2 * Math.PI * v;
return r * Math.cos(theta);
}
let positions = [];
for ( let i = 0; i < 1000; i ++ ) {
let x = sampleNormalDistribution();
let y = sampleNormalDistribution();
let z = sampleNormalDistribution();
let magnitude = Math.sqrt(x * x + y * y + z * z);
x /= magnitude;
y /= magnitude;
z /= magnitude;
positions.push(x);
positions.push(y);
positions.push(z);
}

If you want to generate a random distribution of points throughout the sphere instead, sample again, this time with a uniform distribution between [0,1], cube root the value, and multiply by the previous value. This will give you a uniform distribution of points throughout the sphere.

SphericalParticleDistribution.jsx
let sampleNormalDistribution = () => { ... }
let positions = [];
for ( let i = 0; i < 10000; i ++ ) {
let x = sampleNormalDistribution();
let y = sampleNormalDistribution();
let z = sampleNormalDistribution();
let r = Math.cbrt(Math.random()); // Cube root! Not square root
let magnitude = Math.sqrt(x * x + y * y + z * z);
x *= (r / magnitude);
y *= (r / magnitude);
z *= (r / magnitude);
positions.push(x);
positions.push(y);
positions.push(z);
}

← Back to blog