java中计算平面图形夹角

在代码中我们知道了ABC,DEF等六个点的坐标,现在需要求出∠A 和 ∠D 的度数。怎么计算?
(这个其实是一道数学题,只是需要我们用代码写出来,先来回顾一下之前的三角函数和反三角函数)


1、三角函数

  • 锐角三角函数

进行角度计算的时候,我们先来回顾一下三角函数,当我们需要计算某个角的三角函数时,我们可以通过构造直角三角形,即把这个角放到某个直角三角形中,然后利用这个直角三角形的三条边长进行相关的三角函数计算。

!!!注意,下面的对应关系只限于构造出来的直角三角形中,在普通的三角形中不适用


  • 任意角三角函数

在平面直角坐标系xOy中设∠β的始边为x轴的正半轴,设点P(x,y)为∠β的终边上不与原点O重合的任意一点,设r=OP,令∠β=∠α,则:

sinα = y / r;
cosα = x / r;
tanα = y / x;

其实也是通过构建直角三角形进行计算


2、反三角函数

百度百科-反三角函数

欧拉提出反三角函数的概念,并且首先使用了“arc+函数名”的形式表示反三角函数。
我们可以利用反三角函数求出对应角度的弧度。


3、向量夹角计算

  • 二维向量

求向量AB,向量AC 的夹角,向量DF,向量DE 的夹角

  • 向量求角度的计算公式
v1⋅v2=|v1||v2|cosθ

[向量v1] 点乘 [向量v2] 等于 [向量v1的长度] 乘以 [向量v2的长度] 再乘以 [向量v1和向量v2夹角的余弦]


  • 向量的点乘

向量的点乘,也叫向量的内积、数量积,对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,点乘的结果是一个标量(没有方向的数量值)。

点乘的几何意义是可以用来表征或计算两个向量之间的夹角(公式如上),以及在b向量在a向量方向上的投影。


  • 向量的模

向量→AB的大小也就是向量→AB的长度(或称模),记作|→AB|。
(没办法把箭头放到字母上面去,就这样写吧)


  • 向量角度计算
计算过程

4、代码计算

回到上面三角形的计算,我们可以按照向量角度计算的步骤来计算∠A 。
A、B、C 三个点的坐标我们都已经知道了,下面就用point[A/B/C]_[x/y]来进行表示

  • 1、向量
    →AB:(pointB_x - pointA_x ,pointB_y - pointA_y)
    →AC:(pointC_x - pointA_x ,pointC_y - pointA_y)

  • 2、向量的点乘 →AB · →AC
//向量的点乘
int vector = (pointB_x - pointA_x) * (pointC_x - pointA_x) + (pointB_y - pointA_y) * (pointC_y - pointA_y);

  • 3、向量的模乘 |→AB||→AC|
//向量的模乘
double sqrt = Math.sqrt(
        (Math.abs((pointB_x - pointA_x) * (pointB_x - pointA_x)) + Math.abs((pointB_y - pointA_y) * (pointB_y - pointA_y)))
      * (Math.abs((pointC_x - pointA_x) * (pointC_x - pointA_x)) + Math.abs((pointC_y - pointA_y) * (pointC_y - pointA_y)))
);

  • 4、∠A的余弦值
double cosA = vector / sqrt ;

  • 5、∠A的弧度
//反余弦计算弧度
double radian = Math.acos(vector / sqrt);

  • 6、∠A的度数
//弧度转角度制
int degree= (int) (180 * radian / Math.PI);

5、方法提取

代码中使用的根据点坐标计算角度的方法

/**
 * 
 * @param vertexPointX -- 角度对应顶点X坐标值
 * @param vertexPointY -- 角度对应顶点Y坐标值
 * @param point0X
 * @param point0Y
 * @param point1X
 * @param point1Y
 * @return
 */
private int getDegree(int vertexPointX, int vertexPointY, int point0X, int point0Y, int point1X, int point1Y) {
    //向量的点乘
    int vector = (point0X - vertexPointX) * (point1X - vertexPointX) + (point0Y - vertexPointY) * (point1Y - vertexPointY);
    //向量的模乘
    double sqrt = Math.sqrt(
            (Math.abs((point0X - vertexPointX) * (point0X - vertexPointX)) + Math.abs((point0Y - vertexPointY) * (point0Y - vertexPointY)))
                    * (Math.abs((point1X - vertexPointX) * (point1X - vertexPointX)) + Math.abs((point1Y - vertexPointY) * (point1Y - vertexPointY)))
    );
    //反余弦计算弧度
    double radian = Math.acos(vector / sqrt);
    //弧度转角度制
    return (int) (180 * radian / Math.PI);
}

推荐阅读更多精彩内容