Skip to main content

2点間の距離

2点間の距離のはなし

ゲームを作っているとよく2次元でも3次元でも2点間の距離を出したくなるよね。
それで登場するのが次の公式\

$p_1(x_1,y_1,z_1)$ と $p_2(x_2,y_2,z_2)$ があるときに、その2点の距離は

$$ dist = \sqrt{(x_2-x_1)^2+(y_2-y_1)^2+(z_2-z_1)^2} $$

で計算できる。というもの。
これはこれでよく使うし、計算は合ってます。(結構座標書くときに間違って混乱するよね)

DirectXのプログラム作ってるみなさんでは、ソースコードでは以下の様になると思います。

#include <iostream>

using std::cout;
using std::endl;

int main()
{
    //3次元空間上の2点
    XMFLOAT3 v1{ 2.0, 3.0, 4.0 };
    XMFLOAT3 v2{ 4.0, 6.0, 8.0 };

    //距離計算 2点間の距離
    float dist1 = sqrt((v1.x - v2.x) * (v1.x - v2.x) 
                     + (v1.y - v2.y) * (v1.y - v2.y)
                     + (v1.z - v2.z) * (v1.z - v2.z));
    cout << "距離(ふつうの計算) :" << dist1 << endl;
}

XMFLOAT3とかめんどくさい。。。


そんで、DirectXMathに以下のような関数があります。
XMVector3Length 関数

ある2点間の距離は、その2点を始点と終点(どっちがどっちでも同じだよ)とするベクトルの長さに他ならないので、2点をベクトル化してしまえば、この関数が結果を返してくれます。

#include <iostream>
#include <DirectXMath.h>

using namespace DirectX;
using std::cout;
using std::endl;

int main()
{
    //3次元空間上の2点
    XMFLOAT3 v1{ 2.0, 3.0, 4.0 };
    XMFLOAT3 v2{ 4.0, 6.0, 8.0 };

    //距離計算 2点間の距離
    float dist1 = sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y) + (v1.z - v2.z) * (v1.z - v2.z));
    cout << "距離(ふつうの計算) :" << dist1 << endl;

    XMVECTOR xv1 = XMLoadFloat3(&v1);
    XMVECTOR xv2 = XMLoadFloat3(&v2);
    float dist2 = XMVectorGetX(XMVector3Length(xv1 - xv2));

    cout << "距離(ベクトルの長さ): " << dist2 << endl;
}

XMVector3Length関数は戻り値がXMVECTOR型です(距離とか長さなのに)、これは最適化とかメモリ転送の都合でデータの幅を合わせておいて、大きさの揃ったデータだけを使うことで最適化を図っているからです。 戻ってくるデータは {length, length, length, length} になっています。 なので、x,y,z,wのどれかをとってやれば長さが取り出せます。

XMVECTORからデータを取り出す命令は

  • XMVectorGetX
  • XMVectorGetY
  • XMVectorGetZ
  • XMVectorGetW などが用意されているのでお好きなものをどうぞ。 これで、距離計算はDirectXMathさえ使っていれば簡単だね。