# How to introduce random correlations in a 3D uniform distribution of points?

I would like to build a simple visualization of the distribution of galaxies on a large scale model of the universe. Currently, my galaxies are represented as uniform random black dots in a 3D cube, using the minimal working code below (this is a manipulate box, to see the effect of adding random dots, from 1 to 1000):

r = 1;

box = Graphics3D[{Opacity[0.1], EdgeForm[Gray], Cuboid[{0, 0, 0}, {1, 1, 1}]}];

x0[n_, r_] := x0[n, r] = RandomReal[{0, 1}]
y0[n_, r_] := y0[n, r] = RandomReal[{0, 1}]
z0[n_, r_] := z0[n, r] = RandomReal[{0, 1}]

particles[n_, r_] := Graphics3D[{PointSize -> 0.005,
Point[{x0[n, r], y0[n, r], z0[n, r]}]
}]

graph3D[Np_, r_] := Show[
{box, Table[{particles[n, r]}, {n, 1, Np}]},
PlotRange -> {{0, 1}, {0, 1}, {0, 1}},
ImageSize -> {700, 700},
SphericalRegion -> True,
Method -> {"RotationControl" -> "Globe"}
]

Manipulate[graph3D[Np, r], {{Np, 1, "N"}, 1, 1000, 1}, Row[{Button["Randomiser", {r = RandomReal[]}]}]]


I want to modify the random distribution to add correlation between galaxies, so the dots are creating random clusters and filaments as seen in the popular 3D simulations found on the internet (see for example this one: https://hipacc.ucsc.edu/Bolshoi/index.html).

So how could we modify the three functions x0[n_, r_], y0[n_, r_], z0[n_, r_] to introduce some random correlations between the black dots (i.e to create clusters and random structures)?

Please, I'm looking for something very simple, nothing fancy or complicated, that could work with an old version of Mathematica. I don't need something very realistic and I don't want to reproduce the large Newtonian N-body simulations like the Millenium Run! I simply want to produce a 3D visualization that feels qualitatively similar to the cosmic web:

• My suggestion would be to research methods for generating random fractals. For example, the diamond-square algorithm that's used for generating landscapes could probably be re-purposed (in some fashion) to create 3D "landscapes". I think it'll be much easier to seed some initial conditions from which you generate a fractal iteratively than to define probability distributions. Jul 25 at 19:01
• "something very simple, nothing fancy or complicated" - well, you're not asking for something very simple though. I agree that modifying the distributions seems like a dead end. Daniel's approach below is much more promising. Jul 25 at 19:14
• This question is likely of interest, especially the accepted answer with a modification on Simon Wood's post Jul 25 at 20:56

Here is a simple first approach:

We seed our "universe" by some random mass points (aka dark matter). Then the next mass point is chosen by an empirical distribution consisting of the already created mass points plus some noise. Then we repeat:

noise = 0.1;
dat = RandomReal[{-1, 1}, {20, 3}];
Do[AppendTo[dat,
noise RandomReal[{-1, 1}, 3] +
RandomVariate[EmpiricalDistribution[dat]]], 1000]
Graphics3D[Point[dat]]


To create a "Manipulate", we may e.g. write:

getPts[n_, noise_] := Module[{dat = RandomReal[{-1, 1}, {20, 3}]},
Do[AppendTo[dat, noise RandomReal[{-1, 1}, 3] + RandomChoice[dat]],
n]; dat]
Manipulate[
Graphics3D[Point[getPts[n, noise]],
PlotRange -> {{-1, 1}, {-1, 1}, {-1, 1}}]
, {{noise, 0.1}, 0, 0.4}, {{n, 1000}, 100, 5000}]

• Seems great. Unfortunately, my very old version of Mma (7.0) doesn't recognize the commands RandomVariate and EmpiricalDistribution. Are there equivalent commands that would work for old versions of Mma?
– Cham
Jul 25 at 20:05
• RandomVariate[EmpiricalDistribution[dat]] simply selects a random point from the current dataset, so you can replace that with RandomChoice[dat] (which seems to have been introduced in v6.0) Jul 25 at 20:54
• @GeorgeVarnavides, works like a charm! Thanks! I'll wait a bit before marking this answer, since others may suggest other solutions.
– Cham
Jul 25 at 23:33
• Look at the addition to my answer. Jul 27 at 16:45
• It will work if you write PointSize[...] instead of PointSize->.... Jul 29 at 13:09