Here is the final conclusion. As i thought, the exact distance (the SQR with floats, this is, Phythagoras algorithm) is the faster one and the more accurate in calculation
Code: Select all
; /// return approx distance between 2 points ///
; /// usage : approx_distance(x1-x2,y1-y2) ///
Procedure approx_distance(xx,yy)
xx=Abs(xx)
yy=Abs(yy)
If xx<yy
ProcedureReturn (yy<<8+yy<<3-yy<<4-yy<<1+xx<<7-xx<<5+xx<<3-xx<<1)>>8
Else
ProcedureReturn (xx<<8+xx<<3-xx<<4-xx<<1+yy<<7-yy<<5+yy<<3-yy<<1)>>8
EndIf
EndProcedure
Procedure.f distance(xx.f,yy.f)
!;finit
!fld dword[esp] ;push xx to FPU stack (to st0)
!fmul st0,st0
!fld dword[esp+4] ;push yy value to FPU stack (to st0) (xx is now in st1)
!fmul st0,st0
!faddp
!fsqrt
EndProcedure
Procedure.l approx_distanceASM(xx.l,yy.l)
!mov eax,dword[esp]
!mov ebx,dword[esp+4]
!cmp eax,0
!jnl @f
!neg eax
!@@:
!cmp ebx,0
!jnl @f
!neg ebx
!@@:
!cmp eax,ebx
!jnl @f
!xchg eax,ebx
!@@:
!mov edx,eax
!shl edx,1
!shl eax,3
!sub eax,edx
!shl edx,3
!sub eax,edx
!shl edx,4
!add eax,edx
!;
!mov edx,ebx
!shl edx,1
!shl ebx,3
!sub ebx,edx
!shl edx,4
!sub ebx,edx
!shl edx,2
!add ebx,edx
!;
!add eax,ebx
!shr eax,8
ProcedureReturn
EndProcedure
;-PROVE IT:
DisableDebugger
cx1=13:cx2=782:cy1=345:cy2=286
tt=gettickcount_()
For t=1 To 1000000
approx_distance(cx2-cx1,cy2-cy1)
Next
EnableDebugger
Debug gettickcount_()-tt
DisableDebugger
tt=gettickcount_()
!finit
For t=1 To 1000000
distance(cx2-cx1,cy2-cy1)
Next
EnableDebugger
Debug gettickcount_()-tt
DisableDebugger
tt=gettickcount_()
For t=1 To 1000000
approx_distanceASM(cx2-cx1,cy2-cy1)
Next
EnableDebugger
Debug gettickcount_()-tt
Debug ""
Debug approx_distance(cx2-cx1,cy2-cy1)
Debug distance(cx2-cx1,cy2-cy1)
Debug approx_distanceASM(cx2-cx1,cy2-cy1)
griz, take the best one for you.
And here can see the speed difference between call or not call to function:
Code: Select all
Procedure.f distance(xx.f,yy.f)
!fld dword[esp] ;push xx to FPU stack (to st0)
!fmul st0,st0
!fld dword[esp+4] ;push yy value to FPU stack (to st0) (xx is now in st1)
!fmul st0,st0
!faddp
!fsqrt
EndProcedure
DisableDebugger
cx1=13:cx2=782:cy1=345:cy2=286
xx.f=cx2-cx1:yy.f=cy2-cy1
result.f
tt=gettickcount_()
!finit
For t=1 To 1000000
!fld dword[v_xx] ;push xx to FPU stack (to st0)
!fmul st0,st0 ;xx^2
!fld dword[v_yy] ;push yy value to FPU stack (to st0) (xx is now in st1)
!fmul st0,st0 ;yy^2
!faddp ;xx^2+yy^2
!fsqrt ;hypotenuse, this is, SQR(xx^2+yy^2)
!fstp dword[v_result]
Next
EnableDebugger
Debug gettickcount_()-tt
DisableDebugger
tt=gettickcount_()
!finit
For t=1 To 1000000
distance(xx,yy)
Next
EnableDebugger
Debug gettickcount_()-tt
Debug ""
Debug result
Debug distance(cx2-cx1,cy2-cy1)