java - 用线检测拦截

标签 java algorithm math

如何制作一个算法来检测点 (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;
}
这有时有效,但并不总是一致的。
我把这个放在一个物理游戏中,我需要这个,这样球才能滚下一条线。
我有哪些方法可以改进它以使其正常工作?
编辑:多亏了 Felix Castor,我才能让它工作。这是最终的代码:
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;
}

最佳答案

使用斜率截距形式,您可以插入 x 并查看 y 是否相等。y = m*x + bm = (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 那么点在这条线上。
您将需要处理将严格水平线作为边缘情况的情况。那些会破坏等式。
编辑:条件已更改
既然你想确定一个点离线有多远,我会说笛卡尔空间中点和线之间距离的公式是要走的路。见 Distance from a point to a line由两点定义的截面线。这个公式看起来很难看,但它很简单。
enter image description here

  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
如果您对容差感兴趣,我认为这是一种更好的方法。

关于java - 用线检测拦截,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64992440/

相关文章:

java - Elastic Search 中的嵌套文档

以最小总距离连接所有点的算法

c++ - 使用 Dijkstra 的最大概率路径

c++ - 如何遵循调用自身的函数的流程?

Python/Numpy 它叫什么/你如何表示将两个向量的每个元素相乘的操作?

java - JPA : not overriding equals() and hashCode() in the entities?

Java - 在没有未经检查的强制转换的情况下,混合类型容器(非泛型类)是否可能?

c# - 如何以编程方式从值中删除/添加复合/非复合百分比和固定金额?

algorithm - 从样本中恢复订单

java - 列表信息聚合