使用line检测拦截

rur96b6h  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(274)

我怎样才能做一个算法来检测一个点(x,y)是否与一条线相交(x1,y1,x2,y2)?
我已经试过了:

boolean onLine(float a, float b, float c, float d, float x, float y){
    boolean answer = false;
    float[] p1 = new float[] {a, b};
    float[] p2 = new float[] {c, d};
    float x_spacing = (p2[0] - p1[0]) / ((a+c)/2 + (b+d));
    float y_spacing = (p2[1] - p1[1]) / ((a+c)/2 + (b+d));
    List<float[]> line = new ArrayList();
    float currentX = 0;
    float currentY = 0;
    while(currentX+a<c&&currentY+b<d){
        currentX += x_spacing;
        currentY += y_spacing;
        line.add(new float[]{a+currentX, b+currentY});
    }
    for(int j = 0; j < line.size(); j++){
        if(x > line.get(j)[0]-x_spacing && x < line.get(j)[0]+x_spacing && y > line.get(j)[1]- 
        y_spacing && y < line.get(j)[1]+y_spacing){
            answer = true;
            println("Hit line!");
            break;
         }
    }
return answer;

}
这有时有效,但并不总是一致的。
我把这个和一个物理游戏放在一起,我需要这个,这样球就可以滚下一条线。
我有什么方法可以改进它使它工作?。
编辑:多亏了费利克斯·卡斯特,我才得以工作。以下是最终代码:

boolean onLine(float x1, float y1, float x2, float y2, float xt, float yt, 
               float wid, float hit){
    float Y = (y2 - y1)/(x2 - x1)* xt + y1 -(y2 - y1)/(x2 - x1) * x1;
    boolean answer = false;
    if(abs(Y - yt) < 5) answer = true;
    if(abs(Y - yt-hit) < 5) answer = true;
    if(abs(Y - yt-(hit/2)) < 5) answer = true;
    if(abs(Y - yt+hit) < 5) answer = true;
    if(abs(Y - yt+(hit/2)) < 5) answer = true;
    return answer;

}

ua4mk5z4

ua4mk5z41#

使用斜率截距形式,你可以插入你的x,看看y是否相等。 y = m*x + b m = (y2 - y1)/(x2 - x1) b = y1 - (y2 - y1)/(x2 - x1) * x1 所以方程变成 Y = (y2 - y1)/(x2 - x1)* X + y1 -(y2 - y1)/(x2 - x1) * x1 给定一个点(xt,yt),您可以将xt插入x,然后计算结果并与yt进行比较。如果它们相等,则点在直线上。
如果y==yt给定xt,则点在直线上。
你将需要处理的情况下,你有严格的水平线作为边缘情况。这会毁了这个等式。

编辑:条件已更改

既然你想确定点离直线有多远,我想说笛卡尔空间中点和直线之间的距离的公式就是正确的方法。见点到线段的距离两点定义的直线。这个公式看起来很难看,但它是直截了当的。

double numerator = Math.abs((y2 - y1) * xt - (x2 - x1) * yt + x2 * y1 - y2 * x1);
  double denominator = Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2));
  double distance = numerator / denominator;

和前面一样,测试点是(xt,yt),直线是由两个点(x1,y1)和(x2,y2)定义的。因为距离总是>=0,所以您的测试将是:

if( distance <= tolerance) return true

如果你对宽容感兴趣的话,我认为这是一个更好的方法。

相关问题