0

I would like to draw a figure in 3D where I have a large cylinder inside which there are:

a) smaller cylinders parallel to the larger cylinder that contains them, like in the image below (taken from: How to draw cylinders inside a cylinder)

enter image description here

b) randomly distributed spheres that "break" the small cylinders. Occasionally these sphere may appear also on the surface of the main cylinder. I am also ok to place the sphere manually (rather than randomly)

I am looking for suggestion on how to proceed.

Luigi
  • 1,301
  • 8
  • 14

3 Answers3

2

Something like the following?

Graphics3D[{
  {Opacity[0.3], Cylinder[{{0, 0, -1}, {0, 0, 1}}, 1]},
  {Opacity[0.4], 
   Table[If[x^2 + y^2 <= .9^2, 
     Cylinder[{{x, y, -1}, {x, y, 1}}, 0.1]], {x, -1, 1, .2}, {y, -1, 
     1, .2}]}
  , Table[pos = RandomReal[{-.9, .9}, 3]; 
   If[pos[[1 ;; 2]].pos[[1 ;; 2]] <= .9^2, Sphere[pos, 0.1]], 100]
  }]

enter image description here

Daniel Huber
  • 51,463
  • 1
  • 23
  • 57
  • Yes. This is close to what I am looking for. How to randomize the x-y position of the cylinders without having them overlap? (like in the figure above) – Luigi Nov 02 '20 at 14:30
2
outerradius = 1.0;
seeds = RandomPoint[Disk[{0, 0}, outerradius], 3000];
radius = .05;
results = Reap[
    While[Length[seeds] > 2,
     (* pick a point and remove all others within radius *)
     {{point}, seeds} = TakeDrop[seeds, 1];
     seeds = Select[seeds, EuclideanDistance[#, point] > 2 radius &];
     Sow[point];
     ]
    ][[2, 1]];
height = 1.0;
cylinders = 
  Cylinder[{Append[#, 0], Append[#, height]}, radius] & /@ results;
Graphics3D[{Blue, Opacity[.5], 
  Cylinder[{{0, 0, 0.001}, {0, 0, height - 0.001}}, 
   outerradius + radius], Gray, Opacity[1], cylinders}, 
 Lighting -> "Neutral", Boxed -> False]

Unfortunately I can't get the clipping of the cylinders at the edges. It is very slow to do a RegionUnion of all the cylinders and then RegionIntersection this bundle with the outer cylinder to chop the edges off. You'd be better off doing this in more optimized 3D software capable of boolean CSG operations.

wires in core

flinty
  • 25,147
  • 2
  • 20
  • 86
1

Here is how you create non overlapping random circles inside a unit circles. Take care not to create too many circles, because if the unit circle is filled, the function will search forever:

oldpos = {};
newpos[] := (While[(t = RandomReal[{-.9, .9}, 2]; t.t > 0.9^2) || ( 
     Min[Norm[# - t] & /@ oldpos] < 0.2)]; AppendTo[oldpos, t]; t)
Graphics[Table[Circle[newpos[], 0.1], {40}]]

enter image description here

Daniel Huber
  • 51,463
  • 1
  • 23
  • 57