POV-Ray : Newsgroups : povray.general : Stacking Balls : Re: Stacking Balls Server Time
13 Aug 2024 13:15:13 EDT (-0400)
  Re: Stacking Balls  
From: Friedemann Schmidt
Date: 24 Aug 1998 15:46:21
Message: <35e1b4f5.29165353@news.povray.org>
Hi,

>  I once asked if anybody had developed a routine for object collision
>avoidance which I believe is what you will need to fill a cylinder or
>any other shape without them overlapping. Dan Connely replied that
>he had seen one recently but I can't remember where the posted reply
>is located at. Dan if your out there could you fill in the blanks.

I just wrote a little macro which fills a cylinder with spheres
randomly without overlapping. The problems are, that it takes a long
time to render for many spheres in a small cylinder and that the
spheres doesn't contact each other. So it can only be used to fill a
shape in space without gravitation ;-)

The parameter variables are:
  SeedNr: value for initializing the random stream
  CylRadius: Radius of the cylinder
  CylHeight: Height of the cylinder
  Count: The number of spheres to create
  MinSize: Minimum size of a sphere
  MaxSize: Maximum size of a sphere
  MaxLoops: After this number of loops the macro will be interrupted
if no new position for a sphere can be found.

The cylinder is based on the X-Z-floor.

Example:  FillCylinder(1, 1, 2, 500, 0.1, 0.1, 100) 
(It took 50 seconds on my computer by parsing...)

A macro for filling a sphere or a box could be written easily by the
same way.

By the way, the macro can also be used by

union {
  FillCylinder(1, 1, 2, 500, 0.1, 0.1, 100)
  rotate...
  translate ...
}

#macro FillCylinder(SeedNr, CylRadius, CylHeight, Count, MinSize,
MaxSize, MaxLoops)
  #local Seed = seed(SeedNr);
  #local Pos = array[Count]
  #local Size = array[Count]

  #local i = 0;
  #local Loops = 0;
  #while (i < Count & Loops < MaxLoops)
    #local Size[i] = rand(Seed)*(MaxSize-MinSize)+MinSize;
    
    #local Break = false;
    #while (Break = false)
      #local X = rand(Seed)*(CylRadius-Size[i])*2-(CylRadius-Size[i]);
      #local Z = rand(Seed)*(CylRadius-Size[i])*2-(CylRadius-Size[i]);
      #if (vlength(<X, 0, Z>) <= CylRadius-Size[i])
        #local Break = true;
      #end
    #end
    #local Y = rand(Seed)*(CylHeight-2*Size[i])+Size[i];
    #local Pos[i] = <X, Y, Z>;
    
    #local ShowIt = true;
    #local j = 0;
    #while (j < i & ShowIt = true)
      #if (vlength(Pos[j]-Pos[i])-Size[j]-Size[i] < 0)
        #local ShowIt = false;
      #end
      #local j = j + 1;
    #end
      
    #if (ShowIt = true)    
      #debug concat("Sphere ", str(i+1, 0, 0), "\n")
      sphere {
        Pos[i], Size[i]
        pigment { color rgb <1, 0, 0> }
      }
      #local i = i + 1;
      #local Loops = 0;
    #else
      #local Loops = Loops + 1;
    #end
  #end
  #if (Loops > 0)
    #debug concat(">>> Break after ", str(Loops, 0, 0), " loops!\n")
  #end
#end

Bye,
Friedemann




Friedemann Schmidt
Fri### [at] Stonescom
Raytracing-Gallery: http://www.rz.fhtw-berlin.de/~s0049669/


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.