Generating a set of random 3D coordinates is ok, e.g.
positions = RandomReal[{0, 10}, {10, 3}];
radius = 1;
Graphics3D[{Red, Sphere[positions, radius]}, PlotRangePadding -> 2,
Lighting -> "Neutral"]
Now I want to add a constraint, so that the distance between any point and its nearest neighbour is fixed.
A good way of thinking about it would be like generating a virtual molecule, where the atoms can't be too close to each other, but nor can they be too far apart otherwise they wouldn't be bonded.
I had a prototype made in C++ a while back that just iterated over and over, adding a new point each time the randomly generated coordinates happened to fit the constraint. For example, first I placed a single point with random coordinates and called it i
. Then I created a new point, j
, with random coordinates. I then defined a distance between point i
and point j
:
euclideandistance = Sqrt[
(positions[[i,1]]-positions[[j,1]])^2 +
(positions[[i,2]]-positions[[j,2]])^2 +
(positions[[i,3]]-positions[[j,3]])^2
]
Then if the constraint, based on bondlength
,
0.9*bondlength < euclideandistance < 1.1*bondlength
was satisfied, I'd add point j
and start over with a new point k
, comparing the distance to its nearest neighbour (which of course could be i
or j
now) and repeating...
This seems somewhat inefficient...it was a quick-and-dirty prototype after all! Coming from a C++ background to Mathematica, is there a good way to do this in Mathematica that doesn't involve a While
loop?
Update
Courtesy of Yves Klett, this question (in 2D and with only a lower bound) Efficient way to generate random points with a predefined lower bound on their pairwise Euclidean distance is what I had in mind, I didn't spot it in my search before posting this.
I'll go away and have a play myself when I can tomorrow to apply it to my scenario, and post what I come up with when I've done so (though any answers in the meantime are fine! It all adds to the learning experience for me).
While
) :D $\endgroup$