平面上の最近点は、内積で求めることができます。
任意の点Aがあり、平面上の点Pと平面の法線ベクトルをNとすると...
平面上の最近点 = A - N * ( PA ・ N )
平面方程式(ax+by+cz+d=0)を使う場合は..
法線N = (a,b,c)
平面上の点P = (a*d, b*d, c*d)
と置き換えると同様に計算できます。
点+法線バージョンと、平面方程式バージョンがあります。平面の定義によって使い分けてください。
#include <math.h>
//3Dベクトル
struct Vector3D{
double x,y,z;
};
//3D頂点 (ベクトルと同じ)
#define Vertex3D Vector3D
//平面 ( ax+by+cz+d=0 ) // ※平面方程式の作成方法はこちら...
struct Plane {
double a,b,c,d;
};
//ベクトル内積
double dot_product( const Vector3D& vl, const Vector3D vr) {
return vl.x * vr.x + vl.y * vr.y + vl.z * vr.z;
}
//平面上の最近点を求める その1( P=平面上の点 N=平面の法線 )
Vertex3D NearPosOnPlane( const Vertex3D& A, const Vertex3D& P, const Vertex3D& N )
{
//PAベクトル(A-P)
Vector3D PA;
PA.x = A.x - P.x;
PA.y = A.y - P.y;
PA.z = A.z - P.z;
//法線NとPAを内積
//法線の順方向に点Aがあればd > 0、 逆方向だとd < 0
double d = dot_product( N, PA );
//内積値から平面上の最近点を求める
Vertex3D ret;
ret.x = A.x - ( N.x * d );
ret.y = A.y - ( N.y * d );
ret.z = A.z - ( N.z * d );
return ret;
}
//平面上の最近点を求める その2(平面方程式 ax+by+cz+d=0 を使う場合 )
Vertex3D NearPosOnPlane2( const Vertex3D& A, const Plane& plane )
{
//平面方程式から法線と平面上の点を求める
//平面の法線N( ax+by+cz+d=0 のとき、abcは法線ベクトルで単位ベクトルです )
Vector3D N;
N.x = plane.a;
N.y = plane.b;
N.z = plane.c;
//平面上の任意の点P (法線*dは平面上の点)
Vector3D P;
P.x = plane.a * plane.d;
P.y = plane.b * plane.d;
P.z = plane.c * plane.d;
return NearPosOnPlane( A,P, N );
}