I tried to translate an interesting function, the function use is to detect if a line and a circle is collisioned.
Here is the delphi code
function TForm1.is_collide(lx1, ly1, lx2, ly2, cx, cy, cr: integer):boolean;
var
vx, vy : integer;
wx, wy : integer;
udotv : real;
d : integer;
begin
vx := (lx2-lx1);
vy := (ly2-ly1);
{ bagi dot product dengan panjang garis (nggak perlu di akar) }
udotv := ((cx-lx1) * vx + (cy-ly1) * vy) / (vx * vx + vy * vy);
{ untuk versi float, nggak usah di rounding }
wx := round(udotv * vx)+ lx1 - cx;
wy := round(udotv * vy)+ ly1 - cy;
d := round(sqrt(wx * wx + wy * wy));
{ collision kalau d < cr }
result := (cr-d) >= 0;
end;
And here is my attempt to translate it.
IsCollide proc uses esi edi lx1:dword, ly1:dword, lx2:dword, ly2:dword, _cx:dword, cy:dword, cr:dword
LOCAL vx,vy,wx,wy,udotv,d:dword
LOCAL cxlx,cxly:dword
LOCAL buff[256]:dword
LOCAL dvdr:dword
prog_start:
; vx := (lx2-lx1);
; vy := (ly2-ly1);
invoke GetDeltaXY,lx1,ly1,lx2,ly2
mov vx,edx
mov vy,eax
; dvdr:=(vx * vx + vy * vy)
xor edx,edx
mov eax,vx
mul eax
push eax
xor edx,edx
mov eax,vy
mul eax
add eax,dword ptr[esp]
pop ecx
mov dvdr,eax
; udotv = (cx-lx1) * vx + (cy-ly1) * vy;
; Mulai operasi
;(cx-lx1)
mov edx,_cx
sub edx,lx1
mov cxlx,edx
; *vx
xor edx,edx
mov eax,cxlx
mul vx
mov cxlx,eax
;(cy-ly1)
mov edx,cy
sub edx,ly1
mov cxly,edx
; *vy
xor edx,edx
mov eax,cxly
mul vy
add eax,cxlx
push eax
pop udotv
; Operasi udotv berakhir
;wx = (udotv * vx + lx1)-cx;
xor edx,edx
mov eax,udotv
mul vx
xor edx,edx
div dvdr
add eax,lx1
sub eax,_cx
mov wx,eax
;wy = (udotv * vy + ly1)-cy;
xor edx,edx
mov eax,udotv
mul vy
xor edx,edx
div dvdr
add eax,ly1
sub eax,cy
mov wy,eax
;d = sqrt(wx * wx + wy * wy);
xor edx,edx
mov eax,wx
mul eax
mov wx,eax
xor edx,edx
mov eax,wy
mul eax
add eax,wx
push eax
fild dword ptr[esp]
fsqrt
fistp dword ptr[esp]
pop d
; if d<cr then it is collisioned
mov eax,d
.if eax<cr
xor eax,eax
inc eax
.else
mov eax,0
.endif
prog_end:
ret
IsCollide endp
My code doesnot work and I dont know where is my fault. Can anyone help?
[]
Quote from: RotateRight on August 24, 2008, 10:32:46 PM
You could always see what the compiler did.
J.dpr.14: begin
004085F0 55 push ebp
004085F1 8BEC mov ebp,esp
004085F3 83C4E8 add esp,-$18
004085F6 53 push ebx
004085F7 56 push esi
004085F8 57 push edi
004085F9 8955FC mov [ebp-$04],edx
004085FC 8BF8 mov edi,eax
J.dpr.15: vx := (lx2-lx1);
004085FE 8BD9 mov ebx,ecx
00408600 2BDF sub ebx,edi
J.dpr.16: vy := (ly2-ly1);
00408602 8B7514 mov esi,[ebp+$14]
00408605 2B75FC sub esi,[ebp-$04]
J.dpr.19: udotv := ((cx-lx1) * vx + (cy-ly1) * vy) / (vx * vx + vy * vy);
00408608 8B4510 mov eax,[ebp+$10]
0040860B 2BC7 sub eax,edi
0040860D F7EB imul ebx
0040860F 8B550C mov edx,[ebp+$0c]
00408612 2B55FC sub edx,[ebp-$04]
00408615 0FAFD6 imul edx,esi
00408618 03C2 add eax,edx
0040861A 8945EC mov [ebp-$14],eax
0040861D DB45EC fild dword ptr [ebp-$14]
00408620 8BC3 mov eax,ebx
00408622 F7EB imul ebx
00408624 8BD6 mov edx,esi
00408626 0FAFD6 imul edx,esi
00408629 03C2 add eax,edx
0040862B 8945E8 mov [ebp-$18],eax
0040862E DB45E8 fild dword ptr [ebp-$18]
00408631 DEF9 fdivp st(1)
00408633 DD5DF0 fstp qword ptr [ebp-$10]
00408636 9B wait
J.dpr.22: wx := round(udotv * vx)+ lx1 - cx;
00408637 895DEC mov [ebp-$14],ebx
0040863A DB45EC fild dword ptr [ebp-$14]
0040863D DC4DF0 fmul qword ptr [ebp-$10]
00408640 E8B7A8FFFF call @ROUND
00408645 03F8 add edi,eax
00408647 2B7D10 sub edi,[ebp+$10]
0040864A 8BDF mov ebx,edi
J.dpr.23: wy := round(udotv * vy)+ ly1 - cy;
0040864C 8975EC mov [ebp-$14],esi
0040864F DB45EC fild dword ptr [ebp-$14]
00408652 DC4DF0 fmul qword ptr [ebp-$10]
00408655 E8A2A8FFFF call @ROUND
0040865A 0345FC add eax,[ebp-$04]
0040865D 2B450C sub eax,[ebp+$0c]
00408660 8BF0 mov esi,eax
J.dpr.24: d := round(sqrt(wx * wx + wy * wy));
00408662 8BC3 mov eax,ebx
00408664 F7EB imul ebx
00408666 8BD6 mov edx,esi
00408668 0FAFD6 imul edx,esi
0040866B 03C2 add eax,edx
0040866D 8945EC mov [ebp-$14],eax
00408670 DB45EC fild dword ptr [ebp-$14]
00408673 83C4F4 add esp,-$0c
00408676 DB3C24 fstp tbyte ptr [esp]
00408679 9B wait
0040867A E86DA8FFFF call Sqrt
0040867F E878A8FFFF call @ROUND
J.dpr.26: result := (cr-d) >= 0;
00408684 8B5508 mov edx,[ebp+$08]
00408687 2BD0 sub edx,eax
00408689 0F99C0 setns al
J.dpr.27: end;
0040868C 5F pop edi
0040868D 5E pop esi
0040868E 5B pop ebx
0040868F 8BE5 mov esp,ebp
00408691 5D pop ebp
00408692 C21000 ret $0010
I dont have delphi compiler, thanks.