检查两个对象之间相交的算法
Algorithm to check intersection between two objects
我正在编写一个小游戏,但在交叉点上遇到了一些问题。我需要一种有效的算法来检查两个对象(具有 x 和 y 坐标以及宽度和高度)是否相交。
我尝试了以下方法,但它并不总是有效,有时它无法识别路口。
public boolean contains(int x, int y) {
if ((x < this.x + this.width) && (x >= this.x) && (y < this.y + this.height) && (y >= this.y))
return true;
else
return false;
}
我有一个包含对象的 ArrayList,我执行以下操作:
private boolean checkIntersection(String pDirection) {
for (int i = 0; i < walls.size(); i++) {
if (pDirection.equalsIgnoreCase("right") && car.contains(walls.get(i).getX() - 1, walls.get(i).getY()))
return true;
if (pDirection.equalsIgnoreCase("left") && car.contains(walls.get(i).getX() + 30, walls.get(i).getY()))
return true;
if (pDirection.equalsIgnoreCase("top") && car.contains(walls.get(i).getX(), walls.get(i).getY() + 30))
return true;
if (pDirection.equalsIgnoreCase("down") && car.contains(walls.get(i).getX(), walls.get(i).getY() - 1))
return true;
}
return false;
}
注意“-1”和“+30”是为了避免车进入"walls",那里的墙宽30,高30。车也有相同的尺寸.
另请注意,x 和 y 是矩形的左上角线。车和墙都是长方形的。
非常感谢您的帮助。
信息:如果我在墙上方并且我将方向更改为 "down" 或反之亦然,它不会识别一排墙开头的交叉点。
See picture
编辑 1(我尝试反转对象,但它也不总是有效):
private boolean checkIntersection(String pDirection) {
for (int i = 0; i < walls.size(); i++) {
if (pDirection.equals("right") && walls.get(i).contains(car.getX() + 30, car.getY()))
return false;
if (pDirection.equals("left") && walls.get(i).contains(car.getX() - 1, car.getY()))
return false;
if (pDirection.equals("top") && walls.get(i).contains(car.getX(), car.getY() - 1))
return false;
if (pDirection.equals("down") && walls.get(i).contains(car.getX(), car.getY() + 30))
return false;
}
return true;
}
你算法的缺陷是,你总是在检查墙的左上角是否在车里。但是,这并不等同于有交集。
相反,您应该检查任何一个对象是否(至少)包含另一个对象的一个角(不一定是左上角)。
请注意,您应该对两侧都执行此检查,即汽车包含墙的任何角或墙包含汽车的任何角。
我通过以下方式解决了修改 contains 方法,现在它完美地工作了:
public boolean contains(int x, int y) {
if ((x < this.x + this.width) && (x > this.x-this.width) && (y < this.y + this.height) && (y > this.y-this.height))
return true;
else
return false;
}
我认为我是无意中这样做的(检查非交叉而不是交叉),但我可以使用@samgak 和@Gene 的 answer/suggestion 来优化它。谢谢,问题解决了。
我正在编写一个小游戏,但在交叉点上遇到了一些问题。我需要一种有效的算法来检查两个对象(具有 x 和 y 坐标以及宽度和高度)是否相交。
我尝试了以下方法,但它并不总是有效,有时它无法识别路口。
public boolean contains(int x, int y) {
if ((x < this.x + this.width) && (x >= this.x) && (y < this.y + this.height) && (y >= this.y))
return true;
else
return false;
}
我有一个包含对象的 ArrayList,我执行以下操作:
private boolean checkIntersection(String pDirection) {
for (int i = 0; i < walls.size(); i++) {
if (pDirection.equalsIgnoreCase("right") && car.contains(walls.get(i).getX() - 1, walls.get(i).getY()))
return true;
if (pDirection.equalsIgnoreCase("left") && car.contains(walls.get(i).getX() + 30, walls.get(i).getY()))
return true;
if (pDirection.equalsIgnoreCase("top") && car.contains(walls.get(i).getX(), walls.get(i).getY() + 30))
return true;
if (pDirection.equalsIgnoreCase("down") && car.contains(walls.get(i).getX(), walls.get(i).getY() - 1))
return true;
}
return false;
}
注意“-1”和“+30”是为了避免车进入"walls",那里的墙宽30,高30。车也有相同的尺寸.
另请注意,x 和 y 是矩形的左上角线。车和墙都是长方形的。
非常感谢您的帮助。
信息:如果我在墙上方并且我将方向更改为 "down" 或反之亦然,它不会识别一排墙开头的交叉点。 See picture
编辑 1(我尝试反转对象,但它也不总是有效):
private boolean checkIntersection(String pDirection) {
for (int i = 0; i < walls.size(); i++) {
if (pDirection.equals("right") && walls.get(i).contains(car.getX() + 30, car.getY()))
return false;
if (pDirection.equals("left") && walls.get(i).contains(car.getX() - 1, car.getY()))
return false;
if (pDirection.equals("top") && walls.get(i).contains(car.getX(), car.getY() - 1))
return false;
if (pDirection.equals("down") && walls.get(i).contains(car.getX(), car.getY() + 30))
return false;
}
return true;
}
你算法的缺陷是,你总是在检查墙的左上角是否在车里。但是,这并不等同于有交集。
相反,您应该检查任何一个对象是否(至少)包含另一个对象的一个角(不一定是左上角)。
请注意,您应该对两侧都执行此检查,即汽车包含墙的任何角或墙包含汽车的任何角。
我通过以下方式解决了修改 contains 方法,现在它完美地工作了:
public boolean contains(int x, int y) {
if ((x < this.x + this.width) && (x > this.x-this.width) && (y < this.y + this.height) && (y > this.y-this.height))
return true;
else
return false;
}
我认为我是无意中这样做的(检查非交叉而不是交叉),但我可以使用@samgak 和@Gene 的 answer/suggestion 来优化它。谢谢,问题解决了。