





 
 




 
 


Hello,
I have a problem with atan2(a,b) when b = zero.
The documentation on the page
<http://www.povray.org/documentation/view/3.7.1/228/> says :
Arctangent of (A/B). Returns the angle, measured in radians, whose
tangent is (A/B). **Returns appropriate value even if B is zero**
In my case, i get : Parse Error: Domain error in atan2!
So it's up to me to test if b=zero and return the appropriate value ?

Kurtz le pirate
Compagnie de la Banquise
Post a reply to this message


 
 




 
 


Le 17/10/2021 à 12:40, kurtz le pirate a écrit :
>
> Hello,
>
> I have a problem with atan2(a,b) when b = zero.
>
> The documentation on the page
> <http://www.povray.org/documentation/view/3.7.1/228/> says :
>
> Arctangent of (A/B). Returns the angle, measured in radians, whose
> tangent is (A/B). **Returns appropriate value even if B is zero**
>
> In my case, i get : Parse Error: Domain error in atan2!
>
> So it's up to me to test if b=zero and return the appropriate value ?
>
>
>
Looking at the code (parser_expression.cpp), it is a direct call to
atan2 function.
Povray parsed A, B, so from atan2 man page, A=y, B=x, *BUT* the code is
just defensive:
<pre>
if (FTRUE(Val)  FTRUE(Val2))
Val = atan2(Val,Val2);
else
Error("Domain error in atan2!");
break;
</pre>
0 & 0 : Domain error. Which is correct as well as atan2 implementation
returning +pi/0/pi/+0 according to y,x being +/0 at the same time.
Post a reply to this message


 
 




 
 


On 17/10/2021 14:01, Le_Forgeron wrote:
> ...
> Povray parsed A, B, so from atan2 man page, A=y, B=x, *BUT* the code is
> just defensive:
> ...
>
Clear and precise answer. I was misled by the description of the
function in the documentation.

Kurtz le pirate
Compagnie de la Banquise
Post a reply to this message


 
 




 
 


Le 20211017 à 06:40, kurtz le pirate a écrit :
>
> Hello,
>
> I have a problem with atan2(a,b) when b = zero.
>
> The documentation on the page
> <http://www.povray.org/documentation/view/3.7.1/228/> says :
>
> Arctangent of (A/B). Returns the angle, measured in radians, whose
> tangent is (A/B). **Returns appropriate value even if B is zero**
>
> In my case, i get : Parse Error: Domain error in atan2!
>
> So it's up to me to test if b=zero and return the appropriate value ?
>
>
>
A/B is undefined when B = 0.
So, «Parse Error: Domain error in atan2» is the appropriate value when B
is zero.
The appropriate value when B is zero would be plus AND minus infinity.
Post a reply to this message


 
 




 
 


kurtz le pirate <kur### [at] gmailcom> wrote:
>
> Clear and precise answer. I was misled by the description of the
> function in the documentation.
>
I would be mislead by that too. The docs imply that *a value* will be returned
(not a domain error message) but "The appropriate value when B is zero would
be plus AND minus infinity", as Alain has mentioned. Which naturally triggers a
domainerror. Seems to me that the error message should be worded more
appropriately, at least. Or the docs should include this bit of info, for users
who may not know the math details of what happens when B=0.
Post a reply to this message


 
 




 
 


On 20211017 6:40 AM (4), kurtz le pirate wrote:
>
> I have a problem with atan2(a,b) when b = zero.
>
> The documentation on the page
> <http://www.povray.org/documentation/view/3.7.1/228/> says :
>
> Arctangent of (A/B). Returns the angle, measured in radians, whose
> tangent is (A/B). **Returns appropriate value even if B is zero**
>
> In my case, i get : Parse Error: Domain error in atan2!
Is your value for A also zero?
> So it's up to me to test if b=zero and return the appropriate value ?
It seems that some people are confused about atan2().
Of course, the inverse tangent of A/0 is undefined, because A/0 is
undefined. But a simple limits exercise, as well as the very definition
of the tangent of an angle, show that these undefined tangents
correspond to the angles pi/2 and pi/2, and it is therefore useful to
pretend that they are valid.
The purpose of atan2() is to handle these special cases, by converting a
naive atan()'s argument into an ordered pair, thus allowing the wouldbe
inverse tangent of A/0 to be computed without having to divide by 0. A
simple scene file shows that the *only* time atan2() fails with a domain
error is when *both* A and B are zero. Of course, (0, 0) is an
indeterminate case, for which returning a value would be nonsensical.
[BEGIN CODE]
#version 3.7;
global_settings { assumed_gamma 1 }
#declare Args = array [9]
{ <0, 1>, <1, 1>, <1, 0>, <1, 1>, <0, 1>,
<1, 1>, <1, 0>, <1, 1>, <0, 0>,
}
#for (I, 0, 8)
#debug concat ("atan2 (", vstr (2, Args[I], ", ", 0, 0), ") = ")
#debug concat (str (atan2 (Args[I].x, Args[I].y), 0, 6), "\n")
#end
[END CODE]
This scene runs fine with the 3rd and 7th arguments; it does not halt
with a parse error until it gets to the last argument.
Perhaps "unless both A and B are zero" could be added to the documentation.
Post a reply to this message


 
 




 
 


On 17/10/2021 23:46, Cousin Ricky wrote:
> ...
> Of course, the inverse tangent of A/0 is undefined, because A/0 is
> undefined. But a simple limits exercise, as well as the very definition
> of the tangent of an angle, show that these undefined tangents
> correspond to the angles pi/2 and pi/2, and it is therefore useful to
> pretend that they are valid.
>
> The purpose of atan2() is to handle these special cases, by converting a
> naive atan()'s argument into an ordered pair, thus allowing the wouldbe
> inverse tangent of A/0 to be computed without having to divide by 0. A
> simple scene file shows that the *only* time atan2() fails with a domain
> error is when *both* A and B are zero. Of course, (0, 0) is an
> indeterminate case, for which returning a value would be nonsensical.
> ...
Cousin Ricky is right about everything!
And therefore, my problem is when A AND B are equal to zero.
Lot of datas to deal with, the debugging will be long...
(i'm working on the visualization of complex functions with domain coloring)

Kurtz le pirate
Compagnie de la Banquise
Post a reply to this message


 
 




 
 


Le 20211018 à 11:42, kurtz le pirate a écrit :
> On 17/10/2021 23:46, Cousin Ricky wrote:
>
>> ... Of course, the inverse tangent of A/0 is undefined, because A/0 is
>> undefined. But a simple limits exercise, as well as the very definition
>> of the tangent of an angle, show that these undefined tangents
>> correspond to the angles pi/2 and pi/2, and it is therefore useful to
>> pretend that they are valid.
>>
>> The purpose of atan2() is to handle these special cases, by converting a
>> naive atan()'s argument into an ordered pair, thus allowing the wouldbe
>> inverse tangent of A/0 to be computed without having to divide by 0. A
>> simple scene file shows that the *only* time atan2() fails with a domain
>> error is when *both* A and B are zero. Of course, (0, 0) is an
>> indeterminate case, for which returning a value would be nonsensical.
>> ...
>
> Cousin Ricky is right about everything!
>
> And therefore, my problem is when A AND B are equal to zero.
>
> Lot of datas to deal with, the debugging will be long...
> (i'm working on the visualization of complex functions with domain
> coloring)
>
>
>
Add a test to see if both A and B are zero, and replace that with some
small value for B. It could be something like the following just before
the call to atan2 :
#if (A=0 ! B=0) #declare B= 0.001; #end
... atan2(A,B) ...
Post a reply to this message


 
 




 
 


Alain Martel <kua### [at] videotronca> wrote:
> > And therefore, my problem is when A AND B are equal to zero.
> >
> > Lot of datas to deal with, the debugging will be long...
> > (i'm working on the visualization of complex functions with domain
> > coloring)
> >
> >
> >
> Add a test to see if both A and B are zero, and replace that with some
> small value for B. It could be something like the following just before
> the call to atan2 :
>
> #if (A=0 ! B=0) #declare B= 0.001; #end
> ... atan2(A,B) ...
This problem seems to come up a fair number of times
http://news.povray.org/web.5d4222c54ed4290e4eec112d0%40news.povray.org
And I've had the same sorts of problems and even segmentation faults and core
dumps triggered by similar issues with acos and asin.
Off the top of my head, the way I see it, is that if you're taking atan2 (A/B),
and both A and B are zero, then let's assume arguendo that A is held constant at
zero throughout the evaluation of all B's. 0/N is always zero, so the above
suggested solution and past similar solutions seem to be a good way to address
the issue.
I typically use the usual 1x10^6 value used for coincident surface stuff and
whatnot in POVRay, but maybe Bill P or someone else could suggest a better
value, or that atan2 values could be graphed for a range of B values to get a
better idea of where the point of diminishing returns / insignificant
differences in results lies.
Perhaps it might be a good idea to have a few wrapper macros to perform these
calculations with effective and reliable protective measures proceding the
evaluation of atan2, asin, and acos.
Post a reply to this message


 
 




 
 


The Wikipedia page about atan2 (and some of the references cited there) give me
the impression that there is no truly *standard* way of implementing the
function.
"The realization of the function differs from one computer language to another."
Hmm, that doesn't sound good.
"The C function atan2, and most other computer implementations, are designed
to...always define atan2(0, 0). On implementations without signed zero, or when
given positive zero arguments, it is normally defined as 0. It will always
return a value...rather than raising an error or returning a NaN (Not a
Number)."
However...
"For systems implementing signed zero, infinities, or Not a Number (for example,
IEEE floating point)...these *may* return NaN or raise an exception when given a
NaN argument."
Then it gets more complex with such stuff as real vs. imaginaryand/orcomplex
numbers, "undefined" vs. "indeterminate" values, "signed 0" vs. "unsigned 0",
the two arguments sometimes being reversed, etc.
Various programs and computer languages handle the atan2(0,0) problem in
different ways and with different outcomes(!)
Much of this stuff is way over my head, as I am a NaM
(NotaMathematician :P ),
but the overall situation is surprising to me. And some of the explanations
border on the realm of mathematical 'philosophy'.
Post a reply to this message


 
 




 

