Thanks Antonio!
This show me how to manage a multiply with about doubling the precision.
The next step is more difficult.
For more semplicity I partial ported the code:
Code: Select all
@echo off
setlocal EnableDelayedExpansion
rem setting batch canvas like. X*Y = 40*40 = 0..39*1..40
set /A width=40, height=40
rem Adjust for pretty results
set /a w=width+2, h=height+2
mode %w%,%h%
set w=&set h=
rem amount=number of particle, milliseconds=millisecond update
set /A amount=8, milliseconds=100
rem Sqrt macro
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 prepare screenbuffer
For /L %%l in (1,1,%width%) do set "_empty=!_empty! "
set "g=.@"
set /A factor = 9, min_proximity = 4*10000
rem create particle
for /L %%I in (1,1,%amount%) do call :particle %%I
for /L %%? in () do (
rem call :fading
call :acceleration_accumulation
rem delay
rem C:\windows\system32\pathping 127.0.0.1 -n -q 1 -p %milliseconds% >nul
rem Draw screenbuffer /canvas
cls & For /L %%l in (1,1,%height%) do echo( !L%%l!
For /L %%l in (1,1,%height%) do set L%%l=
)
exit /b
:acceleration_accumulation
for /L %%I in (1,1,%amount%) do (
rem title %%I
set /A Js=%%I+1
for /L %%J in (!Js!,1,%amount%) do (
set /A vec.x=p[%%I].pos.x-p[%%J].pos.x, vec.y=p[%%I].pos.y-p[%%J].pos.y
rem check for big number
if !vec.x! gtr 46340 (set /a "X2=vec.x/10*(vec.x/10)/100") else set /a X2=vec.x*vec.x/10000
if !vec.y! gtr 46340 (set /a "Y2=vec.y/10*(vec.y/10)/100") else set /a Y2=vec.y*vec.y/10000
set /A Len=X2+Y2
if !Len! gtr 0 set /A "Len=%Sqrt(N):N=Len%"
rem correct for sqrt fixed point. Not correct for Len^3 overflow
rem set /A Len*=100
rem now Len is multiply for 100 and not 10000
rem echo !len! prima %%I %%J !vec.x! !vec.y! !X2! !Y2!
set /A Len=Len*Len/100*Len/factor
rem echo !len! dopo
if !Len! equ 0 set Len=1
rem echo %%I %%J !x! !y! !p[%%I].pos.x! !p[%%J].pos.x! !p[%%I].pos.y! !p[%%J].pos.y!
rem pause
set /A "vec.x/=Len, y/=Len"
Rem this not work!
rem if !Len! gtr !min_proximity! set /A p[%%J].acc.x+=vec.x, p[%%J].acc.y+=vec.y, p[%%I].acc.x-=vec.x, p[%%I].acc.y-=vec.y
)
rem ###############################################################
rem Particle.step
rem validate acceleration . SI PUO' TOGLIERE?
rem if not defined x1 (x1=0,y1=0) OR if not defined y1 (x1=0,y1=0)
if not defined p[%%I].acc.x set /A p[%%I].acc.x=0, p[%%I].acc.y=0
if not defined p[%%I].acc.y set /A p[%%I].acc.x=0, p[%%I].acc.y=0
rem echo vel.x:!p[%%I].vel.x! vel.y:!p[%%I].vel.y!
set /A p[%%I].vel.x+=p[%%I].acc.x, p[%%I].vel.y+=p[%%I].acc.y
rem lenght: (x*x+y*y)^(1/2)
set /A speed=p[%%I].vel.x*p[%%I].vel.x/10000+p[%%I].vel.y*p[%%I].vel.y/10000
if !speed! gtr 0 set /A "speed=%Sqrt(N):N=speed%"
if !speed! gtr !speed_limit! set /A p[%%I].vel.x/=speed*10000/speed_limit, p[%%I].vel.y=speed*10000/speed_limit
rem echo !p[%%I].pos.x!+!p[%%I].vel.x! !p[%%I].pos.y!+!p[%%I].vel.y!
rem pause
set /A p[%%I].pos.x+=p[%%I].vel.x, p[%%I].pos.y+=p[%%I].vel.y
set /A p[%%I].acc.x=0, p[%%I].acc.y=0
rem X*Y = 40*40 = 0..39*1..40
if !p[%%I].pos.x! lss 0 set /A p[%%I].pos.x=0, p[%%I].vel.x=p[%%I].vel.x*-bounce_damping/10000
if !p[%%I].pos.y! lss 10000 set /A p[%%I].pos.y=10000, p[%%I].vel.y=p[%%I].vel.y*-bounce_damping/10000
set /A cw=%width%*10000-10000, ch=%height%*10000
if !p[%%I].pos.x! gtr !cw! set /A p[%%I].pos.x=cw, p[%%I].vel.x=p[%%I].vel.x*-bounce_damping/10000
if !p[%%I].pos.y! gtr !ch! set /A p[%%I].pos.y=ch, p[%%I].vel.y=p[%%I].vel.y*-bounce_damping/10000
rem ###############################################################
rem draw particle
set /A x=p[%%I].pos.x/10000, y=p[%%I].pos.y/10000
rem PLOTTING
if !y! lss 1 pause
if not defined L!y! set "L!y!=%_empty%"
For /F "tokens=1-3" %%x in ("!x! !y! 1") do (
set "L=!L%%y:~%%x!"
set "L%%y=!L%%y:~0,%%x!!g:~%%z,1!!L:~1!"
)
rem ###############################################################
)
exit /b
:particle
:: %1 particle index
rem particle initializing, fixedpoint
rem var initial_speed = 1 , var speed_limit = 4, bounce_damping = 0.5 =>10/2*1000
rem multiply by 2
set /A initial_speed = 2*10000, speed_limit = 8*10000, bounce_damping = 10/2*2*1000
set /A p[%1].acc.x=0, p[%1].acc.y=0
set /A p[%1].vel.x=!random!*10000/32767 * initial_speed/10000 - initial_speed * 10/2*1000 /10000
set /A p[%1].vel.y=!random!*10000/32767 * initial_speed/10000 - initial_speed * 10/2*1000 /10000
set /A p[%1].pos.x=!random!*10000/32768*width, p[%1].pos.y=!random!*10000/32768*height+10000 & rem X*Y = 40*40 = 0..39*1..40
rem set /A val=!random!*10000/32767 * initial_speed/10000
rem echo vel.x:!p[%1].vel.x! vel.y:!p[%1].vel.y! !val!
rem pause
exit /b
The question is the CUBE function with the next Division by "factor"
I think that its necessary to do a CUBE_DIV piece.
The problem is: store the result of CUBE and then DIVIDE or make a progressive multiple and divide how the showed code ?
Einstein1969