POV-Ray : Newsgroups : povray.general : Isosurface oddity : Re: Isosurface oddity Server Time
30 Jul 2024 06:18:45 EDT (-0400)
  Re: Isosurface oddity  
From: clipka
Date: 14 Jul 2009 10:25:00
Message: <web.4a5c95049e56e3e95fee4dc70@news.povray.org>
Doctor John <joh### [at] homecom> wrote:
> What's happening? Surely Pov's only got to look up the next number in
> the random stream which can't be much different from looking up the
> values of the declared variables.

This is really not an isosurface-specific issue; you get this error message
whenever you try to use rand() in a function.

There's two answers to your question - a short one and a long one:

(A) POV-Ray only supports a reduced set of built-in keywords in functions;
rand() is one of those not supported there, hence the error message.

(B) The POV-Ray function mechanism was designed for terms that need to be
evaluated over and over at run-time; for instance, to find even a single
ray-isosurface intersection, the defining function needs to be evaluated
multiple times over and over again with varying arguments. Therefore, a rand()
placed inside such a defining function would theoretically be evaluated over
and over again, too - creating a function that would change not only over
space, but also over "time" (even in a highly erratic way), which would
perfectly wreck the isosurface algorithm (aside from obviously not being what
you want).

So in order for this to work, the random value needs to be evaluated *before*
storing the function for later use - which is just what your second construct
does. To have POV-Ray automatically do this would require implementing special
treatment for the rand() keyword - which in other circumstances may *not* be
what the user would expect (for instance, someone might try to implement a
non-uniformly distributed random generator, using the function framework
instead of a macro).

Speaking of macros: As a matter of fact, if you need this idiom (using
rand()-generated values in a isosurface-defining function) frequently, you can
save some of the work by defining a Rand() macro as follows:

    #macro Rand(stream)
      #declare R = rand(stream);
      R
    #end

As macros are *always* evaluated at compile-time, and #declare statements are
valid everywhere, you could now place the call anywhere, even in a function
definition, without creating ambiguities or "misbehaving" functions.


Post a reply to this message

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