向量是指在数学中用于表示大小和方向的量。在计算机科学中,向量通常用于表示物体的位置、速度和加速度等。在Java中,可以使用坐标系中两点之间的差异来计算向量之间的距离。
在二维空间中,向量通常表示为一个有序的数对(x, y),其中x和y分别表示向量在x轴和y轴上的分量。例如,向量(3, 4)表示一个向右3个单位和向上4个单位的向量。在三维空间中,向量通常表示为一个有序的三元组(x, y, z),其中x、y和z分别表示向量在x、y和z轴上的分量。
我们可以通过计算线段的向量,来判断手指(鼠标)在屏幕中的移动方向。速度等信息。可以通过向量计算两条线段的夹角度数等。
向量可以进行加法和减法运算。向量的加法运算是将两个向量的分量相加,得到一个新的向量。向量的减法运算是将一个向量的分量减去另一个向量的分量,得到一个新的向量。
而我们如何通过坐标获取线段的向量呢?很简单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的向量和。而减法也就是将+号跟换为-号而已。
}
我们得到的向量有什么用处呢?下面就是向量的一些简单使用场景了。
假如,我们有两个任意的坐标点,需要计算这两个坐标点连接的线段与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平行,无所谓顺时针逆时针)。
在上面计算了线段和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°,线条下面的就是0~180°
然后画一个米字格,每个线段的夹角就是45°。那么右边就是±45°。上面就是45°~135°了(PS:135=45+45+45)。
在前面,我们计算了如何获取线条和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 的情况。
关于向量也就是这些了。还有更多复杂的使用场景。这里就不扩展了,太复杂了。