写图形学算法时经常要用到,整理一下:
第一种方法 ,使用向量计算三个点ABC
AB=(b.x-a.x, b.y-a.y)
AC=(c.x-a.x, c.y-a.y)
cosA = (AB*AC)/(|AB|*|AC|)
这种方法好像很复杂,首先AB*AC,
|AB|,|AC|需要求两点间的距离
向量夹角余弦公式法具体举例:
比如已知三点M(1,1),A(2,2),B(2,1)求角度∠AMB
1.先求向量MA,MB
向量公式 MA=(A.x-M.x)i+(B.x-M.x)j
所以:
MA=(2-1,2-1)=(1,1)
MB=(2-1,1-1)=(1,0)
则两向量的数量积为:
MA*MB=1×1+1×0=1
2.求向量的模
向量的模=sqrt(x*x+y*y)
|MA|=√(1×1)+(1×1)=√2
|MB|=√(1*1)+(0*0)=√1
将以上结果带入向量夹角余弦公式得:
cos∠AMB=MA*MB/|MA|*|MB|=√2/2
则∠AMB=45度
C++代码实现之:
#include
求解图:
旋转的方向角如何判断呢,使用叉乘计算公式。ma-> X mab-> = (ma.x*mb.y - mb.x*ma.y)(k->) 系数为正即为逆时针,负为顺时针,0共线。
第二种方法 ,用余弦定理:
cosA = (b*b + c*c - a*a )/ 2*b*c
其中a,b,c为三点连线所成三角形三边边长,用上面第一种方法使用的求模公式可以求出模,或者用两点间距离公式求出:
d=√(p1.x-p2.x)^2+(p1.y-p2.y)^2。
第三种方法 ,其实就是分别求出直线AM,BM的斜率,得到对应的角度,两线角度之差即为夹角,考虑到夹角的方向,顺时钟夹角定为正。
计算方法代码(未验证):
分别求出两直线斜率,然后相减 #define PI 3.1415926535897 #define RADIAN(a) (a*PI/180.0) //根据角度获得弧度 #define ANGLE(r) (180.0*r/PI)//根据弧度获得角度 float GetRotateAngle(const POINT &ptAnchor,const POINT&ptOld,const POINT&ptNew) { float fRt; float dx,dy; float fAgO,fAgN; dx=ptOld.x-ptAnchor.x; dy=(ptOld.y-ptAnchor.y); if(dx==0) { if(dy>0) fAgO=90; else fAgO=-90; } else { fAgO=ANGLE(atan(dy/dx));//(90,-90)之间 } dx=ptNew.x-ptAnchor.x; dy=(ptNew.y-ptAnchor.y); if(dx==0) { if(dy>0) fAgN=90; else fAgN=-90; } else { fAgN=ANGLE(atan(dy/dx));//(90,-90)之间 } fRt=fAgO-fAgN; return fRt; }