Skip to main content
add hexagonal version
Source Link
Mark Adler
  • 5k
  • 1
  • 22
  • 38

And now for something completely different. @novice did not ask that the circles be placed randomly, rather that the circles be distributed "uniformly". You can get more circles in if they are not placed randomly. This hexagonally packs in as many circles as possible of radius r, and then removes any excess circles randomly:

distinctx[n_,r_]:=Module[{x,c},
  x={
    2Floor[1/(2r)+1/2]-1,
    2Floor[1/(2r)],
    Sqrt[3](2Floor[1/(2Sqrt[3]r)+1/2]-1),
    2Sqrt[3]Floor[1/(2Sqrt[3]r)]}//
    Min[1/Select[#,#>0&]]&;
  c=Join[
    Table[Circle[x{2 i+1,Sqrt[3]j},r],
      {i,-Floor[1/(2x)+1/2],Floor[1/(2x)-1/2]},
      {j,-1-2Floor[1/(2Sqrt[3]x)-1/2],1+2Floor[1/(2Sqrt[3]x)-1/2],2}]
      //Flatten,
    Table[Circle[x{2 i,Sqrt[3]j},r],
      {i,-Floor[1/(2x)],Floor[1/(2x)]},
      {j,-2Floor[1/(2Sqrt[3]x)],2Floor[1/(2Sqrt[3]x)],2}]
      //Flatten];
  If[Length[c]>n,RandomSample[c,n],c]
]

For example:

distinctx[10,0.15]//
Graphics[{Blue,Line[{{-1,-1},{-1,1},{1,1},{1,-1},{-1,-1}}],Black,#}]&

random sample of hex arrangement

distinctx[40,0.15]//
Graphics[{Blue,Line[{{-1,-1},{-1,1},{1,1},{1,-1},{-1,-1}}],Black,#}]&

just a few missing

You're very unlikely to be able to get 40 circles of radius 0.15 stuffed in there randomly.

And now for something completely different. @novice did not ask that the circles be placed randomly, rather that the circles be distributed "uniformly". You can get more circles in if they are not placed randomly. This hexagonally packs in as many circles as possible of radius r, and then removes any excess circles randomly:

distinctx[n_,r_]:=Module[{x,c},
  x={
    2Floor[1/(2r)+1/2]-1,
    2Floor[1/(2r)],
    Sqrt[3](2Floor[1/(2Sqrt[3]r)+1/2]-1),
    2Sqrt[3]Floor[1/(2Sqrt[3]r)]}//
    Min[1/Select[#,#>0&]]&;
  c=Join[
    Table[Circle[x{2 i+1,Sqrt[3]j},r],
      {i,-Floor[1/(2x)+1/2],Floor[1/(2x)-1/2]},
      {j,-1-2Floor[1/(2Sqrt[3]x)-1/2],1+2Floor[1/(2Sqrt[3]x)-1/2],2}]
      //Flatten,
    Table[Circle[x{2 i,Sqrt[3]j},r],
      {i,-Floor[1/(2x)],Floor[1/(2x)]},
      {j,-2Floor[1/(2Sqrt[3]x)],2Floor[1/(2Sqrt[3]x)],2}]
      //Flatten];
  If[Length[c]>n,RandomSample[c,n],c]
]

For example:

distinctx[10,0.15]//
Graphics[{Blue,Line[{{-1,-1},{-1,1},{1,1},{1,-1},{-1,-1}}],Black,#}]&

random sample of hex arrangement

distinctx[40,0.15]//
Graphics[{Blue,Line[{{-1,-1},{-1,1},{1,1},{1,-1},{-1,-1}}],Black,#}]&

just a few missing

You're very unlikely to be able to get 40 circles of radius 0.15 stuffed in there randomly.

side comment
Source Link
Mark Adler
  • 5k
  • 1
  • 22
  • 38

I'd show you one in four dimensions, except that there's no HyperSphere[] or Graphics4D[]. Perhaps someone could work on those.

I'd show you one in four dimensions, except that there's no HyperSphere[] or Graphics4D[]. Perhaps someone could work on those.

add 3D
Source Link
Mark Adler
  • 5k
  • 1
  • 22
  • 38

As pointed out by Ernst Stelzer, this works in 3D just as well with two small changes:

distinct3D[n_,r_,maxiter_]:=Module[{p,m,k},
  p={};
  m=0;
  k=maxiter;
  While[
    p=Join[p,RandomReal[{-1,1},{n,3}]];
    p=sweep[p,2r];
    k=If[Length[p]>m,maxiter,k-1];
    m=Length[p];
    m<n&&k>0
  ];
  Sphere[#,r]&/@If[Length[p]>n,Take[p,n],p]
]

Then:

distinct3D[150, 0.2, 100]//Graphics3D

118 spheres of radius 0.2 packed into 2x2x2 box

That is 118 spheres.

As pointed out by Ernst Stelzer, this works in 3D just as well with two small changes:

distinct3D[n_,r_,maxiter_]:=Module[{p,m,k},
  p={};
  m=0;
  k=maxiter;
  While[
    p=Join[p,RandomReal[{-1,1},{n,3}]];
    p=sweep[p,2r];
    k=If[Length[p]>m,maxiter,k-1];
    m=Length[p];
    m<n&&k>0
  ];
  Sphere[#,r]&/@If[Length[p]>n,Take[p,n],p]
]

Then:

distinct3D[150, 0.2, 100]//Graphics3D

118 spheres of radius 0.2 packed into 2x2x2 box

That is 118 spheres.

add max iterations
Source Link
Mark Adler
  • 5k
  • 1
  • 22
  • 38
Loading
clarify
Source Link
Mark Adler
  • 5k
  • 1
  • 22
  • 38
Loading
better algorithm
Source Link
Mark Adler
  • 5k
  • 1
  • 22
  • 38
Loading
minor improvement
Source Link
Mark Adler
  • 5k
  • 1
  • 22
  • 38
Loading
Source Link
Mark Adler
  • 5k
  • 1
  • 22
  • 38
Loading