POV-Ray : Newsgroups : povray.general : #switch #case in function? Server Time
27 Jul 2024 12:31:02 EDT (-0400)
  #switch #case in function? (Message 3 to 12 of 12)  
<<< Previous 2 Messages Goto Initial 10 Messages
From: jr
Subject: Re: #switch #case in function?
Date: 16 Jun 2024 07:45:00
Message: <web.666ecfaebf6d15f1869a24876cde94f1@news.povray.org>
hi,

Ilya Razmanov <ily### [at] gmailcom> wrote:
> Yet another stupid question from me: can I use "case" operator withing
> function? I can't figure it out.

you can use the 'select' function from within your 'function {}', but I think
that's as good as it gets.  BE and or WFP are the people with the "function
nous".

<https://wiki.povray.org/content/Reference:Numeric_Expressions#Functions>


regards, jr.


Post a reply to this message

From: Cousin Ricky
Subject: Re: #switch #case in function?
Date: 16 Jun 2024 19:46:45
Message: <666f7965@news.povray.org>
On 2024-06-16 06:13 (-4), Ilya Razmanov wrote:
> Yet another stupid question from me: can I use "case" operator withing
> function? I can't figure it out.

Well... technically it is possible use #switch #case in a function
definition, but it will be evaluated only at parse time, freezing the
function definition at whatever the parse state was at that point.  This
is not generally useful.

So, do as Bill and Jr say: use select().  (I had to find this out the
hard way.)


Post a reply to this message

From: Ilya Razmanov
Subject: Re: #switch #case in function?
Date: 17 Jun 2024 05:19:28
Message: <666fffa0$1@news.povray.org>
On 16.06.2024 14:37, Bald Eagle wrote:

> I've done various versions of your Boolean product approach, but most often, it
> just comes down to using nested select () statements.
> 
> Just think of them as #if - (then) - #else statements and it will all make
> sense.

I'm trying to think but nothing happens (on the other side, this is, at 
least, reproducible, and I like reproducibility).

> That way you can also have plenty of #debug statements and whatever else you

Don't tell me about debug messages, it's too tempting. There is nothing 
I like more than making my programs say something stupid to the user. 
Nobody know but my programs are full of stupid sayings, like buttons 
"Allons-y!", "As you were!" and "Dismissed!". Nobody knows it because 
they are redefined at runtime to something human-friendly like "Ok" and 
"Cancel".

Well, anyway, I stepped onto weird artifacts with continuous 
nonmonotonous functions already, which guarantees keeping me busy. "She 
had no problems, therefore she bought a pig" (c) local proverb

-- 
Ilyich the Toad
https://dnyarri.github.io/


Post a reply to this message

From: Ilya Razmanov
Subject: Re: #switch #case in function?
Date: 17 Jun 2024 05:57:29
Message: <66700889$1@news.povray.org>
On 17.06.2024 2:46, Cousin Ricky wrote:

> definition, but it will be evaluated only at parse time,

I definitely want it to change between objects, and even worse, between 
triangle angles.

Okey then, seems like I'd better try to do something reasonable with my 
boolean*float + boolean*float switches at this time.

-- 
Ilyich the Toad
https://dnyarri.github.io/


Post a reply to this message

From: Ilya Razmanov
Subject: Using splines to map arbitrary value (was Re: #switch #case in function?)
Date: 17 Jun 2024 23:27:05
Message: <6670fe89$1@news.povray.org>
Ok, since my previous silly question was about piecewise functions 
rather than #switch per se (that is, case was supposed to be used to 
make function piecewise), I think I'll publish a solution for initial 
problem here, although it's not directly related to #switch.

Initially, I wanted piecewise linear function, as most simple to edit. 
Resulting solution looks somewhat like this:

#declare scl = function(c, lin, hin, lout, hout) {
     (c-lin)/(hin-lin) * (hout-lout) + lout
   }  // Linear rescale function from lin..hin to lout..hout range

#declare map_4 = function(c) {      // Piecewise rescaling example start
   (c <= 0.7) * scl(c, 0, 0.7, 0,1)  // rescale 0-0.7 to 0-1
   + (c > 0.7 & c <= 0.9) * scl(c, 0.7, 0.9, 1, 0.5)  // rescale 0.7-0.9 
to 1-0.5
   + (c > 0.9) * scl(c, 0.9, 1, 0.5, 1)  // rescale 0.9-1 to 0.5-1
   }  // Piecewise example end

yes, I managed to overcome my laziness and pack rescaling into separate 
scl function with simplified syntaxis.

But later I realized (yes, good ideas always come to me later) that 
piecewise interpolation is somewhere in POVRay already. For example, in 
splines. After a long attempts to understand what's written in manual I 
came up with the following:

#declare interpol = function {
   spline {
     linear_spline
     0.0, <0.0,0,0>
     0.7, <1.0,0,0>
     0.9, <0.5,0,0>
     1.0, <1.0,0,0>
     }
   }

#declare map_5 = function(c) {interpol(c).u}

and well, map_5 seem to give the same result as map_4 above, while being 
much easier to edit.

Surely, all this is too simple and obvious for people here, but well, at 
least next time I need interpolation, I can find it in this NG archives :-)

-- 
Ilyich the Toad
https://dnyarri.github.io/


Post a reply to this message

From: William F Pokorny
Subject: Re: Using splines to map arbitrary value (was Re: #switch #case infunction?)
Date: 18 Jun 2024 09:31:14
Message: <66718c22$1@news.povray.org>
On 6/17/24 23:27, Ilya Razmanov wrote:
> Ok, since my previous silly question was about piecewise functions 
> rather than #switch per se (that is, case was supposed to be used to 
> make function piecewise), I think I'll publish a solution for initial 
> problem here, although it's not directly related to #switch.

Thanks for posting your solution. It's good to be reminded of useful 
approaches to need.

On your original question about #switch inside a function{} block, I saw 
your switch by multiplication as good as anything else for clarity. As 
others said, using select()s is the more common function{} block switch 
alternative.

It is perhaps useful to add that there is a performance trade-off 
between the two approaches. The select()s are often faster, though it 
depends some on the details.

Bill P.


// Example requires the yuqk fork for f_boom() which throws after
// printing six values. It's a user function debugging aid.

#include "functions.inc"

#declare Fn_switch =
     function (_V,_Default) {
         select(-(_V=1),f_boom(1,0,0,0,0,0),
         select(-(_V=2),f_boom(2,0,0,0,0,0),
         select(-(_V=3),f_boom(3,0,0,0,0,0),
         select(-(_V=4),f_boom(4,0,0,0,0,0),
             _Default)
         )
         )
         )
     }

#declare Fn_switchByMult =
     function (_V,_Default) {
         (_V=1)*f_boom(1,0,0,0,0,0) +
         (_V=2)*f_boom(2,0,0,0,0,0) +
         (_V=3)*f_boom(3,0,0,0,0,0) +
         (_V=4)*f_boom(4,0,0,0,0,0) +
         ((_V<1)|(_V>4))*_Default
     }

     #debug concat("\nFn_switch returned <",
         str(Fn_switch(5,0),1,0),">\n\n")

//  --- Fn_switchByMult always throws as f_boom(1,0,0,0,0,0)
//      always runs. Everything is evaluated in a 'switch by
//      multiplication'
//  #debug concat("\nFn_switchByMult returned <",
//      str(Fn_switchByMult(5,0),1,0),">\n\n")

#error "Stop early\n"
//---


Post a reply to this message

From: Bald Eagle
Subject: Re: Using splines to map arbitrary value (was Re: #switch #case infunction?=
Date: 18 Jun 2024 10:05:00
Message: <web.667193726b7c39638519c45d25979125@news.povray.org>
William F Pokorny <ano### [at] anonymousorg> wrote:

> On your original question about #switch inside a function{} block, I saw
> your switch by multiplication as good as anything else for clarity.

WFP,

I was trying to think of some additional way to lay things like this out for
clarity, and I wondered if you might think about a way to evaluate functions in
a structure like a color_map.

Or perhaps more like a prism or a spline.

Then it would be easy to see what ranges any given function would be evaluated
in.

function_map {
     [0.0 FunctionA (x, y, z)]
     [0.3 FUnctionA (x, y, z)]
     [0.3 FunctionB (N)]
     [0.7 FunctionC (j, k)]
     [0.7 FunctionD (clock)]
     [1.0 FunctionD (clock)]
}

What are your thoughts on this type of data structure and how much work would
require its implementation?

- BW


Post a reply to this message

From: Ilya Razmanov
Subject: Re: Using splines to map arbitrary value (was Re: #switch #caseinfunction?)
Date: 18 Jun 2024 10:10:24
Message: <66719550$1@news.povray.org>
On 18.06.2024 16:31, William F Pokorny wrote:

> 
> On your original question about #switch inside a function{} block, I saw 
> your switch by multiplication as good as anything else for clarity.

Too many math operators in a row make it difficult for me to remember 
"what was that and what I did it for?" Besides, it allows non-continous 
functions to be created, which, in my particular case, is a disadvantage 
- I'm not going to think of what POVRay will do in areas where function 
is not defined, and debug all this. With splines I only have to watch 
for endpoints 0 and 1 to exist.

In fact, I made a decision to remove all various mapping functions and 
replace them with just spline. Using it completely match Photoshop and 
GIMP "Curves" so is absolutely intuitively clear to me and hopefully 
clear enough for other people, and instead of several algorithms with 
explanatory comments I'll be having just one control points table. The 
only problem is that in POVRay input-output pairs are written left to 
right, while in Photoshop visualized as 2D plot, but I think I can stand 
it :-)

-- 
Ilyich the Toad
https://dnyarri.github.io/


Post a reply to this message

From: Bald Eagle
Subject: Re: Using splines to map arbitrary value (was Re: #switch #caseinfunction?)
Date: 18 Jun 2024 10:55:00
Message: <web.66719eaeaf1180ff8519c45d25979125@news.povray.org>
Ilya Razmanov <ily### [at] gmailcom> wrote:

> Too many math operators in a row make it difficult for me to remember
> "what was that and what I did it for?" Besides, it allows non-continous
> functions to be created, which, in my particular case, is a disadvantage
> - I'm not going to think of what POVRay will do in areas where function
> is not defined, and debug all this.

You can always just use POV-Ray itself to graph your functions, and then you
will know exactly what will happen.

https://news.povray.org/povray.binaries.images/thread/%3Cweb.5926c5ddec053131c437ac910%40news.povray.org%3E/?ttop=44359
4&toff=900

https://news.povray.org/povray.text.scene-files/thread/%3Cweb.5926c60f1312c693c437ac910%40news.povray.org%3E/?ttop=4435
39&toff=100

https://news.povray.org/povray.text.scene-files/attachment/%3Cweb.5926c60f1312c693c437ac910%40news.povray.org%3E/graphf
unction.pov.txt

- BW


Post a reply to this message

From: William F Pokorny
Subject: Re: Using splines to map arbitrary value (was Re: #switch #case infunction?=
Date: 19 Jun 2024 09:33:51
Message: <6672de3f$1@news.povray.org>
On 6/18/24 10:02, Bald Eagle wrote:
> William F Pokorny <ano### [at] anonymousorg> wrote:
> 
>> On your original question about #switch inside a function{} block, I saw
>> your switch by multiplication as good as anything else for clarity.
> 
> WFP,
> 
> I was trying to think of some additional way to lay things like this out for
> clarity, and I wondered if you might think about a way to evaluate functions in
> a structure like a color_map.
> 
> Or perhaps more like a prism or a spline.
> 
> Then it would be easy to see what ranges any given function would be evaluated
> in.
> 
> function_map {
>       [0.0 FunctionA (x, y, z)]
>       [0.3 FUnctionA (x, y, z)]
>       [0.3 FunctionB (N)]
>       [0.7 FunctionC (j, k)]
>       [0.7 FunctionD (clock)]
>       [1.0 FunctionD (clock)]
> }
> 
> What are your thoughts on this type of data structure and how much work would
> require its implementation?
> 

For clarity about when each function runs an how they are interpolated - 
your suggest a start.

Handling all those individual function arguments would be messy. We'd 
have to deal with vector vs scalar functions. An encapsulating 
performance concern is that when any map interpolates / blends you need 
the value at both ends of each interpolation segment(*). Needing both 
values means two function calls for each interpolation segment - whether 
you need the interpolation aspect or not.

(*) Unless you are sitting on an index value or at at one of the ends of 
the overall set of interpolation segments. Most implementations grab two 
end values to keep the internal code simple. There is some optimization 
in POV-Ray's code base; I had to fix a bug where the new to v3.8 
blend_mode feature got tangled in one of those optimizations IIRC.

If the interpolations needed are not too complicated and fit into the 
available blend_mode, blend_gamma mechanisms, you can implement pigments 
which can be used as functions in a way similar to the way splines can 
be used in functions for such a purpose.

I have a bell ringing in my head that I played with some sort of 
function selection approach in years past. One based on 'gradient x' 
while creating isosurfaces I think - green, ugly shapes.

We have user_defined{} pigments / density too with which something might 
be doable.

There is in the fork yuqk the inbuilt f_mult1to8pairs() function, which 
in part, is aimed at cleaner representations / handling of sets of up to 
eight functions each having a corresponding multiplier/boolean. It was 
also aimed at being more efficient, but it won't especially be so over 
an in function select sequence - unless I get around to implementing 
some solid method of passing function pointers into inbuilt functions. 


There is too in yuqk f_morph2to9fncts() which enables all sorts of crazy 
weights and normalizations of a collection of input functions. I should 
get back to play more with this one! Maybe it's more animation related, 
but the idea is anything from morphing a sphere into a box to maybe 
including shipped shape classes with configuration options. It is, 
though, not a simple or especially clean function to use at this point. 
Maybe with some practice / refinement.

At the moment, I see a general, clean representation/solution to 
combining functions as messy - and an significant chunk of work.

Ah, there is too the 'average' back door to using functions as indexes 
which could be used in some simpler cases. Though the overall 
representation isn't itself that clean as using functions as variable 
weighting indexes is head twisting itself.

We can write macros as Cousin Ricky suggested with a simpler interface 
which would write / compile to SDL using select(s).

The thing nice about the spline and pigment_map based approaches is so 
long as the need fits into the available feature set, you get 
interpolation more or less for free.

How to more easily handle collections of functions / function code is an 
aim for the yuqk fork. All makes me think implementing Ingo's gradient 
macro collection as an inbuilt function collection, sooner rather than 
later, would be good. Especially, if I get back to playing with 
f_morph2to9fncts() and similar.

Bill P.


Post a reply to this message

<<< Previous 2 Messages Goto Initial 10 Messages

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