Page 1 of 1
Atan?
Posted: 09 Jun 2020 12:23
by misol101
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.
Re: Atan?
Posted: 09 Jun 2020 12:54
by ShadowThief
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.
Re: Atan?
Posted: 09 Jun 2020 17:03
by misol101
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%
Re: Atan?
Posted: 09 Jun 2020 21:54
by T3RRY
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
Re: Atan?
Posted: 11 Jun 2020 19:59
by Aacini
I think this is the fastest method to evaluate ATAN with good precision:
Code: Select all
@echo off
setlocal EnableDelayedExpansion
rem CORDIC reference: https://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf
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
Re: Atan?
Posted: 12 Jun 2020 01:40
by misol101
Thanks to both of you!