Below is an example of how to generate one hundred small spheres randomly distributed inside a cylinder:

constexpr G4int NP = 100; // number of spheres
constexpr G4double r = 0.5*cm; // radius of a sphere
constexpr G4double DMIN = 3*r; // min distance between two spheres
constexpr G4double Rcyl = 10*cm; // radius of the cylinder
constexpr G4double Zcyl = 20*cm; // half length of the cylinder
// create a logical volumes for cylinder
G4Material* cyl_material = nist->FindOrBuildMaterial("G4_WATER");
G4Tubs* cylinder =
new G4Tubs("Cylinder", 0., Rcyl, Zcyl, 0., CLHEP::twopi);
G4LogicalVolume* cyl_logical =
new G4LogicalVolume(cylinder, cyl_material, "Cylinder");
// generate positions inside cylinder
G4ThreeVector bmin, bmax;
cylinder->BoundingLimits(bmin, bmax); // get bounding box of the cylinder
std::vector<G4ThreeVector> position;
while (position.size() < NP) {
G4double x = bmin.x() + (bmax.x() - bmin.x())*G4UniformRand();
G4double y = bmin.y() + (bmax.y() - bmin.y())*G4UniformRand();
G4double z = bmin.z() + (bmax.z() - bmin.z())*G4UniformRand();
G4ThreeVector p(x, y, z);
// check position
if (cylinder->Inside(p) != kInside) continue;
if (cylinder->DistanceToOut(p) < 0.5*DMIN) continue;
G4int size = position.size();
G4int k = 0;
for ( ; k < size; ++k) {
if ((position[k] - p).mag() < DMIN) break;
}
if (k == size) position.push_back(p); // add position to the list
}
// create a logical volume for spheres
G4Material* sph_material = nist->FindOrBuildMaterial("G4_AU");
G4Orb* sphere = new G4Orb("Sphere", r);
G4LogicalVolume* sph_logical =
new G4LogicalVolume(sphere,sph_material,"Sphere");
// create physical volumes for spheres
for (G4int i = 0; i < NP; ++i) {
new G4PVPlacement(0, position[i], sph_logical, "Partical", cyl_logical,
false, 0, checkOverlaps);
}
// create physical volume for cylinder
new G4PVPlacement(0, G4ThreeVector(), cyl_logical, "Cylinder", logicWorld,
false, 0, checkOverlaps);