## POV-Ray 3.1 : Returning a value!

### POV-Ray 3.1 : Returning a value!

Hi,
OK, I am really pissed off because I can't figure it out...I've RTFM many
times (mainly the sections 4.2.8.4 and 4.2.8.5), and I still can't figure it
out.  I am making a 'plug-in' that requires the use of randomly generated
numbers.  I also wanted them to be negative numbers as well.  So, I created a
macro that would return a +1 or a -1 (randomly)...but I can't figure out how
to have that value returned.  I have something like this:

#macro Sign()
#local S=seed(clock);
#local R=rand(S);

#if(R <= .5)
1
#else
-1
#end
#end

I don't know if that is right or not, but I hope you can see what I am up to.
I know there is another way to generate random values from -1 to 1
(like: #local R=(rand(S)*2)-1 but just for now, I want to know how to return
values).

BTW, I wonder why POV-Ray Team could've just implemented a #return directive
It would make things really easy...and this shouldn't limit to numbers.

Thanks!
Bye!

- Website: http://www.geocities.com/SiliconValley/Heights/1107
- ICQ #7196672

### POV-Ray 3.1 : Returning a value!

> I can't figure out how to have that value returned.

You could do it like this:

#macro Sign()
#local S=seed(clock);
#local R=rand(S);

#if(R <= .5)
#declare return = 1
#else
#declare return = -1
#end
#end

and just use 'return' in the calling code.

/Ib

### POV-Ray 3.1 : Returning a value!

Hi,

>> I can't figure out how to have that value returned.

>You could do it like this:

>#macro Sign()
>  #local S=seed(clock);
>  #local R=rand(S);

>  #if(R <= .5)
>     #declare return = 1
>  #else
>     #declare return = -1
>  #end
>#end

>and just use 'return' in the calling code.

But the thing is, it is possible to not use a global value for this thing.  In
the manual (and sample scene), there is a macro called interpolate.  It looks
like this:

#macro Interpolate(T,T1,T2,P1,P2)
(P1+(T1+T/(T2-T1))*(P2-P1))
#end

It will return some values (which I am not sure what)...basically, I wanted to
use this to not have to repeat code...

Bye!

- Website: http://www.geocities.com/SiliconValley/Heights/1107
- ICQ #7196672

### POV-Ray 3.1 : Returning a value!

Quote:>>> I can't figure out how to have that value returned.
>>#macro Sign()
>>  #local S=seed(clock);
>>  #local R=rand(S);

>>  #if(R <= .5)
>>     #declare return = 1
>>  #else
>>     #declare return = -1
>>  #end
>>#end

>>and just use 'return' in the calling code.
>But the thing is, it is possible to not use a global value for this thing.
In
>the manual (and sample scene), there is a macro called interpolate.  It
looks
>like this:
>#macro Interpolate(T,T1,T2,P1,P2)
>   (P1+(T1+T/(T2-T1))*(P2-P1))
>#end

You've answered your own question really.  You don't return values since a
macro is a
text replacement function (substitution) and therefore returning a value is
irrelevent.  try

#macro Sign()
#local S=seed(clock); //I don't recommend this since it will throw out
animations.
#if(rand(S) <= .5)
1
#else
-1
#end
#end

I'm not sure how statements inside the #if construct are parsed so this may
not work...

--

### POV-Ray 3.1 : Returning a value!

Quote:

> OK, I am really pissed off because I can't figure it out...I've RTFM many
> times (mainly the sections 4.2.8.4 and 4.2.8.5), and I still can't figure it
> out.  I am making a 'plug-in' that requires the use of randomly generated
> numbers.  I also wanted them to be negative numbers as well.  So, I created a
> macro that would return a +1 or a -1 (randomly)...but I can't figure out how
> to have that value returned.  I have something like this:

> #macro Sign()
>   #local S=seed(clock);
>   #local R=rand(S);

>   #if(R <= .5)
>     1
>   #else
>    -1
>    #end
> #end

> I don't know if that is right or not, but I hope you can see what I am up to.
> I know there is another way to generate random values from -1 to 1
> (like: #local R=(rand(S)*2)-1 but just for now, I want to know how to return
> values).

> BTW, I wonder why POV-Ray Team could've just implemented a #return directive
> It would make things really easy...and this shouldn't limit to numbers.

I think the first problem you're having is due to a bug in POV-Ray
3.1.beta.4 that affects macros defined without any parameters.
Therefore, rewriting the macro as:

#macro Sign(X)
#ifndef (S) #declare S = seed(clock * 1e6); #end
#if (rand(S) < .5) 1 #else -1 #end
#end

would allow you to call the macro using a dummy parameter (any value
will do), avoiding the bug, eg:

translate <Sign(0) * 10, Sign(0) * 15, -5>

You'll also notice that I've rewritten your seed definition so that it
is only globally declared the first time the macro is called - otherwise
you would get the same "random" number every time!  Also, the seed()
function only accepts integers, so seed(clock) is only useful if the
clock value is different for every frame.  If, on the other hand, you
use the default 0 to 1 clock, you will normally want to multiply by a
suitably large number to give a different seed for each frame.

Note that while the above macro will work in place of pretty much any
float value (in objects, transformations, functions, etc.), it will not
work properly in a #declare statement.  It is possible to assign the
random value to a variable, eg:

#declare MyVar = 10 * Sign(X)

but this will generate a semi-colon warning (although placing a
semi-colon after the Sign(X) will cause a crash!).  Also, only one
Sign(X) can be used per #declare, and it must appear at the end of the
#declare statement.  For these reasons, it might be better to modify the
macro to declare a global variable and then use this variable as
required.  Alternatively, if you want to modify an existing variable by
the random value, you could use:

#macro Sign(MyVar)
#ifndef (S) #declare S = seed(clock * 1e6); #end
#declare MyVar = MyVar * (rand(S) < .5 ? 1 : -1);
#end

to be used like this:

#declare X = 182.41 / 12; Sign(MyVar)

Finally, I can reassure you that the 3.1.beta.4 bug affecting
parameterless macros has been fixed in later versions of the beta, and
should not affect the release version.

### POV-Ray 3.1 : Returning a value!

Quote:>#macro Sign()
>  #local S=seed(clock);
>  #local R=rand(S);

>  #if(R <= .5)
>    1
>  #else
>   -1
>   #end
>#end

>I don't know if that is right or not, but I hope you can see what I am up to.
>I know there is another way to generate random values from -1 to 1
>(like: #local R=(rand(S)*2)-1 but just for now, I want to know how to return
>values).

That's the proper way to return a value.  Also see the scenes\macro
directory for sample scenes.

However your macro won't work if its called several times in the same
frame because it re-inits the seed every call.  Read the section on
local vs global too.  Local IDs are temporary.

Quote:>BTW, I wonder why POV-Ray Team could've just implemented a #return directive
>It would make things really easy...and this shouldn't limit to numbers.

Its not necessary.
Chris Young POV-Team

Wonder if you can help me with something.

When I'm trying to create large numbers of randomly-positioned objects,
I follow the usual format of:

*************************
#declare r1=seed(0)
#declare r2=seed(1)

#declare numobject=0

#while (numobject<100)

#object {myobject translate/rotate/etc)

#declare numobject=numobject+1

#end
**********************

The problem is that about half the times when I do this, I get
an "Unexpected End of File" error on the second-to last line of the
above, as though it isn't seeing the #end statement on the last line.
Sometimes if I mess around with it long enough, it'll finally start
working, but I can never figure out what I did to fix it. Does anybody
know what causes this and how to get around it when it happens?