侧边栏壁纸
  • 累计撰写 416 篇文章
  • 累计创建 65 个标签
  • 累计收到 150 条评论

目 录CONTENT

文章目录

Java 通过向量,计算移动方向。计算线段角度等

Z同学
2023-04-04 / 0 评论 / 3 点赞 / 1,205 阅读 / 1,869 字
温馨提示:
本文最后更新于 2023-04-05,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1. 简介

向量是指在数学中用于表示大小和方向的量。在计算机科学中,向量通常用于表示物体的位置、速度和加速度等。在Java中,可以使用坐标系中两点之间的差异来计算向量之间的距离。

在二维空间中,向量通常表示为一个有序的数对(x, y),其中x和y分别表示向量在x轴和y轴上的分量。例如,向量(3, 4)表示一个向右3个单位和向上4个单位的向量。在三维空间中,向量通常表示为一个有序的三元组(x, y, z),其中x、y和z分别表示向量在x、y和z轴上的分量。

我们可以通过计算线段的向量,来判断手指(鼠标)在屏幕中的移动方向。速度等信息。可以通过向量计算两条线段的夹角度数等。

2. 获取线段的向量

向量可以进行加法和减法运算。向量的加法运算是将两个向量的分量相加,得到一个新的向量。向量的减法运算是将一个向量的分量减去另一个向量的分量,得到一个新的向量。

而我们如何通过坐标获取线段的向量呢?很简单x1-x2 就是向量x,y1-y2就是向量y。合起来就是向量在二维平面(直角坐标系)中的向量值:

   public static void getVectors(Point p1,Point p2,Point p3,Point p4){
        double ABx = p1.x - p2.x;
        double ABy = p1.y - p2.y;
        double CDx = p3.x - p4.x;
        double CDy = p3.y - p4.y;
       
        System.out.println("线段1的向量是: (" + ABx + ", " + ABy + ").");
        System.out.println("线段2的向量是: (" + CDx + ", " + CDy + ").");
       
       	//向量的加法:
         double[] sum = new double[2];
         sum[0] = ABx + CDx;
         sum[1] = ABy + CDy;
       	//得到的和sum就是一个新的向量了。是线段1和线段2的向量和。而减法也就是将+号跟换为-号而已。
    }

我们得到的向量有什么用处呢?下面就是向量的一些简单使用场景了。

3. 计算线段和X轴的角度

假如,我们有两个任意的坐标点,需要计算这两个坐标点连接的线段与X轴的夹角。

我们可以使用向量的知识,很简单的得到这个角度:

public double getDegrees(Point p1, Point p2) {
   //得到两个坐标点的差值, 其实得到的dx 和dy 就是我们线条的向量了
   double dx = p2.x - p1.x;
   double dy = p2.y - p1.y;
   double angleRadians = Math.atan2(dy, dx); // 根据该方法,可以直接获取坐标点和x轴的夹角,返回的是一个-π到π之间的弧度值
   double degrees = Math.toDegrees(angleRadians); //调用Math的API 将弧度转为角度,角度值范围为±180°。
   return degrees;
}

在这个方法中,我们传入的坐标点的Y值的大小,决定了角度的正负数。

如果p1的Y值大于p2,返回的就是:-179°~0 中间的值。

如果p1的Y值小于p2,返回的就是:0~180°中间的值。

我们如果结合手机或者电脑屏幕的坐标来计算。

简单理解就是,点p1在p2的上方,那么计算的就是从x轴出发顺时针的角度,也就是0~180°

而点p1在点p2的下方,那么计算的就是从x轴出发,逆时针的角度。也就是-179°~0。(因为180°的时候,p1和p2平行,无所谓顺时针逆时针)。

4. 根据用户移动轨迹,判断用户的移动方向

在上面计算了线段和X轴的夹角。我们其实可以根据这个角度,判断计算用户的移动轨迹。也就能得到用户手指或者鼠标的移动轨迹了。

示例如下:

   public static String getDegrees(Point p1, Point p2) {
        //得到线段的向量
        double dx = p2.x - p1.x;
        double dy = p2.y - p1.y;
       //得到线段和x轴的夹角弧度
        double angleRadians = Math.atan2(dy, dx);
       //zinyan.com 将弧度值转为角度值
        double degrees = Math.toDegrees(angleRadians);
        //根据角度确定方向
        if (degrees >= -45 && degrees < 45) {
            return "right";//从右往左,也就是所谓的右边进入
        } else if (degrees >= 45 && degrees < 135) {
            return "up"; //从下往上 ,也就是所谓的上部进入
        } else if (degrees >= -135 && degrees < -45) {
            return "down";//从上往下 ,也就是所谓的底部进入
        } else {
            return "left"; //其他的就是左边进入的了, 从左往右移动的轨迹
        }
    }

上面的角度比较值,其实45度比较好理解。我们平面画一条直线当做X轴。线条上面的就是0-180°,线条下面的就是0180°

然后画一个米字格,每个线段的夹角就是45°。那么右边就是±45°。上面就是45°~135°了(PS:135=45+45+45)。

5. 通过向量和角度,计算两个线条的夹角

在前面,我们计算了如何获取线条和X轴的夹角。我们如果有两条线段,那么如何获取这两条线段的夹角呢?

处理逻辑很简单,例如线段1和x轴的夹角是90°,线段2和x轴的夹角是130°。那么线段1和线段2的夹角应该是:130°-90°=40°

使用x轴当做基准点,进行处理,你会发现运算逻辑很简单,具体示例代码如下:

//p1和p2 组合成线段1,p3和p4组合成线段2
    public static double getDegress(Point p1,Point p2,Point p3,Point p4){
        //这里是p2-p1也可以是p1-p2 位置是无所谓的,只是要统一。如果x轴是p2-p1,那么y轴也得是p2-p1
        double d1x = p2.x - p1.x;
        double d1y = p2.y - p1.y;
        //这个的逻辑和上面一样,p3-p4或者p4-p3都可以
        double d2x = p4.x - p3.x;
        double d2y = p4.y - p3.y;
        //然后通过atan2 得到弧度,要注意了这个方法中必须是y轴值在前面,x轴值在后面
        //两个弧度相减,就是两个线段的夹角弧度
        double angle = Math.atan2(d1y, d1x) - Math.atan2(d2y, d2x);
        //将弧度,转为角度。并通过绝对值去除正负符号
        angle = Math.abs(Math.toDegrees(angle));
        if (angle > 180) {
            //因为线段夹角内角+外角=360°,
            // 如果超过180°了说明我们得到的是最大的外角了,而夹角应该是最小的角度,所以进行了360-angile
            angle = 360 - angle;
        }
        return angle;
    }

当我们使用向量和Math的API。你会发现计算角度等会很方便

Math.atan2() 方法返回从 X 轴到指定坐标点 (x,y) 之间的角度(以弧度为单位)。它是 Math.atan(y/x)的安全版,可以避免除数为 0 的情况。

6. 小结

关于向量也就是这些了。还有更多复杂的使用场景。这里就不扩展了,太复杂了。

3

评论区