POV-Ray : Newsgroups : povray.newusers : help with macro : Re: help with macro Server Time
29 Jul 2024 06:20:21 EDT (-0400)
  Re: help with macro  
From: Chris B
Date: 15 May 2006 14:12:37
Message: <4468c495$1@news.povray.org>
"mine" <nomail@nomail> wrote in message 
news:web.4468ad3d4767bb90a533cc200@news.povray.org...
> "Chris B" <c_b### [at] btconnectcomnospam> wrote:
>> "mine" <nomail@nomail> wrote in message
>> news:web.44687a797f9206dfa533cc200@news.povray.org...
>> > I've made a basic macro (with the help of a tutorial)that randomly 
>> > places
>> > objects (in this case spheres) in a given space. The trouble is the
>> > tutorial didn't tell me how to stop the spheres from touching. Can 
>> > anyone
>> > help? I've included the macro below.
>> >
>> ... snip ...
>>
>> Hi,
>>
>> You can declare an array of size 'floater_count', then each time round 
>> the
>> current loop, do another loop to test whether the position of the centre 
>> of
>> the sphere is closer than the diameter of floater to any of the existing
>> positions (see the vlength() function, which you can use on the 
>> difference
>> between each pair of positions).
>>
>> Then you can put the 'object' statement plus the line where you decrement
>> 'floater_count' inside an #if clause along with a new line to add the new
>> position into the array.
>>
>> If you're likely to want to increase float_count to where you get close 
>> to
>> the limit where you can't find enough positions, then you should also add 
>> a
>> way of breaking out of your existing loop to avoid that you loop
>> indefinitely.
>>
>> I didn't post code because it sounds like you're trying to work stuff out
>> for yourself, but if you want the answer, just say.
>>
>> Regards,
>> Chris B.
>
> hi Chris B.
> I tried figure it out but kept on getting lost. You better just give me 
> the
> answer. I sort of understand what I was trying to do but I have no idea 
> how
> to do it. Thanks for helping.
>
>

Hi,

I see Warp has posted a perfectly good solution, that does the same thing in 
a slightly different sequence. It collects the set of points into an array 
in the first loop, then draws the objects using those points in a second 
loop.

Here's the approach I described using the code you posted as a starting 
point (I'd recommend you use uppercase letters to start each variable name 
as that helps avoid conflicts with any stuff added to future versions of 
POV-Ray). I also added the LoopLimit stuff that both Warp and I mentioned 
earlier to avoid infinite loops (so you probably want to set the 
Floater_count back to 20).


camera {location <0, 0, -10> look_at  <3,3,0>}
light_source { <0, 50, -400> color 1}

#declare ObjectRadius = 1;

#declare Floater = sphere{<0,.5,0>, ObjectRadius}
#declare Thingy_red = <1,0,0>;
#declare Floater_count = 200;
#declare Locations = seed(1);

#declare Positions = array[Floater_count];
#declare FloaterQuantity = Floater_count;
#declare LoopLimit = 1000;
#declare CollisionCounter = 0;

#while (Floater_count > 0 & CollisionCounter < LoopLimit)
  #declare x_loc = rand(Locations)*7-1;
  #declare y_loc = rand(Locations)*7-1;
  #declare z_loc = rand(Locations)*7-1;
  #declare I = FloaterQuantity - 1;
  #declare TooClose = 0;
  #while(I>Floater_count-1)
    #if (vlength(<x_loc,y_loc,z_loc>-Positions[I])<ObjectRadius*2)
      #declare TooClose = 1;
    #end
    #declare I = I - 1;
  #end
  #if (TooClose)
    #declare CollisionCounter = CollisionCounter + 1;
  #else
    #declare CollisionCounter = 0;
    object{Floater
      pigment{color Thingy_red}
      translate <x_loc,y_loc,z_loc>
    }
    #declare Floater_count = Floater_count - 1;
    #declare Positions[Floater_count] = <x_loc,y_loc,z_loc>;
  #end
#end

#if (CollisionCounter >= LoopLimit)
  #debug "\n\nWARNING: Loop Limit Exceeded\n\n\n"
#end
.

Regards,
Chris B.


Post a reply to this message

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