POV-Ray : Newsgroups : povray.general : Macros and arrays Server Time
20 Nov 2024 12:40:01 EST (-0500)
  Macros and arrays (Message 1 to 6 of 6)  
From: Gail Shaw
Subject: Macros and arrays
Date: 13 Aug 2001 08:12:37
Message: <3b77c435@news.povray.org>
I'm busy writing a macro to create piles of objects and I've run into a
rather nasty problem.

Below is a very simplified example of what I'm trying to do

I'd like the code to produce a lot of red spheres, a lot of blue
spheres and a lot of boxes of various shades of gray. What I get
are a lot of blue spheres and a lot of light gray boxes.

I'm guessing (not knowing exactly how macros work) that
when the objects are put into the first array the macros are
executed and the results put in the array. Is there any way inside
pov-ray to have the macros storred in the array and only executed
when the objects are written out?

I could probably do this fairly easily in VB (except for the trace) but
I'd rather do it in Pov.

Thanks
Gail
*************************************************************************
* gsh### [at] monotixcoza                *   Step into the abyss,           *
* http://www.rucus.ru.ac.za/~gail/   *   and let go.          Babylon 5 *
*************************************************************************
* The difficult we do immediately, the impossible takes a little longer *
*************************************************************************

#declare rnd=seed(1328);

#declare Land=height_field{ /* anything here */ }

#macro Object1()
  sphere {0,0.1
  #if (rand(rnd)>0.5)
    pigment {rgb <1,0,0>}
  #else
    pigment {rgb <0,0,1>}
  #end
 }
#end

#macro Object2()
   box {<-0.1,0,-0.1>,<0.1,0.1,0.1> pigment {rgb rand(rnd)}}
#end

#declare ObjectArray=array[2]
#declare ObjectArray[0]=Object1()
#declare ObjectArray[1]=Object2()

#declare LotsOfObjects=array[1000]
#declare i=0;
#declare rnd2=seed(783);
#while (i<1000)
  #if (rand(rnd2)<0.5)
    #declare LotsOfObjects[i]=ObjectArray[0]
  #else
    #declare LotsOfObjects[i]=ObjectArray[1]
  #end
  #declare i=i+1;
#end
#declare i=0;
#declare rnd2=seed(8452);
union {
#while (i<1000)
  declare Pos=<rand(rnd2),100,rand(rnd2)>
  object {LotsOfObjects[i] translate trace(Land,Pos,-y)}
  #declare i=i+1;
#end
}


Post a reply to this message

From: JRG
Subject: Re: Macros and arrays
Date: 13 Aug 2001 08:29:29
Message: <3b77c829@news.povray.org>
> I'm guessing (not knowing exactly how macros work) that
> when the objects are put into the first array the macros are
> executed and the results put in the array. Is there any way inside
> pov-ray to have the macros storred in the array and only executed
> when the objects are written out?

You guessed well. Why don't you just write as foolows:

#declare rnd=seed(1328);

 #declare Land=height_field{ /* anything here */ }

 #macro Object1()
 sphere {0,0.1
  #if (rand(rnd)>0.5)
  pigment {rgb <1,0,0>}
  #else
    pigment {rgb <0,0,1>}
  #end
  }
 #end
 #macro Object2()
    box {<-0.1,0,-0.1>,<0.1,0.1,0.1> pigment {rgb rand(rnd)}}
 #end


 #declare LotsOfObjects=array[1000]
 #declare i=0;
 #declare rnd2=seed(783);
 #while (i<1000)
   #if (rand(rnd2)<0.5)
     #declare LotsOfObjects[i]=Object1()
   #else
     #declare LotsOfObjects[i]=Object2()
   #end
   #declare i=i+1;
 #end
 #declare i=0;
 #declare rnd2=seed(8452);
 union {
 #while (i<1000)
   #declare Pos=<rand(rnd2),100,rand(rnd2)>;
   object {LotsOfObjects[i] translate trace(Land,Pos,-y)}
   #declare i=i+1;
 #end
 }


Post a reply to this message

From: Gail Shaw
Subject: Re: Macros and arrays
Date: 13 Aug 2001 08:52:20
Message: <3b77cd84@news.povray.org>
"JRG" <jrg### [at] hotmailcom> wrote in message
news:3b77c829@news.povray.org...
> > I'm guessing (not knowing exactly how macros work) that
> > when the objects are put into the first array the macros are
> > executed and the results put in the array. Is there any way inside
> > pov-ray to have the macros storred in the array and only executed
> > when the objects are written out?
>
> You guessed well. Why don't you just write as foolows:
>

As I said, that was simplified code. I'm writing
a macro to pile objects up (planning later to take
gravity and friction into account.) I want to allow
any number of different objects with different probabilities.
The macro as currently written takes an array of objects and an array of
probailities

eg

// very pseudo-code

#declare ObjectsArray=array[4] {Object1,Object2,Object3,Object4}
#declare ProbArray = array[4] {0.5,0.2,0.2,0.1}

Pile(ObjectsArray,ProbArray)

In the above case 50% of the pile will be object1, 20% object2 etc

Gail
--
*************************************************************************
* gsh### [at] monotixcoza                *   Step into the abyss,           *
* http://www.rucus.ru.ac.za/~gail/   *   and let go.          Babylon 5 *
*************************************************************************
* The difficult we do immediately, the impossible takes a little longer *
*************************************************************************


Post a reply to this message

From: ingo
Subject: Re: Macros and arrays
Date: 13 Aug 2001 10:13:34
Message: <Xns90FCA510C73Dseed7@povray.org>
in news:3b77cd84@news.povray.org Gail Shaw wrote:

> // very pseudo-code
> 
> #declare ObjectsArray=array[4] {Object1,Object2,Object3,Object4}
> #declare ProbArray = array[4] {0.5,0.2,0.2,0.1}
> 
> Pile(ObjectsArray,ProbArray)
> 
> In the above case 50% of the pile will be object1, 20% object2 etc
> 
> 

You'll have to do it in a few steps:

1. generate a random integer number in the range 0 to len(ProbArray)-1

2. use the resulting number as input for the ProbArray and retreive the 
probability.

3. generate a random number in the range 0-1, check if it is smaller or 
equal to the probability.

4. if no, start all over again.

5 if yes, take the number you found in step two and use it as input in 
the ObjectsArray.



Ingo

-- 
Photography: http://members.home.nl/ingoogni/
Pov-Ray    : http://members.home.nl/seed7/


Post a reply to this message

From: Gail Shaw
Subject: Re: Macros and arrays
Date: 13 Aug 2001 10:43:00
Message: <3b77e774@news.povray.org>
"ingo" <ing### [at] homenl> wrote in message
news:Xns### [at] povrayorg...
> in news:3b77cd84@news.povray.org Gail Shaw wrote:
>
> > // very pseudo-code
> >
> > #declare ObjectsArray=array[4] {Object1,Object2,Object3,Object4}
> > #declare ProbArray = array[4] {0.5,0.2,0.2,0.1}
> >
> > Pile(ObjectsArray,ProbArray)
> >
> > In the above case 50% of the pile will be object1, 20% object2 etc
> >
> >
>
> You'll have to do it in a few steps:
>

I've got the probability part. The way I've done it (which is probably not
the best)
is to create a second probability array. Using the above example the second
array would read {0.5,0.7,0.9,0.1}

I generate a random number between 0 and 1 then read along the array
checking
to see if the random number is smaller than the array value. If it is I use
the
array index as an index into the object array and stop checking, otherwise I
increment the
array index.

The problem I have is if one of the objects is created using a macro then
the macro is evaluated
when the object is assigned to the ObjectsArray and I'd like to find a way
to only evaluate the
macro when the object is actually created in the scene.

Gail
--
*************************************************************************
* gsh### [at] monotixcoza                *   Step into the abyss,           *
* http://www.rucus.ru.ac.za/~gail/   *   and let go.          Babylon 5 *
*************************************************************************
* The difficult we do immediately, the impossible takes a little longer *
*************************************************************************


Post a reply to this message

From: ingo
Subject: Re: Macros and arrays
Date: 13 Aug 2001 11:52:49
Message: <Xns90FCB5E4BBA97seed7@povray.org>
in news:3b77e774@news.povray.org Gail Shaw wrote:

> I generate a random number between 0 and 1 then read along the
> array checking
> to see if the random number is smaller than the array value. If it
> is I use the
> array index as an index into the object array and stop checking,
> otherwise I increment the
> array index.

If I understand it right what you do, this will not get you an even 
distribution.
 
 
> The problem I have is if one of the objects is created using a
> macro then the macro is evaluated
> when the object is assigned to the ObjectsArray and I'd like to
> find a way to only evaluate the
> macro when the object is actually created in the scene.

My solution, not very elegant.

---%<------%<---
#declare Stream=seed(7);

#macro PickObject(ObjArr, ProbArr, Stream)
   #local Len=dimension_size(ProbArr,1)-0.0000001;
   #local Loop=1;
   #while (Loop)
      #local Pos=int(rand(Stream)*Len); //range 0 to dimension_size-1
      //#debug concat("pos", str(Pos,0,-1),"\n")
      #local Prob=ProbArr[Pos];
      //#debug concat("prob",str(Prob,0,-1),"\n")
      #local Rnd=rand(Stream);
      //#debug concat("rnd",str(Rnd,0,-1),"\n")
      #if( Rnd <= Prob)
         #local Result=ObjArr[Pos];
         #local Loop=0;
      #end     
   #end
   (Result)
#end

#macro Sphere1()sphere{0,0.2 pigment{rgb 1}}#end
#macro Sphere2()sphere{0,0.3 pigment{rgb 1}}#end
#macro Sphere3()sphere{0,0.4 pigment{rgb 1}}#end
#macro Sphere4()sphere{0,0.5 pigment{rgb 1}}#end
#declare Sphere5=sphere{0,0.6 pigment{rgb 1}}

#declare ObjArr=array[5]{1,2,3,4,5}
#declare ProbArray=array[5]{0.1,0.3,0.4,0.6,0.2}

//while (...)
   #declare Result=PickObject(ObjArr, ProbArray, Stream);
   #switch(Result)
      #case(0)
         object{
            Sphere1()
      #break
      #case(1)
         object{
            Sphere2()
         }
      #break
      
      //etc
                    
   #end
//#end
camera {
   location <0,0,-4>
   look_at 0
}
light_source{
   <500,500,-500>
   rgb 1
}
---%<------%<---


Ingo

-- 
Photography: http://members.home.nl/ingoogni/
Pov-Ray    : http://members.home.nl/seed7/


Post a reply to this message

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