POV-Ray : Newsgroups : povray.general : how to prevent overlapping random objects? : Re: how to prevent overlapping random objects? Server Time
29 Jul 2024 20:16:21 EDT (-0400)
  Re: how to prevent overlapping random objects?  
From: Edouard
Date: 15 Aug 2010 17:00:00
Message: <web.4c6854dad03a138b20e671e70@news.povray.org>
"Simone" <inf### [at] alienenterprisesde> wrote:

> Hi,
> I created a bunch of cylinders with a while loop and the rand() function.
> But some of the cylinders are overlapping like in this picture:
> http://alien23.de/test4/cylinders.jpg
>
>I've spent hours trying out other values for the cylinders' translation.
> But when I use other values together with rand() I can prevent the cylinders
> from overlapping but then everything looks too orderly.
>
> So I basically want the bunch of cylinders to look like in the picture just
> without the 4 or 5 overlapping cylinders.
>
> I know it might work with the trace function to check whether they overlap and
> so I read through Jonathan Hunt's pebbles.pov where he uses this.
> But I found it very difficult and I don't know how too adapt the trace function
> to my scene.
>
> Or maybe it is possible to put all the translation data into an output file, and
> manually edit the overlapping cylinders and then reimport it? But I have no clue
> how to do this either.

Hi Simone!

Can I suggest a different function than rand() for placing the cylinders - there
is a mathematical set of functions call low discrepancy sequences, and the
simplest one of those to implement in POV macros is a Halton Sequence. The
output looks like the output from rand(), but the positions don't overlap (the
positions it produces just fill in the spaces, so the points get more and more
closely packed).

The code is:

#macro halton( index, base )
 #local out = 0.0;
 #local fraction = 1.0 / base;
 #local i = index;
 #while( i > 0 )
  #local remainder = mod( i, base );
  #local out = out + (fraction * remainder);
  #local i = int(i / base);
  #local fraction = fraction / base;
 #end

 out
#end

and you call it with a integer value that simply increases - e.g. a loop counter
(1,2,3,4,5,6...) - and a prime number as the base (2, 3, 5 etc - the smaller
ones give more pleasing results for what you are wanting to do)

You can create another macro to output a 2D coord:

#macro halton2D( n )
 #local baseX = 2;
 #local baseY = 3;
 < halton( n, baseX ), halton( n, baseY ), 0 >
#end


then you could place the cylinders with something like this:

union {
#declare num_cylinders = 100;
#declare i = 0;
#while( i < num_cylinders )
 object { cyl  translate halton2D( i ) * some_scale_value }
 #declare i = i + 1;
#end
}


You can also place objects in full 3D space with a helper like:

#macro halton3D( n )
 #local baseX = 2;
 #local baseY = 3;
 #local baseZ = 5;
 < halton( n, baseX ), halton( n, baseY ), halton( n, baseZ ) >
#end


Cheers,
Edouard.


Post a reply to this message

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