POV-Ray : Newsgroups : povray.general : #switch #case in function? Server Time
4 Dec 2024 21:05:38 EST (-0500)
  #switch #case in function? (Message 1 to 10 of 12)  
Goto Latest 10 Messages Next 2 Messages >>>
From: Ilya Razmanov
Subject: #switch #case in function?
Date: 16 Jun 2024 06:13:59
Message: <666ebae7$1@news.povray.org>
Yet another stupid question from me: can I use "case" operator withing 
function? I can't figure it out.

Details:

I already used functions in my POVmosaic for mapping some object 
attributes to source pixel brightness, and surely implemented some 
transfer functions. And surely I want map in my img2mesh as well since 
sometimes I need some map adjustment. Currently I do it with Photoshop 
by editing source PNG heightfield with Photoshop "Curves/Map", saving 
resulting PNG, passing through img2mesh, rendering mesh thus obtained, 
realizing I need slightly changing map so editing it with Photoshop 
"Curves/Map" again etc. etc., so surely I want to transfer map from 
Photoshop into POVRay so it works in a non-destructive manner right in 
the final scene.

Currently my maps look like this:

//    Map functions
#declare map_1 = function(c) {c}               // Direct input
#declare map_2 = function(c) {1.0 - c}         // Negative input
#declare map_3 = function(c) {pow(c,(1/1.5))}  // Gamma 1.5
#declare map_4 = function(c) {      // Piecewise rescaling example start
     (c < 0.7) * ((c - 0) / (0.7 - 0) * (1 - 0) + 0) +       // rescale 
0-0.7 to 0-1
     (c >= 0.7) * ((c - 0.7) / (1 - 0.7) * (0.5 - 1) + 1)    // rescale 
0.7-1 to 1-0.5
}  // Piecewise example end

as you can see, map_4 is piecewise, one piece scaling up, another one 
scaling with inversion (sorry for all the +0 and -0, I put them to make 
things look "generalized" to try to prevent me forgetting what happens 
here. I'm still not sure that it doesn't contain errors already, need 
more tests), where "piecewise" is achieved by multiplying bools on cases 
and then adding all this together. It works but looks silly, and looking 
silly increase its chances to make me mess something up.

Is there any more elegant way to do piecewise functions in POVRay? I 
know that "if" and "case" exist in some form, but from examples I can 
see I don't get whether I can put them within functions, or not.

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


Post a reply to this message

From: Bald Eagle
Subject: Re: #switch #case in function?
Date: 16 Jun 2024 07:40:00
Message: <web.666ece78bf6d15f11f9dae3025979125@news.povray.org>
Ilya Razmanov <ily### [at] gmailcom> wrote:

Hi Ilya,

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.

Also, if it helps, you can get all of your equation expressions sorted out and
commented in a macro, and have the macro return the function for further use in
the scene.

That way you can also have plenty of #debug statements and whatever else you
need to make sure you're doing things right before you instantiate the actual
function.

- Bill


Post a reply to this message

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

Goto Latest 10 Messages Next 2 Messages >>>

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