I'm having an issue with a 3D distribution of points. The distribution is really nice looking in Mathematica, but it is used in an OpenGL astronomy program (Celestia) to generate a nebula, with sprites. The problem is caused by a too high density of points at some locations in the distribution. The sprites are then adding, which turns into an ugly rendering. I need to lower the density of points at those locations only, and I really don't know how.
I need to reject some points when the local density gets too high, or to add a short range repulsive force between the particles.
Here's the code I'm currently using with Mathematica 7.0. That code was defined elsewhere on this forum (see Simulation of the Crab nebula)
MinRadius := 0.00; (* min radius of distribution *)
MaxRadius := 1.00; (* max radius of distribution *)
MinSprite := 0.003; (* min radius of sprites *)
MaxSprite := 0.07; (* max radius of sprites *)
Oblateness := 0.8; (* oblateness of the spherical distribution *)
NumberOfVoids := 1000;
NumberOfPoints := 20000;
SpriteSize[r_] :=
MinSprite + (MaxSprite - MinSprite)(r - MinRadius)/(MaxRadius - MinRadius);
voidpts = Select[RandomReal[{-1, 1}, {NumberOfVoids, 3}],
MinRadius <= Norm[#/{1, 1, Oblateness}] <= MaxRadius &];
pts = Select[RandomReal[{-1, 1}, {NumberOfPoints, 3}],
MinRadius <= Norm[#/{1, 1, Oblateness}] <= MaxRadius &];
nf = Nearest[voidpts];
DistributeDefinitions[nf];
pts = ParallelMap[Nest[0.9975 (# + 0.01 (# - First@nf[#])) &, #, 100] &, pts];
PlotColor = ColorData["SunsetColors"];
Graphics3D[{PointSize[0.005], {PlotColor[Norm[1.3 #]], Sphere[#, 0.005]} & /@ pts},
Boxed -> False, Background -> Black, Lighting -> "Neutral", SphericalRegion -> True]
The number of points generated at the intersection of several filaments is too large : there's too much points accumulated there, and this is a problem for rendering in Celestia (too much sprites at the same location is very ugly).
So is there a way to reduce or dilute these points ? I need a rejection mecanism when the local density gets higher than a certain value (depending on the local sprite size).
The shortest distance between points shouldn't be smaller than the local sprite size (which is a function of distance to the origin). How can I add this as a constraint in the iteration process ?
Take note that I'm working with Mathematica 7.0 only (I don't have access to newer versions), so please consider suggestions compatible with this version.