平面三点计算夹角

纯数学问题,今天正好有人询问到,搜索复习几何知识,留此记录。

平面给定三点,计算夹角有三种方法:

1 使用向量计算

关于向量a和b,向量夹角余弦公式
   a*b = |a||b|cosTheta
所以 
   夹角 = acos(a*b) / (|a|*|b|)

两向量的数量积 = a.x*b.x + a.y*b.y

向量的模 = sqrt(x*x+y*y)

在二维下,计算量是最小的一种方法了(节约了sqrt计算),只需要一次acos

例,三个点A(1,1), B(2,1), C(2,2)

AB=(B.x-A.x, B.y-A.y)=(1,0)

AC=(C.x-A.x, C.y-A.y)=(1,1)

cosA = (AB*AC)/(|AB|*|AC|)=1/2=√2/2, 则夹角BAC=45度

2 余弦定理

cosA = (AB*AB + AC*AC - BC*BC ) / 2*AB*AC

例,三个点A(1,1), B(2,1), C(2,2)

cosA = (1+2-1)/2*1*2=1/2=√2/2, 则夹角A=45度

3 单独计算AB和AC的角度

分别求出直线AB, AC的斜率,得到对应的角度,两线角度之差即为夹角,考虑到夹角的方向,顺时钟夹角定为正

AB的角度:atan2(AB.y, AB.x)

AC的角度:atan2(AC.y, AC.x)

计算AB和AC的差


在JavaScript中使用第二种方法实现:

var lengthAB = Math.sqrt( Math.pow(pointA.X - pointB.X, 2) + 
                Math.pow(pointA.Y - pointB.Y, 2)),
    lengthAC = Math.sqrt( Math.pow(pointA.X - pointC.X, 2) + 
                Math.pow(pointA.Y - pointC.Y, 2)),
    lengthBC = Math.sqrt( Math.pow(pointB.X - pointC.X, 2) + 
                Math.pow(pointB.Y - pointC.Y, 2));
var cosA = (Math.pow(lengthAB, 2) + Math.pow(lengthAC, 2) - Math.pow(lengthBC, 2)) / 
                (2 * lengthAB * lengthAC);
var angleA = Math.round( Math.acos(cosA) * 180 / Math.PI );

Math反三角函数返回值是弧度,若需要的是角度时还应将弧度转换,如最末行所示。

你可能感兴趣的:(数学几何,平面三点,计算夹角,JavaScript)