lisp 计算三点的夹角_计算三点所形成的夹角的三种方法

本文详细介绍了计算三维空间中任意三点形成夹角的三种方法:1) 利用向量的点积和模长计算;2) 应用余弦定理;3) 直线斜率求差法。并提供了C++代码示例,包括叉乘判断方向。
摘要由CSDN通过智能技术生成

写图形学算法时经常要用到,整理一下:

第一种方法 ,使用向量计算三个点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 #include using namespace std; int main() { double x1,y1,x2,y2,x4,y4; // xy3 == xy2 cout << "input x1 and y1:"; cin >> x1 >> y1; cout << "input x2 and y2:"; cin >> x2 >> y2; cout << "input x4 and y4:"; cin >> x4 >> y4; double ma_x = x1 - x2; double ma_y = y1 - y2; double mb_x = x4 - x2; double mb_y = y4 - y2; double v1 = (ma_x * mb_x) + (ma_y * mb_y); double ma_val = sqrt(ma_x*ma_x + ma_y*ma_y); double mb_val = sqrt(mb_x*mb_x + mb_y*mb_y); double cosM = v1 / (ma_val*mb_val); double angleAMB = acos(cosM) * 180 / M_PI; cout << "Angel AMB = " << angleAMB << endl; return EXIT_SUCCESS; }

求解图:

旋转的方向角如何判断呢,使用叉乘计算公式。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; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值