3 D空間における平面の法線ベクトル計算

3016 ワード


3 D空間における平面の法線ベクトル計算
取平面上の3点は、それぞれ、P 1(x 1,y 1,z 1)、P 2(x 2,y 2,z 2)、P 3(x 3,y 3,z 3)、工夫ベクトル(dx,dy,dz)であり、法ベクトルは以下の式を満たす.
(x2-x1)*dx+(y2-y1)*dy+(z2-z1)*dz=0;
(x3-x1)*dx+(y3-y1)*dy+(z3-z1)*dz=0;
(x3-x2)*dx+(y3-y2)*dy+(z3-z2)*dz=0;
本質は、3つの未知数の3つの方程式を解く方程式のグループであり、クレム法則に基づいて、計算法ベクトルは以下の通りである.
bool flag=CalNormalVector(x1,y1,z1,x2,y2,z2,x3,y3,z3,dx,dy,dz);
if(flag)
{
    //    
}
else
{
    //     
}
bool CalNormalVector(float x1,float y1,float z1,float x2,float y2,float z2,float x3,float y3,float z3,
                     float &dx,float &dy,float &dz)
{
	//float a1,a2,b1,b2,c1,c2;
	//
	float _a1=x2-x1; float _b1=y2-y1; float _c1=z2-z1;
	float _a2=x3-x1; float _b2=y3-y1; float _c2=z3-z1;
	float _a3=x3-x2; float _b3=y3-y2; float _c3=z3-z2;
	//_a1x+_b1y+_c1z=0;
	//_a2x+_b2y+_c2z=0;
	//_a3x+_b3y+_c3z=0;
	//3    3             
	//    A
	//| _a1 _b1 _c1 |
	//| _a2 _b2 _c2 |
	//| _a3 _b3 _c3 |
	//     A     0,         
	float DA=_a1*_b2*_c3+_b1*_c2*_a3+_a2*_b3*_c1-_a3*_b2*_c1-_a1*_b3*_c2-_a2*_b1*_c3;
	if (DA!=0)
	{
		dx=0.0f;
		dy=0.0f;
		dz=0.0f;
		return false;
	}
	//---------------------------------------------//
	//     A    0,     
	//    x!=0     y!=0     z!=0   
	float x=0.0f,y=0.0f,z=0.0f;
	// z!=0   , z=-1
	//_a1x+_b1y=_c1;---(1)
	//_a2x+_b2y=_c2;---(2)
	//_a3x+_b3y=_c3;---(3)
	//  2     ,   (1)(2)
	x=0.0f;y=0.0f;
	bool flag3=GetTwoLineIntersection(_a1,_b1,_c1,_a2,_b2,_c2,x,y);
	if (flag3)//    
	{
		dx=-x;
		dy=-y;
		dz=1.0f;
		return true;
	}
	//     ,         
	// x!=0    x=-1,            
	//_b1y+_c1z=_a1;---(1)
	//_b2y+_c2z=_a2;---(2)
	//_b3y+_c3z=_a3;---(3)
	//  2     ,   (1)(2)
	y=0.0f;z=0.0f;
	bool flag1=GetTwoLineIntersection(_b1,_c1,_a1,_b2,_c2,_a2,y,z);
	if (flag1)//    
	{
		dx=1.0f;
		dy=-y;
		dz=-z;
		return true;
	}
	//     ,         
	// y!=0    y=-1,            
	//_a1x+_c1z=_b1;---(1)
	//_a2x+_c2z=_b2;---(2)
	//_a3x+_c3z=_b3;---(3)
	//  2     ,   (1)(2)
	x=0.0f;z=0.0f;
	bool flag2=GetTwoLineIntersection(_a1,_c1,_b1,_a2,_c2,_b2,x,z);
	if (flag2)//    
	{
		dx=-x;
		dy=1.0f;
		dz=-z;
		return true;
	}
	
	//        ,    
	return false;
}
の2つの未知数の2つの方程式の方程式のグループは、クレムの法則に基づいて以下のように解く.
 
  
bool GetTwoLineIntersection(float _a1,float _b1,float _c1,float _a2,float _b2,float _c2,float &x,float &y)
{
	//_a1x+_b1y=_c1;---(1)
	//_a2x+_b2y=_c2;---(2)
	//
	if (_c1==0&&_c2==0)
	{
		//2    2             
		//    B
		//| _a1 _b1 |
		//| _a2 _b2 |
		float DB=_a1*_b2-_a2*_b1;
		if (DB!=0)//     
		{
			x=0;
			y=0;
			return true;
		}
		else//    
		{
			x=0;
			y=0;
			return false;
		}
	}
	else
	{
		//2    2              
		//    B
		//| _a1 _b1 |
		//| _a2 _b2 |
		//
		float DB=_a1*_b2-_a2*_b1;
		if (DB!=0)//    
		{
			float dD1 = _c1 * _b2 - _c2 * _b1;
			float dD2 = _a1 * _c2 - _a2 * _c1;
			x = dD1 / DB;
			y= dD2 / DB;
			return true;
		}
		else//        
		{
			x=0;
			y=0;
			return false;
		}
	}
	return false;
}