ゲームプログラミング技術集 
ひっと

線上の最近点を求める

線上の最近点を求める方法とプログラミング例を紹介

線上の最近点を求める(2次元 3次元)

ABを通る線に点Pから垂線をおろし、その交点Xを求めるには...

ABの単位ベクトルnと、ベクトルAPを内積します。
内積の結果から点Aと点Xの距離が分かります。
AXの距離 = ABの単位ベクトル ・ ベクトルAP
(※ベクトルABの後方に点Xがあると、AXの距離はマイナスの数値になります。そのまま計算に使ってください)
ABの単位ベクトルとAXの距離から、点Xの位置が計算できます。
点X = 点A + (ABの単位ベクトル * AXの距離)

線上の最近点 プログラミング例 (2次元)

3次元のプログラミング例へ

#include <math.h>

//頂点の定義
struct Vertex2D{
	double x;
	double y;
};
//ベクトルの定義(頂点と同じ)
#define Vector2D Vertex2D

//単位ベクトル生成
Vector2D ceate_unit_vector( Vector2D v )
{
	double len = pow( ( v.x * v.x ) + ( v.y * v.y ), 0.5 );//ベクトル長さ
	
	Vector2D ret;
	ret.x = v.x / len;
	ret.y = v.y / len;
	
	return ret;
}

//ベクトル内積
double dot_product(Vector2D vl, Vector2D vr) {
	return vl.x * vr.x + vl.y * vr.y;
}

//点Pと直線ABから線上最近点を求める
Vector2D NearPosOnLine(Vertex2D P, Vertex2D A, Vertex2D B )
{
	Vector2D AB,AP;//ベクトルAB AP

	AB.x = B.x - A.x;
	AB.y = B.y - A.y;
	AP.x = P.x - A.x;
	AP.y = P.y - A.y;

	//ABの単位ベクトルを計算
	Vector2D nAB = ceate_unit_vector(AB);

	//Aから線上最近点までの距離(ABベクトルの後ろにあるときはマイナス値)
	double dist_AX = dot_product( nAB, AP );

	//線上最近点
	Vector2D ret;
	ret.x = A.x + ( nAB.x * dist_AX );
	ret.y = A.y + ( nAB.y * dist_AX );
	
	return ret;
}

線上の最近点 プログラミング例 (3次元)

2次元のプログラミング例へ

#include <math.h>

//頂点の定義
struct Vertex3D{
	double x;
	double y;
	double z;
};
//ベクトルの定義(頂点と同じ)
#define Vector3D Vertex3D

//単位ベクトル生成
Vector3D ceate_unit_vector( Vector3D v )
{
	double len = pow( ( v.x * v.x ) + ( v.y * v.y ) + ( v.z * v.z ), 0.5 );	//ベクトル長さ

	Vector3D ret;
	ret.x = v.x / len;
	ret.y = v.y / len;
	ret.z = v.z / len;
	
	return ret;
}

//ベクトル内積
double dot_product(Vector3D vl, Vector3D vr) {
	return vl.x * vr.x + vl.y * vr.y + vl.z * vr.z;
}

//点Pと直線ABから線上最近点を求める
Vector3D NearPosOnLine(Vertex3D P, Vertex3D A, Vertex3D B )
{
	Vector3D AB,AP;//ベクトルAB AP

	AB.x = B.x - A.x;
	AB.y = B.y - A.y;
	AB.z = B.z - A.z;
	AP.x = P.x - A.x;
	AP.y = P.y - A.y;
	AP.z = P.z - A.z;

	//ABの単位ベクトルを計算
	Vector3D nAB = ceate_unit_vector(AB);

	//Aから線上最近点までの距離(ABベクトルの後ろにあるときはマイナス値)
	double dist_AX = dot_product( nAB, AP );

	//線上最近点
	Vector3D ret;
	ret.x = A.x + ( nAB.x * dist_AX );
	ret.y = A.y + ( nAB.y * dist_AX );
	ret.z = A.z + ( nAB.z * dist_AX );

	return ret;
}

戻る     次へ