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さえ使っていれば簡単だね。