|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
"Chris R" <car### [at] comcastnet> wrote:
>...
> Good catch!
>
> I actually modified f_normalized_atan2 as follows:
>
> #declare f_normalized_atan2 = function(x,y) {
> select(x,
> tau + atan2(x,y),
> pi,
> atan2(x,y)
> )
> }
>
> It's infinitesimally more efficient because you don't have to calculate
> atan2(+/-0,N), and gets rid of the mod arithmetic and addition where it isn't
> needed.
Sorry Chris,
It looked promising, but f_normalized_atan2(0, 1) returns pi instead of 0.
Rewriting it like this will solve that problem:
#declare f_normalized_atan2 =
function(x, y) {
select(
x,
atan2(x, y) + 2*pi,
select(y, pi, 0),
atan2(x, y)
)
}
;
Note that all these rewrites of the atan2() function does not trigger a "Domain
error", like atan2(0, 0) does when called outside a function.
--
Tor Olav
http://subcube.com
https://github.com/t-o-k
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Below are the results of some atan2-tests I just did.
Some constants:
pi/2 = 1.570796326794897
pi = 3.141592653589793
3*pi/2 = 4.712388980384690
2*pi = 6.283185307179586
tau = 2*pi
Z = 1e-100
Here the functions are given valid arguments:
The results for atan2() are all in the closed interval [-pi, +pi]
atan2(-0, -1) = -3.141592653589793
atan2(-Z, -1) = -3.141592653589793
atan2(-1, -Z) = -1.570796326794897
atan2(-1, -0) = -1.570796326794897
atan2(-1, +0) = -1.570796326794897
atan2(-1, +Z) = -1.570796326794897
atan2(-Z, +1) = -0
atan2(-0, +1) = -0
atan2(+0, +1) = +0
atan2(+Z, +1) = +0
atan2(+1, +Z) = +1.570796326794897
atan2(+1, +0) = +1.570796326794897
atan2(+1, -0) = +1.570796326794897
atan2(+1, -Z) = +1.570796326794897
atan2(+Z, -1) = +3.141592653589793
atan2(+0, -1) = +3.141592653589793
Atan2_Fn =
function(a, b) {
mod(atan2(a, b) + tau, tau)
}
The results for Atan2_Fn() are all in the half-open interval [+0, +tau)
Atan2_Fn(-Z, +1) = +0
Atan2_Fn(-0, +1) = +0
Atan2_Fn(+0, +1) = +0
Atan2_Fn(+Z, +1) = +0
Atan2_Fn(+1, +Z) = +1.570796326794897
Atan2_Fn(+1, +0) = +1.570796326794897
Atan2_Fn(+1, -0) = +1.570796326794897
Atan2_Fn(+1, -Z) = +1.570796326794897
Atan2_Fn(+Z, -1) = +3.141592653589793
Atan2_Fn(+0, -1) = +3.141592653589793
Atan2_Fn(-0, -1) = +3.141592653589793
Atan2_Fn(-Z, -1) = +3.141592653589793
Atan2_Fn(-1, -Z) = +4.712388980384690
Atan2_Fn(-1, -0) = +4.712388980384690
Atan2_Fn(-1, +0) = +4.712388980384690
Atan2_Fn(-1, +Z) = +4.712388980384690
n_atan2 =
function(a, b) {
atan2(a, b) + select(a, tau, 0)
}
The results for n_atan2() should all be in the half-open interval [+0, +tau)
n_atan2(-Z, +1) = +6.283185307179586 <--- NB
n_atan2(-0, +1) = +0
n_atan2(+0, +1) = +0
n_atan2(+Z, +1) = +0
n_atan2(+1, +Z) = +1.570796326794897
n_atan2(+1, +0) = +1.570796326794897
n_atan2(+1, -0) = +1.570796326794897
n_atan2(+1, -Z) = +1.570796326794897
n_atan2(+Z, -1) = +3.141592653589793
n_atan2(+0, -1) = +3.141592653589793
n_atan2(-0, -1) = -3.141592653589793 <--- NB !!!
n_atan2(-Z, -1) = +3.141592653589793
n_atan2(-1, -Z) = +4.712388980384690
n_atan2(-1, -0) = +4.712388980384690
n_atan2(-1, +0) = +4.712388980384690
n_atan2(-1, +Z) = +4.712388980384690
f_normalized_atan2 =
function(a, b) {
select(
a,
atan2(a, b) + tau,
select(b, pi, 0),
atan2(a, b)
)
}
The results for f_normalized_atan2() are all in the half-open interval [+0,
+tau)
f_normalized_atan2(-Z, -1) = +3.141592653589793
f_normalized_atan2(-0, -1) = +3.141592653589793
f_normalized_atan2(+0, -1) = +3.141592653589793
f_normalized_atan2(+Z, -1) = +3.141592653589793
f_normalized_atan2(-Z, +1) = +6.283185307179586 <--- NB
f_normalized_atan2(-0, +1) = +0
f_normalized_atan2(+0, +1) = +0
f_normalized_atan2(+Z, +1) = +0
f_normalized_atan2(+1, -Z) = +1.570796326794897
f_normalized_atan2(+1, -0) = +1.570796326794897
f_normalized_atan2(+1, +0) = +1.570796326794897
f_normalized_atan2(+1, +Z) = +1.570796326794897
f_normalized_atan2(-1, -Z) = +4.712388980384690
f_normalized_atan2(-1, -0) = +4.712388980384690
f_normalized_atan2(-1, +0) = +4.712388980384690
f_normalized_atan2(-1, +Z) = +4.712388980384690
Here the functions are given invalid arguments:
Atan2 =
function(a, b) {
atan2(a, b)
}
Atan2(-0, -0) = -3.141592653589793
Atan2(-0, +0) = -0
Atan2(+0, +0) = +0
Atan2(+0, -0) = +3.141592653589793
Atan2_Fn =
function(a, b) {
mod(atan2(a, b) + tau, tau)
}
Atan2_Fn(+0, +0) = +0
Atan2_Fn(+0, -0) = +3.141592653589793
Atan2_Fn(-0, -0) = +3.141592653589793
Atan2_Fn(-0, +0) = +0
n_atan2 =
function(a, b) {
atan2(a, b) + select(a, tau, 0)
}
n_atan2(+0, +0) = +0
n_atan2(+0, -0) = +pi
n_atan2(-0, -0) = -pi <--- NB !!!
n_atan2(-0, +0) = +0
f_normalized_atan2 =
function(a, b) {
select(
a,
atan2(a, b) + tau,
select(b, pi, 0),
atan2(a, b)
)
}
f_normalized_atan2(+0, +0) = +0
f_normalized_atan2(-0, +0) = +0
f_normalized_atan2(-0, -0) = +0
f_normalized_atan2(+0, -0) = +0
When looking at the results from both the valid and invalid arguments, it seems
to me that POV-Ray's built in atan2() gives the most consistent results,
followed by Atan2_Fn().
--
Tor Olav
http://subcube.com
https://github.com/t-o-k
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
"Tor Olav Kristensen" <tor### [at] TOBEREMOVEDgmailcom> wrote:
> Below are the results of some atan2-tests I just did.
>
> Some constants:
>
> pi/2 = 1.570796326794897
> pi = 3.141592653589793
> 3*pi/2 = 4.712388980384690
> 2*pi = 6.283185307179586
>
> tau = 2*pi
>
> Z = 1e-100
>
>
> Here the functions are given valid arguments:
>
> The results for atan2() are all in the closed interval [-pi, +pi]
>
> atan2(-0, -1) = -3.141592653589793
> atan2(-Z, -1) = -3.141592653589793
>
> atan2(-1, -Z) = -1.570796326794897
> atan2(-1, -0) = -1.570796326794897
> atan2(-1, +0) = -1.570796326794897
> atan2(-1, +Z) = -1.570796326794897
>
> atan2(-Z, +1) = -0
> atan2(-0, +1) = -0
>
> atan2(+0, +1) = +0
> atan2(+Z, +1) = +0
>
> atan2(+1, +Z) = +1.570796326794897
> atan2(+1, +0) = +1.570796326794897
> atan2(+1, -0) = +1.570796326794897
> atan2(+1, -Z) = +1.570796326794897
>
> atan2(+Z, -1) = +3.141592653589793
> atan2(+0, -1) = +3.141592653589793
>
>
> Atan2_Fn =
> function(a, b) {
> mod(atan2(a, b) + tau, tau)
> }
>
> The results for Atan2_Fn() are all in the half-open interval [+0, +tau)
>
> Atan2_Fn(-Z, +1) = +0
> Atan2_Fn(-0, +1) = +0
> Atan2_Fn(+0, +1) = +0
> Atan2_Fn(+Z, +1) = +0
>
> Atan2_Fn(+1, +Z) = +1.570796326794897
> Atan2_Fn(+1, +0) = +1.570796326794897
> Atan2_Fn(+1, -0) = +1.570796326794897
> Atan2_Fn(+1, -Z) = +1.570796326794897
>
> Atan2_Fn(+Z, -1) = +3.141592653589793
> Atan2_Fn(+0, -1) = +3.141592653589793
> Atan2_Fn(-0, -1) = +3.141592653589793
> Atan2_Fn(-Z, -1) = +3.141592653589793
>
> Atan2_Fn(-1, -Z) = +4.712388980384690
> Atan2_Fn(-1, -0) = +4.712388980384690
> Atan2_Fn(-1, +0) = +4.712388980384690
> Atan2_Fn(-1, +Z) = +4.712388980384690
>
>
> n_atan2 =
> function(a, b) {
> atan2(a, b) + select(a, tau, 0)
> }
>
> The results for n_atan2() should all be in the half-open interval [+0, +tau)
>
> n_atan2(-Z, +1) = +6.283185307179586 <--- NB
> n_atan2(-0, +1) = +0
> n_atan2(+0, +1) = +0
> n_atan2(+Z, +1) = +0
>
> n_atan2(+1, +Z) = +1.570796326794897
> n_atan2(+1, +0) = +1.570796326794897
> n_atan2(+1, -0) = +1.570796326794897
> n_atan2(+1, -Z) = +1.570796326794897
>
> n_atan2(+Z, -1) = +3.141592653589793
> n_atan2(+0, -1) = +3.141592653589793
> n_atan2(-0, -1) = -3.141592653589793 <--- NB !!!
> n_atan2(-Z, -1) = +3.141592653589793
>
> n_atan2(-1, -Z) = +4.712388980384690
> n_atan2(-1, -0) = +4.712388980384690
> n_atan2(-1, +0) = +4.712388980384690
> n_atan2(-1, +Z) = +4.712388980384690
>
>
> f_normalized_atan2 =
> function(a, b) {
> select(
> a,
> atan2(a, b) + tau,
> select(b, pi, 0),
> atan2(a, b)
> )
> }
>
> The results for f_normalized_atan2() are all in the half-open interval [+0,
> +tau)
>
> f_normalized_atan2(-Z, -1) = +3.141592653589793
> f_normalized_atan2(-0, -1) = +3.141592653589793
> f_normalized_atan2(+0, -1) = +3.141592653589793
> f_normalized_atan2(+Z, -1) = +3.141592653589793
>
> f_normalized_atan2(-Z, +1) = +6.283185307179586 <--- NB
> f_normalized_atan2(-0, +1) = +0
> f_normalized_atan2(+0, +1) = +0
> f_normalized_atan2(+Z, +1) = +0
>
> f_normalized_atan2(+1, -Z) = +1.570796326794897
> f_normalized_atan2(+1, -0) = +1.570796326794897
> f_normalized_atan2(+1, +0) = +1.570796326794897
> f_normalized_atan2(+1, +Z) = +1.570796326794897
>
> f_normalized_atan2(-1, -Z) = +4.712388980384690
> f_normalized_atan2(-1, -0) = +4.712388980384690
> f_normalized_atan2(-1, +0) = +4.712388980384690
> f_normalized_atan2(-1, +Z) = +4.712388980384690
>
>
> Here the functions are given invalid arguments:
>
> Atan2 =
> function(a, b) {
> atan2(a, b)
> }
>
> Atan2(-0, -0) = -3.141592653589793
> Atan2(-0, +0) = -0
> Atan2(+0, +0) = +0
> Atan2(+0, -0) = +3.141592653589793
>
>
> Atan2_Fn =
> function(a, b) {
> mod(atan2(a, b) + tau, tau)
> }
>
> Atan2_Fn(+0, +0) = +0
> Atan2_Fn(+0, -0) = +3.141592653589793
> Atan2_Fn(-0, -0) = +3.141592653589793
> Atan2_Fn(-0, +0) = +0
>
>
> n_atan2 =
> function(a, b) {
> atan2(a, b) + select(a, tau, 0)
> }
>
> n_atan2(+0, +0) = +0
> n_atan2(+0, -0) = +pi
> n_atan2(-0, -0) = -pi <--- NB !!!
> n_atan2(-0, +0) = +0
>
>
> f_normalized_atan2 =
> function(a, b) {
> select(
> a,
> atan2(a, b) + tau,
> select(b, pi, 0),
> atan2(a, b)
> )
> }
>
> f_normalized_atan2(+0, +0) = +0
> f_normalized_atan2(-0, +0) = +0
> f_normalized_atan2(-0, -0) = +0
> f_normalized_atan2(+0, -0) = +0
>
>
> When looking at the results from both the valid and invalid arguments, it seems
> to me that POV-Ray's built in atan2() gives the most consistent results,
> followed by Atan2_Fn().
>
> --
> Tor Olav
> http://subcube.com
> https://github.com/t-o-k
Nice analysis of the various options!
I have adopted your updated f_normalized_atan2, which I find works well with my
isosurfaces. Others may have different expectations and use a different
implementation.
My question would be, (and I should look at the pov code at some point to
check), when an isosurface is being evaluated, are there cases where -0 is
supplied to the isosurface function?
-- Chris R
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
On 12/27/24 09:27, Chris R wrote:
> My question would be, (and I should look at the pov code at some point to
> check), when an isosurface is being evaluated, are there cases where -0 is
> supplied to the isosurface function?
Might be. It depends on the function(s) being used in the isosurface and
what x,y,z values you might see given, environmental-usage of the
isosurface. Also, potentially, on the build compile for the executable.
Using the f_boom() inbuilt in the yuqk fork:
//--- Should be the f_sphere() version of this will run in v3.8 beta 2
#version 3.8;
#include "functions.inc"
isosurface {
function { f_boom(x/-2,y,z,0/-2,0,0) }
//function { f_sphere(x/-2,y,z-1,0.1) }
contained_by { box { -2.0,2.0 } }
threshold 0
accuracy 0.0005
max_gradient 1.1
finish { emission 1.0 }
}
//---
f_boom
1(x) -> -0,
2(y) -> 0,
3(z) -> 0,
4(0) -> -0,
5(1) -> 0,
6(2) -> 0
Bill P.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|