2011-11-03 14 views
0

私のゲームでは、特定の時間に2つのオブジェクト間の距離を見つける必要があります。私の質問は、単にfindDistance関数を改良することができますか?私は何の問題もないようですが、私はそれがもっとうまくいったのか不思議です。また、3D設定でこれを行う場合、別の軸があるので、どのように計算するのですか?2つのオブジェクト間の距離を求める

#include <math.h> 
#include <iostream> 

struct point{float x, y;}; 

float findDistance(point &x, point &y) 
{ 
    float distance, tempx, tempy; 
    tempx = (x.x - y.x); 
    tempx = pow(tempx, 2.0f); 
    tempy = (x.y - y.y); 
    tempy = pow(tempy, 2.0f); 
    distance = tempx + tempy; 
    distance = sqrt(distance); 
    return distance; 
} 

int main() 
{ 
    point a, b; 
    a.x = -2; 
    a.y = -3; 
    b.x = -4; 
    b.y = 4; 

    std::cout << "The distance between point x and y is: " << findDistance(a, b) << std::endl; 
    return 0; 
} 

答えて

1

3D:x*xpos(x,2)を置き換える以外

float findDistance(point &x, point &y) 
{ 
    float distance, tempx, tempy, tempz; 
    tempx = (x.x - y.x); 
    tempx = tempx * tempx; //compiler _might_ be able to make this faster 
    tempy = (x.y - y.y); 
    tempy = tempy * tempy; 
    tempz = (x.z - y.z); 
    tempz = tempz * tempz; 
    distance = tempx + tempy + tempz; 
    distance = sqrt(distance); 
    return distance; 
} 

、これは最適化され、正確な/一般的なままですが、あなたは一般的な必要がない場合は、それが高速になりますすることはできません。

bool distanceLessThan(point &x, point &y, float distance) 
{ 
    float tempx, tempy, tempz, tempd; 
    tempx = std::abs(x.x - y.x); 
    tempy = std::abs(x.y - y.y); 
    tempz = std::abs(x.z - y.z); 
    if (tempx + tempy + tempz < distance) //for small distances, don't square 
     return true; 
    if (tempx + tempy + tempz > distance/2) //for large distances, don't square 
     return false; 
    tempx = tempx * tempx; 
    tempy = tempy * tempy; 
    tempz = tempz * tempz; 
    tempd = distance * distance; 
    if (tempx + tempy + tempz < tempd) 
     return true; 
    return false; 
} 
+1

「float distance」を関数変数としての入力「float distance」とし、スパゲッティコーディングを引き起こすマイクロ最適化を指定します。 –

+0

@SaeedAmiri:私はそれが醜い、混乱していることに同意します。 [Ideone](http://ideone.com/NtMut)とMSVC10では、私の比較は非常に速いと言われています(どれくらい比較することはできませんが、それは私の "空の"ループと同じかそれ以上の速さです)。コーデパッドはATMを破ったようです。 –

1

あなたの現在のアプローチは結構です、新たな連携のためだけに他の人のようにそれを追加します。距離を計算するために、あなたは同じ式を有するn個の次元のために実際に

struct point{float x, y,z;}; 

float findDistance(point &x, point &y) 
{ 
    float distance, tempx, tempy; 

    tempx = (x.x - y.x); 
    tempx = pow(tempx, 2.0f); 
    tempy = (x.y - y.y); 
    tempy = pow(tempy, 2.0f); 
    tempz = (x.z - y.z); 
    tempz = pow(tempz, 2.0f); 
    distance = tempx + tempy + tmpz; 
    distance = sqrt(distance); 
    return distance; 
} 

をしていますが、新しい次元を追加する必要があります。

1

3Dの場合は、

tempz = (x.z - y.z); 
tempz = pow(tempz, 2.0f); 
distance = tempx + tempy + tempz; 
のように、距離に tempzを追加してください。

ところで、 "それが壊れていない場合は、それを修正しないでください。すでに動作しているものを変更することについて心配する必要はありません。

1

私は一般捕虜に感じる(FOO、2)FOOよりも遅くなります* fooの

あなたの計算に使用すると、距離やsquare_of_distanceが十分である必要がある場合にも自問してみてください。あなたは、単にsquare_of_distancesを比較することができる代わりに、それ自体がそれによってSQRT

0

パウ()への呼び出しを保存する実際の距離は、一般的な浮動小数点指数のためのものである、とのために非効率的である大きいた距離見つける例えば

正方形を計算する。代わりに明白な乗法を使用してください。

0

ちょうどzを追加しますが、これよりもはるかに良いことはできません。あなたはpow(x、2)をx * xで置き換えることができますが、それはそれです。あなたは2つのオブジェクトが衝突したばかりか、距離を知る必要がない場合は、そこにいくつかの最適化がありますが、そうでない場合:

float findDistance(point &x, point &y) 
{ 
    float distance, tempx, tempy, tempz; 
    tempx = x.x - y.x; 
    tempy = x.y - y.y; 
    tempz = x.z - y.z; 
    distance = sqrt(tempx*tempx + tempy*tempy + tempz*tempz); 
    return distance; 
} 

は、あなたができる最善についてです。あなたは値によって渡す場合

0

あなたより良いパフォーマンスを得る可能性があります:

float findDistance(point a, point b) 
{ 
    a.x -= b.x; 
    a.x *= a.x; 
    a.y -= b.y; 
    a.y *= a.y 
    return sqrt(a.x * a.y); 
} 

ダックの答えをMooingあなたが知っておくべき他のすべてが含まれています。

0

私はpow機能を使用しません:

distance = tempx*tempx + tempy*tempy; 

を、あなたが衝突検出のために距離が必要な場合はsqrt()を呼び出す必要はありませんように、あなたは距離の二乗を使用して検討するかもしれません。

しかし、 "時期尚早な最適化"と80-20ルール(ランタイムの80%はコードの20%で費やされます)に注意してください。したがって、パフォーマンステストをいくつか実行してください。 findDistance関数では、最適化を開始します。

関連する問題