我怎样才能做一个算法来检测一个点(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;
}
这有时有效,但并不总是一致的。
我把这个和一个物理游戏放在一起,我需要这个,这样球就可以滚下一条线。
我有什么方法可以改进它使它工作?。
编辑:多亏了费利克斯·卡斯特,我才得以工作。以下是最终代码:
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;
}
1条答案
按热度按时间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,则点在直线上。
你将需要处理的情况下,你有严格的水平线作为边缘情况。这会毁了这个等式。
编辑:条件已更改
既然你想确定点离直线有多远,我想说笛卡尔空间中点和直线之间的距离的公式就是正确的方法。见点到线段的距离两点定义的直线。这个公式看起来很难看,但它是直截了当的。
和前面一样,测试点是(xt,yt),直线是由两个点(x1,y1)和(x2,y2)定义的。因为距离总是>=0,所以您的测试将是:
如果你对宽容感兴趣的话,我认为这是一个更好的方法。