如何制作一个算法来检测点 (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&¤tY+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 + 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 那么点在这条线上。
您将需要处理将严格水平线作为边缘情况的情况。那些会破坏等式。
编辑:条件已更改
既然你想确定一个点离线有多远,我会说笛卡尔空间中点和线之间距离的公式是要走的路。见 Distance from a point to a line由两点定义的截面线。这个公式看起来很难看,但它很简单。
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/