16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"Int32x32To64のインラインasm版"
この発言は #00788 裏目小僧 さんの線分の上かどうか(多角形) に対するコメントです
32bitの掛算をして64bitの結果が欲しい場合、DELPHI4 で拡張された
INT64に先に変換してから掛算させると64bitの掛算をするために非常に
効率が悪く速度が落ちるようです。
そこで WinAPIの同名の関数をインラインアセンブラで書いてみました。
function Int32x32To64(X, Y: Integer): int64;
asm
MOV EAX,X {register呼び出し規約の場合はXはEAXなのでホントは不要}
IMUL Y
end;
また、D3を使っていると前回掲示した内外判定や線上判定はTPointを16bit以
上で使っている場合には失敗します。といってINT64はありませんから 以下の
ような関数を書いてみました。
以下はD1では使えません D3でテストしています。
{掛算(32x32=64)して引算(64)しその結果が正かゼロか負なら1,0,-1を返す}
function MulSubSGN(a,b,c,d:integer):Integer;register;{-a*b + c*d}
asm
mov eax,a {a=eaxなのでホントは不要}
IMUL b {b=edx}
xchg c,eax {c=ecx}
xchg d,edx {dはregisterでもメモリ}
IMUL edx
sub eax,c {a*b-c*dに見えるが交換してるので注意}
sbb edx,d
je @pltest {edxがゼロなら 下位テスト}
jge @set1 {edxが正なら 1}
mov eax,-1 {edxが負なら-1}
jmp @exit
@SET1: mov eax,1
jmp @exit
@pltest:
cmp eax,0
jne @SET1
@exit:
end;
{ (-a*b+c*d)/(b^2+d^2) を計算するのだが (b^2+d^2)をま
ともに計算すると遅いので 概算して求めている }
function RoughDistance(a,b,c,d:integer):Integer;stdcall;{ (-a*b+c*d)/(b^2+d^2)}
asm
mov eax,a
IMUL b
mov a,eax
mov ecx,edx
mov eax,c
IMUL d
sub eax,a
sbb edx,ecx
mov a,eax
mov c,edx
{b^2+d^2}
mov eax,b
mov edx,d
test eax,eax
jns @absskp1
neg eax
@absskp1:
test edx,edx
jns @absskp2
neg edx
@absskp2:
cmp eax,edx
jge @swapSkp
xchg eax,edx
@swapSkp:
shr edx,1
add eax,edx
je @exit {ゼロなら割算が出来ない}
mov ecx,eax
{割算}
mov eax,a
mov edx,c
idiv ecx
@exit:
end;
----------------------------------------------------------
MulSubSGN は 内外判定 #786
if rx*dy>ry*rdx then inc (ct) else dec(ct);
を
if MulSubSGN(rx,dy,ry,rdx)< 0 then inc (ct) else dec(ct);
と置き換えて使う事が出来ます。
RoughDistance は rx,ry 先の dx,dyの線分までの距離を概算で求める演算
線の上の判定 #788 の
dlen:=abs(rx*dy-ry*dx) ;
dx:=abs(dx); dy:=abs(dy);
if dx>dy then slen:=dx*2+dy
else slen:=dy*2+dx; {距離は約2ピクセルに調整しています}
if dlen < slen then begin Result:=i; exit; end; {発見した}
以上の5行を
if abs(RoughDistance(rx,dy,ry,dx))<2 then
begin Result:=i; exit; end; {発見した}
と 置き換えて使います。
Original document by 裏目小僧 氏 ID:(GGA03463)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|