Dos Batch Math Library

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
Squashman
Expert
Posts: 4465
Joined: 23 Dec 2011 13:59

Re: Dos Batch Math Library

#46 Post by Squashman » 18 Nov 2015 15:22

I see it as a unary operator in my help.

Code: Select all

The /A switch specifies that the string to the right of the equal sign
is a numerical expression that is evaluated.  The expression evaluator
is pretty simple and supports the following operations, in decreasing
order of precedence:

    ()                  - grouping
    ! ~ -               - unary operators
    * / %               - arithmetic operators
    + -                 - arithmetic operators
    << >>               - logical shift
    &                   - bitwise and
    ^                   - bitwise exclusive or
    |                   - bitwise or
    = *= /= %= += -=    - assignment
      &= ^= |= <<= >>=
    ,                   - expression separator

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: Dos Batch Math Library

#47 Post by Ed Dyreen » 18 Nov 2015 15:42

Good for you, as you see not in my help but implemented luckily

Code: Select all

Microsoft Windows XP [versie 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\profSys\ADMIN>set /?
...
    ()                  - groepering
    * / %              - rekenkundige operators
    + -                 - rekenkundige operators
    << >>               - logische verschuiving
    &                   - And per bit
    ^                   - Uitsluitende Or per bit
    |                   - Or per bit
    = *= /= %= += -=   - toewijzing
      &= ^= |= <<= >>=
    ,                   - expressie-scheidingsteken
...

Squashman
Expert
Posts: 4465
Joined: 23 Dec 2011 13:59

Re: Dos Batch Math Library

#48 Post by Squashman » 18 Nov 2015 15:46

I would ask Microsoft for a patch to fix that!

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: Dos Batch Math Library

#49 Post by Ed Dyreen » 18 Nov 2015 15:49

I take, is ok :mrgreen:

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Dos Batch Math Library

#50 Post by penpen » 18 Nov 2015 17:01

Sad to say:
I could not find the sqrt algorithm, i was talking about above... .

All i could remember was, it bases on this one...
but somehow the appending is fixed, so that the in between results fit in signed int 32 bit numbers...
maybe someone could remember(/find?) it, when i post the scetch of the easier one:

Code: Select all

Example:
sqrt(201918) =
         2 digits groups  <- from decimal .
     20|19|18. = 449.35286(80...)
    - 1   <- topleft 1
    - 3   <- +2
    - 5   <- +2   (+2 as long as result >=0)
    - 7   <- +2   (4 numbers: 1, 3, 5, 7 => 4 is the first digit of the result)
     ------
   =  419   <- substract; append next group at the end
     - 81   <- current result * 2 *10 + 1 (. ignored)
     - 83   <- +2
     - 85   <- +2
     - 87   <- +2 (4 numbers=> next result digit: 4)
     --------
       8318   <- substract; append next group at the end
      - 881   <- current result * 2 *10 + 1 (. ignored)
      - 883   <- +2
      - 885   <- +2
      - 887   <- +2
      - 889   <- +2
      - 891   <- +2
      - 893   <- +2
      - 895   <- +2
      - 897   <- +2 (9 numbers=> next result digit: 9)
      --------
        31700 <- substract; append next group (add . to result, as next group is after decimal digit first time "00" default)
       - 8981 <- current result * 2 *10 + 1 (. ignored)
       - 8983 <- +2
       - 8985 <- +2 (3 numbers=> next result digit: 3)
       ---------
         475100 ...
        - 89861
        - 89863
        - 89865
        - 89867
        - 89869
          ----------
          2577500
         - 898701
         - 898703
         ------------
           78009600
          - 8987041
          - 8987043
          - 8987045
          - 8987047
          - 8987049
          - 8987051
          - 8987053
          - 8987055
           ------------
            611321600
           - 89870561
           - 89870563
           - 89870565
           - 89870567
           - 89870569
           - 89870571
            ------------
             7209820400   <- (>= 2^31-1; so last digit using signed int 32bit math)
            - 898705721
            - 898705723
            - 898705725
            - 898705727
            - 898705731
            - 898705733
            - 898705735
            - 898705737
             -------------
               2017472100 (< 8987057361 ==> next digit 0)
               -------------
               201747210000
                        ...
(If i only could remember its name... then it would be easy.)
(I hope the above is clear enough to be understand easily.)


penpen

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

Re: Dos Batch Math Library

#51 Post by Aacini » 18 Nov 2015 21:30

I recently wrote a fixed point square root Batch program based on the classical "long division" method that I posted in this SO question. This is the code:

Code: Select all

@echo off
setlocal

:nextNumber
   set "number="
   set /P "number=Number:      "
   if not defined number goto :EOF
   call :SquareRoot %number% sqrt=
   echo Square root: %sqrt%
   echo/
goto nextNumber


:SquareRoot number result=
setlocal EnableDelayedExpansion

rem Separate the number in aligned blocks of 2 digits each
for /F "tokens=1,2 delims=." %%a in ("%1") do set "int=%%a" & set "frac=%%b"
set /A i=11, f=10
:nextInt
   if not defined int goto nextFrac
   set /A i-=1
   set "block[%i%]=%int:~-2%"
   set "int=%int:~0,-2%"
goto nextInt
:nextFrac
   if not defined frac goto checkLastBlock
   set /A f+=1
   set "block[%f%]=%frac:~0,2%"
   set "frac=%frac:~2%"
goto nextFrac
:checkLastBlock
if %f% gtr 10 if "!block[%f%]:~1!" equ "" set "block[%f%]=!block[%f%]!0"

rem Get square root of first block: digit between 0 and 9
set /A num=block[%i%], iP1=i+1, addZeros=0
for /L %%r in (0,1,9) do (
   set /A r2=%%r*%%r
   if !r2! leq %num% set /A sqrt=%%r, remainder=num-r2
)

rem Get square root of next blocks
for /L %%i in (%iP1%,1,%f%) do (
   set /A remainder1=remainder*10+!block[%%i]:~0,1!, remainder2=remainder*100+1!block[%%i]!-100, sqrtT2=sqrt*2
   if !sqrtT2! equ 0 (
      rem The number started with zeros: no sqrt yet
      set "sqrt="
      set /A addZeros+=1
      for /L %%r in (0,1,9) do (
         set /A r2=%%r*%%r
         if !r2! leq !remainder2! set /A nextDigit=%%r, remainder=remainder2-r2
      )
   ) else if !remainder1! lss !sqrtT2! (
      rem There is no sqrt for this block
      set /A nextDigit=0, remainder=remainder2
   ) else (
      set /A nextDigit=remainder1/sqrtT2, test=sqrtT2*10+nextDigit, this=test*nextDigit
      if !this! gtr !remainder2! (
         rem Next digit is too large: decrease it
         set /A "times=(this-remainder2)/test+1"
         for /L %%t in (1,1,!times!) do if !this! gtr !remainder2! (
            set /A nextDigit-=1, test=sqrtT2*10+nextDigit, this=test*nextDigit
         )
      )
      set /A remainder=remainder2-this
   )
   set "sqrt=!sqrt!!nextDigit!"
)

for /L %%i in (1,1,%addZeros%) do set "sqrt=0!sqrt!"
set /A point=11-i
set "sqrt=!sqrt:~0,%point%!.!sqrt:~%point%!"
endlocal & set "%2=%sqrt%"
exit /B

In this program the precision is set to the number of decimals / 2 of the input number, but a very simple modification would allow to set it to a fixed number. Some examples:

Code: Select all

Number:      15625.000000
Square root: 125.000

Number:      625
Square root: 25.

Number:      64
Square root: 8.

Number:      9
Square root: 3.

Number:      0.25
Square root: 0.5

Number:      987654321987654321
Square root: 993807990.

Number:      1234567890123456789
Square root: 1111111106.

Number:      2.000000000000000000
Square root: 1.414213562

Antonio

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Math Library

#52 Post by einstein1969 » 22 Nov 2015 08:10

@Penpen
Thanks , the algorithm is clear and if I found the source I will post.

@Aacini
Antonio, The sqrt algorithm with many decimal is very good! I will study for increment my knowledge.

The last Integer SQRT 32Bit is very fast and stable. I have try to optimize but for now is unbeatable.
The performance is about 16 seconds for 46000*2 Sqrts

For who want to optimize i show my attemp:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

for /f "delims==" %%v in ('set') do set "%%v="
for /F %%a in ('copy /Z "%~F0" NUL') do set "CR=%%a"

rem The unbeatable!!
set  "Sqrt(N)=( M=(N),x=M/(11*1024)+40, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"

rem set  "Sqrt(N)=( M=(N), guess=x=(((M-1529513880)>>31)+1)*(4096)+(((M-12752040)>>31)+1)*(8192+2048+1024+512+256+128+64+32+4+1)+(((M-29928)>>31)+1)*(512+256+128+32+4+1)+31, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"
rem set  "Sqrt(N)=( M=(N), x=(((M-1529513880)>>31)+1)*4096+(((M-12752040)>>31)+1)*12261+(((M-29928)>>31)+1)*933+31, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"

rem set  "Sqrt(N)=( M=(N), guess=x=(((M-798345024)>>31)+1)*(16384)+(((M-84015555)>>31)+1)*(8192+2048+1024+256+128+64+32+16+8+4+2+1)+(((M-5904899)>>31)+1)*(2048+1024+512+128+64+32+16+2+1)+(((M-226575)>>31)+1)*(512+256+128+64+16+8+2+1)+(((M-2915)>>31)+1)*(128+32+16+1)+15, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"
rem i guess con intervalli sono più lenti!

rem http://www.mathpath.org/Algor/squareroot/algor.square.root.halley.htm
rem http://www.mathpages.com/home/kmath190.htm
Rem accelerate, 1 accelerate. Se N < 715827882 posso usare la convergenza geometrica. Altrimenti uso quella lineare.
set  "Sqrt(N)=( M=(N), g0=40+N/7000, q1=(0x7FFFFFFF-g0*g0*g0)/(3*g0), overflow=-(M-q1>>31), guess=x=overflow*( p=(g0*(p1=(g0*g0+3*M))/(3*g0*g0+M)) )+(2200+N/29500)*(1-overflow)+1, x1=x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"
Rem questa e' quella stabile.
set  "Sqrt(N)=( M=(N), g0=40+N/7000, overflow=-(M-(0x7FFFFFFF-g0*g0*g0)/(3*g0)>>31), x=overflow*(g0*(g0*g0+3*M)/(3*g0*g0+M))+(2200+N/29500)*(1-overflow)+1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"
rem fisso N=2086000 overflow
set  "Sqrt(N)=( M=(N), g0=40+N/7000, overflow=-(M-2086000>>31), x=-(M-2086000>>31)*(g0*(g0*g0+3*M)/(3*g0*g0+M))+(2200+N/29500)*(1+(M-2086000>>31))+1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"
rem ottimizzo la precedente
set  "Sqrt(N)=( M=(N), g0=40+N/7000, x=-(M-2086000>>31)*(g0*(g0*g0+3*M)/(3*g0*g0+M))+(2200+N/29500)*(1+(M-2086000>>31))+1, x=(M/x+x)>>1, x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"
rem lenta/slow

rem provo con meno iterazioni! una semplice nella quadratica
set  "Sqrt(N)=( M=(N), g0=23+N/1466, q1=(0x7FFFFFFF-g0*g0*g0)/(3*g0), overflow=-(M-q1>>31), guess=x=overflow*( p=(g0*(p1=(g0*g0+3*M))/(3*g0*g0+M)) )+(((M/(2151+N/29265)+(2151+N/29265))>>1 )+1)*(1-overflow), x1=x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"
rem ottimizzo precedente
set  "Sqrt(N)=( M=(N), g0=23+N/1466, x=-(M-(0x7FFFFFFF-g0*g0*g0)/(3*g0)>>31)*( p=(g0*(p1=(g0*g0+3*M))/(3*g0*g0+M)) )+(((M/(2151+N/29265)+(2151+N/29265))>>1 )+1)*(1+(M-(0x7FFFFFFF-g0*g0*g0)/(3*g0)>>31)), x=(M/x+x)>>1, x=(M/x+x)>>1, x+=(M-x*x)>>31 )"
rem lenta/slow

rem for %%s in (-2147483647, -1, 0, 1, 2, 3, 4, 9, 10, 16, 25, 100, 511, 512, 1000, 10000,
for %%s in (0, 1, 2, 3, 4, 9, 10, 16, 25, 100, 511, 512, 1000, 10000,
            65535, 65536, 100000, 131071, 131072, 262143, 262144, 393215, 393216,
            1000000, 2085999, 2086000, 5000000, 10000000, 100000000, 200000000, 1000000000, 2147395600, 2147483647) do (

  set /A "sqrt=!Sqrt(N):N=%%s!"
  rem echo Sqrt(%%s^)=!sqrt! - g0:!g0! q1:!q1! overflow:!overflow! p=!p! p1:!p1! guess:!guess! x1:!x1!
  if !overflow! equ 0 echo(
  echo Sqrt(%%s^)=!sqrt! - g0:!g0! overflow:!overflow! guess:!guess! x1:!x1!
)

pause

set "t1=!time: =0!"


rem < NUL (for /L %%n in (2,1,46340) do (
(for /L %%n in (2,1,46340) do (

   rem set /P "=%%n!CR!" <nul

   set /A "Num2=%%n*%%n, Num2M1=Num2-1, NM1=%%n-1"

   set /A "sqrt=%Sqrt(N):N=Num2M1%"
   if !sqrt! neq !NM1! echo failed on %%n- sqrt(!Num2M1!^) = !sqrt! & pause
   set /A "sqrt=%Sqrt(N):N=Num2%"
   if !sqrt! neq %%n echo failed on %%n- sqrt(!Num2!^) = !sqrt! & pause

))
rem if !overflow! equ 0 echo %%n & pause


for /F "tokens=1-8 delims=:.," %%a in ("!t1!:!time: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31)&8640000, FPS=10000/a"
Title Time Elapsed:!a!0ms - FPS: !FPS:~0,-2!.!FPS:~-2!
set a=&set t1=&set FPS=

pause

exit/b


I try to:
- Divide the interval to guess in more part. For better Guess.
- Accelerate the convergency. Via Halley's method (Householder)
- Mix.

These work well but the performance are lower.

The trick is guessing better. I have found a guess method that use LOG_x(N) (base x logarithm) but I have problem to implement.

This is my progress:

Code: Select all

rem Aacini example
set "Sqrt1(Num)=set /A "M=(Num),sqrt=M/(11*1024)+40,sqrt=(M/sqrt+sqrt)/2"&(for /L %%i in (1,1,5) do set /A "x2=(M/sqrt+sqrt)/2"^&if ^!x2^! leq ^!sqrt^! set /A sqrt=x2)"

Rem Macros
rem Logaritmo
Rem http://unija.ac.id/IT/en/indonesian-encyclopedia-2649/Babylonian-method_7399_unija.html
Rem http://akd-akuntansi-jayabaya.perut.info/_lain.php?_lain=7399
rem http://shipload.musikmart.com/IT/en/indonesian-cyclopedia-1558/Babylonian-method_7399_shipload-musikmart.html
rem http://sablon.baju.us/IT/en/pusat-ensiklopedis-1120/Methods-of-computing-square-roots_7399_sablon-baju.html
Rem For calculate Lenght(N) and store zero for calcolate 10^I
set "Len_Sqrt(N)=$=0000123456789AN"
rem calculate L= Lenght(N) = Number of DIGIT of N, if L is ODD L=2*I+1 else L=2*I+2, Q= if L is ODD 2 else 6
set "Sqrt(N)=( L=0x^!$:~-11,1^!, I=(L-1)/2, Q=(L&1)*2+((L+1)&1)*6)"
rem Calculate 10^I*Q
set "Sqrt1(N)=For %%$ in (^!I^!) do set /A "guess=^!q^!^!$:~0,%%$^!""

Rem Execute macros
set %Len_Sqrt(N):N=65536%
set /A "%Sqrt(N):N=65536%"
%Sqrt1(N)%"
echo %guess%
pause


Can anyone help me?

TODO:
- Compact two step of newton's method into one.

EDIT: The error graphics using LOG + line versus line here

Einstein1969

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Math Library

#53 Post by einstein1969 » 24 Nov 2015 12:19

Hi,

I have update the initial post adding other functions.
Than I have edit the post number 3 for quick functions reference.

I have implementated the Integer 32bit Cmp(x,y) function:

X<Y -> -1
X=Y -> 0
X>Y -> 1

Code: Select all

set "Cmp(x,y)=(x-y)>>31|((y-x)>>31&1)"
set /a "x=7, y=5, C=%cmp(x,y)%"



I have not implemented the 2 parameter substitute becouse I don't know wich method is better.

Einstein1969

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Math Library

#54 Post by einstein1969 » 01 May 2016 08:30

Hi,

I have optimized the Sign(x) removing unnecessary parenthesis and adding an alternate method.

Code: Select all

if %x% lss 0 (set /A "s=-1") else if %x% gtr 0 (set /A "s=1") else set /A "s=0"   & rem 55 microsec.
:: or
set "Sign(x)=(x)>>31 | -(x)>>31 & 1"     & rem 42 microsec.
:: or
set "Sign(x)=(x)>>31 | -(-(x)>>31)"      & rem 42 microsec.


The average execute time is show in the comment. It's calculated with an environment of standard size.

Einstein1969

IcarusLives
Posts: 161
Joined: 17 Jan 2016 23:55

Re: Dos Batch Math Library

#55 Post by IcarusLives » 28 Mar 2018 08:08

Sorry to dig this up, but I've found use out of this.

I was also wondering if it were possible to create a POW macro such as this? Thanks in advanced!!

IcarusLives
Posts: 161
Joined: 17 Jan 2016 23:55

Re: Dos Batch Math Library

#56 Post by IcarusLives » 30 May 2018 06:58

Hey, I wanted to share something I made last night. I thought maybe this would be useful

FIXED! Accuracy is 100%

Image

Code: Select all

@echo off & setlocal enableDelayedExpansion

for /l %%a in (1,1,20) do (
	set /a "rnd1=!random! %% 49 + 1", "rnd2=!random! %% 49 + 1"
	
	call :floatDIV !rnd1! !rnd2!
)

pause & exit

rem i says divide %~1 by %~2
rem bool says if %~1 is greater than %~2 return 0 if false or 1 if true
rem GY says get the modulus of (%~1-%~2) and %~2 divided by 2
rem LY says get the modulus of %~1 and %~2 divided by 2
:floatDIV
	rem	                                    BOOL                              GY                                                                            BOOL                                    LY
	set /a "i=%~1 / %~2", "f=((   ((~(%~1-%~2)>>31)&1)   *   ((10000 * (%~1 - %~2)) %% ((%~2) * 10000) / %~2)   )|((~  ((~(%~1-%~2)>>31)&1)    &1)*   (((%~1) * 10000) %% ((%~2) * 10000) / %~2)   ))"

	if "!f:~3!" equ "" set "f=0!f!"
	if "%~3" neq "" ( set "%~3=!i!.!f!" ) else ( echo %~1 / %~2 = !i!.!f! )
goto :eof

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Math Library

#57 Post by einstein1969 » 04 Jun 2018 08:21

IcarusLives wrote:
28 Mar 2018 08:08
Sorry to dig this up, but I've found use out of this.

I was also wondering if it were possible to create a POW macro such as this? Thanks in advanced!!
the pow function is reconducible to log function and exp function.

pow( x, y ) => exp( y * log( x ) )

I will try to attemp using this article https://www.quinapalus.com/efunc.html

einstein1969

IcarusLives
Posts: 161
Joined: 17 Jan 2016 23:55

Re: Dos Batch Math Library

#58 Post by IcarusLives » 04 Jun 2018 14:02

Thank you so much for the resources! I will research this.

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: Dos Batch Math Library

#59 Post by einstein1969 » 05 Jun 2018 08:44

IcarusLives wrote:
30 May 2018 06:58
Hey, I wanted to share something I made last night. I thought maybe this would be useful

FIXED! Accuracy is 100%

Image

Code: Select all

@echo off & setlocal enableDelayedExpansion

for /l %%a in (1,1,20) do (
	set /a "rnd1=!random! %% 49 + 1", "rnd2=!random! %% 49 + 1"
	
	call :floatDIV !rnd1! !rnd2!
)

pause & exit

rem i says divide %~1 by %~2
rem bool says if %~1 is greater than %~2 return 0 if false or 1 if true
rem GY says get the modulus of (%~1-%~2) and %~2 divided by 2
rem LY says get the modulus of %~1 and %~2 divided by 2
:floatDIV
	rem	                                    BOOL                              GY                                                                            BOOL                                    LY
	set /a "i=%~1 / %~2", "f=((   ((~(%~1-%~2)>>31)&1)   *   ((10000 * (%~1 - %~2)) %% ((%~2) * 10000) / %~2)   )|((~  ((~(%~1-%~2)>>31)&1)    &1)*   (((%~1) * 10000) %% ((%~2) * 10000) / %~2)   ))"

	if "!f:~3!" equ "" set "f=0!f!"
	if "%~3" neq "" ( set "%~3=!i!.!f!" ) else ( echo %~1 / %~2 = !i!.!f! )
goto :eof
for a complete add sub mul div you can view this work https://ss64.org/viewtopic.php?id=1838 I have implemented the karatsuba's multiply.

einstein1969

IcarusLives
Posts: 161
Joined: 17 Jan 2016 23:55

Re: Dos Batch Math Library

#60 Post by IcarusLives » 06 Feb 2019 23:41

How can we conjure up a a couple of math macros for this thread?

I really don't know how... but...

tan()
atan()
atan2()

These would be extremely useful! (at least to me they would be..) And I would really love to learn the math behind it if anyone could explain it or point me in the right direction to getting something like this together.

I am currently working on a project of physics. Right now, all there is is a bouncing ball/vector object. It will rotate and bounce upon collision with the bottom of the screen.

Code: Select all

@echo off & setlocal enableDelayedExpansion & mode 100,100

call:macros

set /a "GRAVITY=1", "MASS=1"
set /a "x=50", "y=3", "bAngle=90"
set "gravity(#)="a#+=(GRAVITY * MASS)", "v#+=a#", "a#*=0", "#+=v#""


for /l %%# in () do ( set /a "frames+=1"

	( %every% 3 frames ) && set /a "!gravity(#):#=y!"
	
	set /a "lx=7 * !cos(x):x=bAngle! + x", "ly=7 * !sin(x):x=bAngle! + y"
	set /a "vy=(((~(y-100)>>31)&1)*(vy*-1))|(((~(100-y)>>31)&1)*(vy*1))"
	set /a "bAngle=(((~(y-100)>>31)&1)*(bAngle*-1))|(((~(100-y)>>31)&1)*(bAngle*1))"
	set /a "bAngle=(((~(vy-0)>>31)&1)*(90))|(((~(0-vy)>>31)&1)*(270))"
	
	set "ball=" & for /l %%b in (0,30,360) do ( set /a "cx=2 * !cos(x):x=%%b! + x", "cy=2 * !sin(x):x=%%b! + y"
		set "ball=!ball!%esc%[!cy!;!cx!HÛ!esc![0m"
	)
	%line% !x! !y! !lx! !ly! 255
	
	<nul set /p "=%esc%[2J!ball!!screen!%esc%[6;6H!vy!" & set "screen="
)






rem initialize macros
:macros
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
for /F %%a in ('echo prompt $E^| cmd') do set "ESC=%%a"
<nul set /p "=!esc![?25l"
set "_SIN=a-a*a/1920*a/312500+a*a/1920*a/15625*a/15625*a/2560000-a*a/1875*a/15360*a/15625*a/15625*a/16000*a/44800000"
set "SIN(x)=(a=(x * 31416 / 180)%%62832, c=(a>>31|1)*a, a-=(((c-47125)>>31)+1)*((a>>31|1)*62832)  +  (-((c-47125)>>31))*( (((c-15709)>>31)+1)*(-(a>>31|1)*31416+2*a)  ), %_SIN%) / 10000"
set "COS(x)=(a=(15708 - x * 31416 / 180)%%62832, c=(a>>31|1)*a, a-=(((c-47125)>>31)+1)*((a>>31|1)*62832)  +  (-((c-47125)>>31))*( (((c-15709)>>31)+1)*(-(a>>31|1)*31416+2*a)  ), %_SIN%) / 10000"

set every=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-2" %%A in ("^!args^!") DO (%\n%
    set /A "rate=%%B %% %%A"%\n%
    if "^!rate^!" neq "0" ( set /a "=2+2"2^>nul )%\n%
)) else SET args=

set plot=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-4" %%1 in ("^!args^!") do (%\n%
	set "screen=^!screen^!!esc![%%2;%%1H!esc![38;5;%%3m%%~4!esc![0m"%\n%
)) else set args=

rem %getDistance% x2 x1 y2 y1 RETURNVAR
set getDistance=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-5" %%1 in ("^!args^!") do (%\n%
	set /a "%%5=( ?=((((((%%1 - %%2))>>31|1)*((%%1 - %%2)))-((((%%3 - %%4))>>31|1)*((%%3 - %%4))))>>31)+1, ?*(2*((((%%1 - %%2))>>31|1)*((%%1 - %%2)))-((((%%3 - %%4))>>31|1)*((%%3 - %%4)))-(((((%%1 - %%2))>>31|1)*((%%1 - %%2)))-((((%%3 - %%4))>>31|1)*((%%3 - %%4))))) + ^^^!?*(((((%%1 - %%2))>>31|1)*((%%1 - %%2)))-((((%%3 - %%4))>>31|1)*((%%3 - %%4)))-(((((%%1 - %%2))>>31|1)*((%%1 - %%2)))-((((%%3 - %%4))>>31|1)*((%%3 - %%4)))*2)) )"%\n%
)) else set args=

rem line x1 y1 x2 y2 color
set line=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-5" %%1 in ("^!args^!") do (%\n%
	if "%%~5" equ "" ( set "hue=30" ) else ( set "hue=%%~5")%\n%
	set /a "xa=%%~1", "ya=%%~2", "xb=%%~3", "yb=%%~4", "dx=%%~3 - %%~1", "dy=%%~4 - %%~2"%\n%
	for /f "tokens=1-2" %%6 in ("^!dx^! ^!dy^!") do (%\n%
		if %%~7 lss 0 ( set /a "dy=-%%~7", "stepy=-1" ) else ( set "stepy=1" )%\n%
		if %%~6 lss 0 ( set /a "dx=-%%~6", "stepx=-1" ) else ( set "stepx=1" )%\n%
		set /a "dx<<=1", "dy<<=1"%\n%
	)%\n%
	for /f "tokens=1-9" %%a in ("^!dx^! ^!dy^! ^!xa^! ^!xb^! ^!ya^! ^!yb^! ^!stepx^! ^!stepy^! ^!hue^!") do (%\n%
		if %%~a gtr %%~b (%\n%
			set /a "fraction=%%~b - (%%~a >> 1)"%\n%
			for /l %%x in (%%~c,%%~g,%%~d) do (%\n%
				for /f "tokens=1" %%6 in ("^!fraction^!") do if %%~6 geq 0 set /a "ya+=%%~h", "fraction-=%%~a"%\n%
				set /a "fraction+=%%~b"%\n%
				for /f "tokens=1" %%6 in ("^!ya^!") do ^!plot^! %%x %%~6 %%i Û%\n%
			)%\n%
		) else (%\n%
			set /a "fraction=%%~a - (%%~b >> 1)"%\n%
			for /l %%y in (%%~e,%%~h,%%~f) do (%\n%
				for /f "tokens=1" %%6 in ("^!fraction^!") do if %%~6 geq 0 set /a "xa+=%%~g", "fraction-=%%~b"%\n%
				set /a "fraction+=%%~a"%\n%
				for /f "tokens=1" %%6 in ("^!xa^!") do ^!plot^! %%~6 %%y %%i Û%\n%
			)%\n%
		)%\n%
	)%\n%
)) else set args=
goto :eof
Overall, my goal in the end is to have all sorts of ways to interact with the ball, and it react in a "physical" way.

I want to include some sort of "wind" per say. I can only imagine a cluster of invisible particles (vectors) pointing in a direction, and smashing into the "ball" object aforementioned. In my mind I imagine this would cause the ball to move as if the wind were pushing it.

For this I guess I could detect collision using this macro Aacini wrote for me.

Code: Select all

rem %getDistance% x2 x1 y2 y1 RETURNVAR
set getDistance=for %%# in (1 2) do if %%#==2 ( for /f "tokens=1-5" %%1 in ("^!args^!") do (%\n%
	set /a "%%5=( ?=((((((%%1 - %%2))>>31|1)*((%%1 - %%2)))-((((%%3 - %%4))>>31|1)*((%%3 - %%4))))>>31)+1, ?*(2*((((%%1 - %%2))>>31|1)*((%%1 - %%2)))-((((%%3 - %%4))>>31|1)*((%%3 - %%4)))-(((((%%1 - %%2))>>31|1)*((%%1 - %%2)))-((((%%3 - %%4))>>31|1)*((%%3 - %%4))))) + ^^^!?*(((((%%1 - %%2))>>31|1)*((%%1 - %%2)))-((((%%3 - %%4))>>31|1)*((%%3 - %%4)))-(((((%%1 - %%2))>>31|1)*((%%1 - %%2)))-((((%%3 - %%4))>>31|1)*((%%3 - %%4)))*2)) )"%\n%
)) else set args=
This leads me to WHY I need tan() atan() and atan2(), because since each wind particle is a vector "pointing" toward a target position, I can use these functions to calculate a pointing position.

Post Reply