I want to generate 100 random coordinates in 3D space satisfying the following conditions:
1) the maximum value of any coordinate is less than 14
2) the distance between any two points is always more than 2
I wrote a code that generates the first coordinate and stuck on how to go further because as I move further, I would have to make sure that the new coordinate is farther than 2 units from all of the coordinates already generated.
A 14*14*14 box? You could create an evenly spaced lattice with 7*7*7 points that is within the box.
343 points in the lattice. Put them on a list. Shuffle the list. Take first 100.
The distance between two points in full lattice is almost 14/6, i.e. 2.33. You can randomly shift each of the selected 100 points a small amount to any direction without creating a collision.
Fill the elements of pts successively as three random numbers uniform on [0,14), checking against all previous points in the vector; add a point only if its distance from all others is > 2. (Speed that up: exclude the absolute difference between corresponding coordinates first; then look at squared distance only. Give up on a potential point as soon as it fails to satisfy the distance criterion against any previous point.)
You've got some space in that box - shouldn't be too many overlaps.
Small matters:
- please put [code][/code] tags around your sample - then the indentation will show properly and we will be able to run in c++-shell without having to download it.
- there are better ways of generating uniform random variables than the discrete rand(); however, we can get to that in a bit.
All you need to do in the first instance is put (nested) loops around the check for a new Atom.
count will be the index of the Atom that you are trying to add, so something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
while ( count < 100 )
{
bool ok = true;
for ( int j = 0; j < count; j++ ) // check ALL previously placed Atoms,
{
// Your current code starting at temp_x = ...
// ... with dis = .... Atom[j] ... // comparing with the jth Atom
// Set ok = false if any Atom is too close; then break out of the loop
}
if ( ok )
{
// Set Atom[count] (rather than your current Atom[1]
}
}
Get the loop structure working. You can improve the random-number stuff and some other details later.
for (int i = 0;i < j;i++)
{
dis [i]= sqrt(pow(temp_x-Atom[i].x, 2) + pow(temp_y-Atom[i].y, 2) + pow(temp_z-Atom[i].z, 2));
if (dis [i] > min_dis)
{
record[i] = 1;
count_record++;
}
else
{
record [i] = 0;
count_record++;
}
}
if (search(record, count_record, 0) == false)
{
Atom[j].x = temp_x;
Atom[j].y = temp_y;
Atom[j].z = temp_z;
count++;
}
}
////////////////Print out the random coordinates////////////
for (int i = 0;i < count;i++)
{
cout << Atom[i].x << '\t' << Atom[i].y << '\t' << Atom[i].z << '\n';
}
return 0;
}
////////////////////////Functions///////////////////////////
///////////////////////////search function//////////////////
bool search(const int record[], int count_record, int target)
{
for(size_t i = 0;i < count_record;i++)
{
if (target == record [i])
return true;
}
return false;
}
]
This is what I have now. The compilation does not show me any errors but it prints only two coordinates. I don't know where I am going wrong.
I'm finding it hard to read without the indentation. Please use the [code][/code]
tags carefully. You can put them in by selecting your code and using the < > item in the Format menu to the right of the box you are entering in.
You are getting very confused with counters. We now have count, count_record and j ... you really only need the first of those.
I would suggest that your outer loop is a while loop, not a for loop. while ( count < row )
This is because your (temp_x,temp_y,temp_z) might NOT get added. At the moment you are just doing row passes and hoping that they are OK. They won't be.
Get rid of your record[] and search stuff ... it isn't needed. Add a particle (and increment count) if it is OK. Don't add the particle (and don't increment count) if it isn't. That's why you should use a while loop based on count ... you can keep looping until you have enough good particles.
Have another look at the loop structure I suggested; don't be too hooked on for loops.