## Atan?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
misol101
Posts: 448
Joined: 02 May 2016 18:20

### Atan?

Anybody happen to be sitting on an atan or atan2 batch macro?

This is the best I got at the moment:

Code: Select all

``````atan2.js:
WScript.Echo(Math.floor(Math.atan2(WScript.Arguments.Item(0),WScript.Arguments.Item(1))/Math.PI*180))

batch script:
cscript //nologo //e:javascript "atan2.js" !TXE! !TZE! >res.txt
set /p ERY=<res.txt
``````
Not good for realtime graphics.

Expert
Posts: 964
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

### Re: Atan?

Just about everything I could find online for how to calculate arctangent boiled down to "press the atan button on your calculator." Further digging ended up suggesting lookup tables and something called https://en.wikipedia.org/wiki/CORDIC, which I'm going to have to look into some more.

misol101
Posts: 448
Joined: 02 May 2016 18:20

### Re: Atan?

Here is a crude estimation of atan, based on the second answer at https://math.stackexchange.com/question ... roximation. I also had to handle the case where y is 0.

This could be improved upon in many ways, but it is acceptable for what I needed it for.

Code: Select all

``````@echo off
rem Calculates atan(x/y) in whole degrees
setlocal EnableDelayedExpansion
set /a x=%1, y=%2, mul=1,base=0, negmul=1
if !y! neq 0 (
set /a "a=(x*100)/y"
if !a! lss 0 set /a negmul=-1, a=-a
if !a! gtr 100 set /a "a=10000/a, mul=-1, base=90"

set /a "r=(a*(4500-1566*(a-100)/100))/10000"
set /a "r=(base+mul*r)*negmul"
) else (
set /a r=90
if !x! lss 0 set /a r=-90
if !x! equ 0 set /a r=0
)
echo %r%
``````

T3RRY
Posts: 40
Joined: 06 May 2020 10:14

### Re: Atan?

Here's a (golfed) marco conversion

Code: Select all

``````@Echo off
Setlocal DisableDelayedExpansion

(Set LF=^

%= Above Empty lines Required =%)

Set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"

::: usage: %atan%{X val}{Y val}{Return var}
Set atan=For %%n in (1 2)Do if %%n==2 (%\n%
For /F "tokens=1,2,3 Delims={}" %%x in ("!xyz!")Do (%\n%
set/a "m=1,_=0,n=1"%\n%
if not %%y==0 (%\n%
set/a "a=(%%x*100)/%%y"%\n%
if !a! lss 0 set/a "n=-1,a=-!a!"%\n%
if !a! gtr 100 set/a "a=10000/a,m=-1,_=90"%\n%
set/a "r=(!a!*(4500-1566*(!a!-100)/100))/10000"%\n%
set/a "r=(!_!+!m!*!r!)*!n!"%\n%
) else (%\n%
set/a r=90%\n%
if %%x lss 0 set/a r=-90%\n%
if %%x equ 0 set/a r=0%\n%
)%\n%
For %%o in (!r!)Do (Endlocal ^& Set "%%z=%%o")%\n%
)%\n%
) Else Setlocal EnabledelayedExpansion ^& set xyz=

%atan%{20}{1}{r.}
%atan%{79}{20}{r.2}
%atan%{79}{0}{r.3}
set r.
pause
``````
If decimal places are required, the old trick of suffixing the number of digits in each value of the operations with 0 and 'fixing' the result with substring modification to reinsert the decimal point should do the trick

Aacini
Expert
Posts: 1647
Joined: 06 Dec 2011 22:15
Location: México City, México

### Re: Atan?

I think this is the fastest method to evaluate ATAN with good precision:

Code: Select all

``````@echo off
setlocal EnableDelayedExpansion

rem Angles: 45.0000 22.5000 11.2500 5.6250 2.8125 1.4062 0.7031
rem Values below are: tan(angle) * 10000
set "TanTable=10000 4142 1989 985 491 246 123 " & rem NOTE the last space!

rem Values for test
rem Angles:     85    80    75    70    60     45    30    20    15    10     5
for %%t in (114300 56713 37320 27475 17321  10000  5774  3640  2679  1763   875) do (
set /P "=atan(angle)*10000=%%t, " < nul

rem The long SET command below calculate ATAN(%%t^) based on TanTable above
set /A "Y=%%t, x=10000, curAngle=450000, sumAngle=0,  sign=(Y>>31)|1, Xnew=X+sign*Y*(Tan=%TanTable: =)/10000, Y-=sign*X*Tan/10000, X=Xnew, sumAngle+=sign*curAngle, curAngle>>=1,  sign=(Y>>31)|1, Xnew=X+sign*Y*(Tan=%0),  sumAngle=(sumAngle+5000)/10000"

echo Angle = !sumAngle!
)

``````
This code uses CORDIC method with 7 elements. If you want more precision you may increase the number of elements and/or the factor used to multiply tangent values (10000 in this case). As complement, if less precision is enough for you, you may diminish the number of elements and/or the 10000 factor, so the method run faster.

You may also use shorter variable names, so the expression be shorter and run faster. The variable names are the same used in the CORDIC description.

Antonio

misol101
Posts: 448
Joined: 02 May 2016 18:20

### Re: Atan?

Thanks to both of you!