|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
|
|