Forum > General

Strange error with arccos()

<< < (2/12) > >>

wp:
Or, to complete it furthermore, here's a ready-to-use procedure for the conversion:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---uses  Math;procedure CartesianToPolar(x, y: Double; var r, phi: Double);begin  if (x = 0) and (y = 0) then    raise Exception.Create('Undefined polar coordinates for x=0 and y=0');  // Or maybe use some "acceptable" result (r=0, phi=0) to avoid the exception  r := sqrt(x*x + y*y);  phi := arctan2(y, x);end;

Paolo:
@wp, that is mathematically fine.
Infact when X=Y=0 phase is undefined... but for practical purposes once X=Y=0 that is the vector is null, or other phisical parameter does not exist, who cares of phase value ?
so usually the phase is put to 0. And in this sense it is what ARCTAN2 do in its code: if X=Y=0 it says result=0.
So this should be usually enough

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  r := sqrt(x*x + y*y);  phi := arctan2(y, x); 

Paolo:
on the occasion of this discussion I want to underline some aspects of the arctan2 calculus in math units which in my opinion should be modified


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function arctan2(y,x : float) : float;  begin    if (x=0) then      begin        if y=0 then          arctan2:=0.0        else if y>0 then          arctan2:=pi/2        else if y<0 then          arctan2:=-pi/2;      end    else      ArcTan2:=ArcTan(y/x);    if x<0.0 then      ArcTan2:=ArcTan2+pi;    if ArcTan2>pi then      ArcTan2:=ArcTan2-2*pi;  end;    
in the code above I see something inefficient

1- there should be a "begin..end" block after else, otherwise the final part is execute even if the result is already determinated


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function arctan2(y,x : float) : float;  begin    if (x=0) then begin      begin        if y=0 then          arctan2:=0.0        else if y>0 then          arctan2:=pi/2        else if y<0 then          arctan2:=-pi/2;      end    elsebegin <----- begin here, otherwise the two next "if" are executed but if X=0 this is useless !!!      ArcTan2:=ArcTan(y/x);    if x<0.0 then      ArcTan2:=ArcTan2+pi;    if ArcTan2>pi then      ArcTan2:=ArcTan2-2*pi;end; <-----------------------------  end;   
2- why the third check in the first "if" chain, if alerady checked Y=0 and Y>0 what is the meaning of testing furhter if  y<0 ?


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function arctan2(y,x : float) : float;  begin    if (x=0) then begin      begin        if y=0 then          arctan2:=0.0        else if y>0 then          arctan2:=pi/2        else //if y<0 then  <---- remove this          arctan2:=-pi/2;   <--- just do that      end    elsebegin <----- here, otherwise the two next if are perfomed but if X=0 this is useless !!!      ArcTan2:=ArcTan(y/x);    if x<0.0 then      ArcTan2:=ArcTan2+pi;    if ArcTan2>pi then      ArcTan2:=ArcTan2-2*pi;end; <----  end;   
3- finally the last part I simplified as follow (final implementation,) why add and subtract twice some values ?


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function MyArcTan2(Y, X : float) : float;begin  if (X = 0) then begin    if (Y = 0) then      Result:=0    else      if (Y > 0) then        Result:=0.5*pi      else        Result:=-0.5*pi  end  else begin    Result:=ArcTan(Y/X);    if (X < 0) then      if (Y < 0) then        Result:=Result-pi      else        Result:=Result+pi  end;end; 
any comment on that ?

Paolo:
@wp, I see now the comment in the code you showed


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---// Or maybe use some "acceptable" result (r=0, phi=0) to avoid the exception 
 :)

wp:

--- Quote from: Paolo on August 05, 2022, 09:49:32 am ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function MyArcTan2(Y, X : float) : float;begin  if (X = 0) then begin    if (Y = 0) then      Result:=0    else      if (Y > 0) then        Result:=0.5*pi      else        Result:=-0.5*pi  end  else begin    Result:=ArcTan(Y/X);    if (X < 0) then      if (Y < 0) then        Result:=Result-pi      else        Result:=Result+pi  end;end; any comment on that ?

--- End quote ---
Submit it to bugtracker so that i can be considered by the FPC devs.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version