回首这篇两年前写的博客,算是自己觉得比较有意思的一篇了,那时候刚拿毕业证也就一年左右吧,在一家小公司写代码,然后一同事也是前辈向我讨教这个问题,问我有没有招编程解决这个问题。抱着试试看的态度立马就研究了起来,从理论到实践,也是第二次感觉到数学和代码的结合真的很奇妙(第一感觉神奇的是在学校实验室捣鼓四轴飞行器的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;
}
效果截图!算是复习了高中时的数学了!
当然这里如果自己画图来理解验证的话就会更清晰了!