已知平面三点坐标求其中两条边之间的夹脚

回首这篇两年前写的博客,算是自己觉得比较有意思的一篇了,那时候刚拿毕业证也就一年左右吧,在一家小公司写代码,然后一同事也是前辈向我讨教这个问题,问我有没有招编程解决这个问题。抱着试试看的态度立马就研究了起来,从理论到实践,也是第二次感觉到数学和代码的结合真的很奇妙(第一感觉神奇的是在学校实验室捣鼓四轴飞行器的pid算法,通过用微分和积分的以及比例控制对飞机的过去、现在、以及未来的飞行姿态做最佳调控)。学的一点数学基础还好没有交还给老师,查资料然后理论+实践花了一小会功夫算是把代码写出来了。虽然只是简单的一道数学题转变为C代码实现。但工作两年多了,确很少有找到这种编程的乐趣和感觉!

向量:既有大小又有方向的量叫向量。
向量的模:向量的长度称为向量的模,用符号| |表示。
零向量:长度为0的向量
单位向量:长度为1的向量平面中,设有向量a={x1, y1},向量b={x2, y2},则有
(1)       向量的加:a+b={x1+x2, y1+y2}
(2)       向量的减:a-b={x1-x2, y1-y2}
(3)       向量的点积(内积):a·b=|a|*|b|*cosθ=x1*x2 + y1*y2
(4)       向量的叉积(外积):a×b=x1*y2 - x2*y1 注:文中出现的*为数学乘法,×为叉积运算符。

 

三维中,设有向量a={x1, y1, z1},向量b={x2, y2, z2},

则a×b = {y1*z2-y2*z1, x2*z1-x1*z2, x1*y2-x2*y1}。注:点用()表示,如(x, y, z),而向量用{}表示,如{x, y, z}。

设有点A=(x1, y1),点B=(x2, y2),则由A到B可组成向量AB={x2-x1, y2-y1}(AB=-BA)。

 

平面中有两个向量a和b:
a∥b当且仅当a×b=0(0向量)
a⊥b当且仅当a·b=0
 
叉积的一个非常重要性质是,可以通过它的符号判断两矢量相互之间的顺逆时针关系:
若a×b > 0 , 则a在b的顺时针方向。
若a×b < 0, 则a在b的逆时针方向。
若a×b = 0,则a和b共线,方向相同或相反。


给出了坐标, 先求出两个向量的模,再求出两个向量的向量积
|a|=√[x1^2+y1^2]
|b|=√[x2^2+y2^2]
a*b=(x1,y1)(x2,y2)=x1x2+y1y2

cos=a*b/[|a|*|b|]=(x1x2+y1y2)/[√[x1^2+y1^2]*√[x2^2+y2^2]]


设a向量坐标为(x1,y1)b向量坐标为(x2,y2)则ab数量积a.b=x1x2+y1y2(注:a.b是数量积,a*b是向量积,是不一样的,不能弄混了.)

 

数量积等于两向量对应坐标相乘后相加,当夹角大于90度时便为负值

 

 

#include 
#include 
#include 
#include 

#define PI 3.1415926

double Get_angle(double Ax, double Ay, double Bx, double By, double Cx, double Cy)
{
	
	double AB = 0;//向量AB的模 
	double BC = 0;
	double Sab = 0.0, Sbc = 0.0, Sabc = 0.0;
	
	double val = 180.0 / PI;
	double angle = 0.0;

	
	AB = sqrt( pow(Ax-Bx,2) + pow(Ay-By,2) ) ;
	BC = sqrt( pow(Bx-Cx,2) + pow(By-Cy,2) ) ;
	
	printf("AB = %f\n", AB);
	printf("BC = %f\n", BC);
	
	Sab = (Bx - Ax) * (Cx - Bx);//向量 
	Sbc = (By - Ay) * (Cy - By);
	

	
	Sabc = sqrt( pow(Sab, 2) + pow(Sbc, 2) ); 
	
	printf("Sab = %f\n", Sab);
	printf("Sbc = %f\n", Sbc);
	printf("Sabc = %f\n", Sabc);
	
	angle =  acos( (Sabc/(AB*BC)) ) * val;	
	
	printf("Sab + Sbc = %f\n", Sab + Sbc);
	if( (Sab + Sbc) < 0 )
	{
		angle = 180.0 - angle;	
	}
	
	return angle;		
}

int main(void)
{
	double  ret = 0;
	//A(0,3)  B(0,0)  C(5,0)  90 正确
	//A(0,3)  B(0,0)  C( 3.464102,2)  120 正确
	//A(0,3)  B(0,0)  C( 3.464102,-2)  60 正确
	 
	
    ret = Get_angle(0, 3, 0, 0,-3.464102, 2.0);

    printf("ret = %f\n", ret);
    
    system("pause");
    return 0;
}

 

效果截图!算是复习了高中时的数学了!

 

已知平面三点坐标求其中两条边之间的夹脚_第1张图片

已知平面三点坐标求其中两条边之间的夹脚_第2张图片

已知平面三点坐标求其中两条边之间的夹脚_第3张图片

当然这里如果自己画图来理解验证的话就会更清晰了!

 

你可能感兴趣的:(linux应用编程)