是否可以使用Area对象检查与线的碰撞?
目前我正在这样做的方式不起作用:
运行时返回false。但线条非常清晰,触及矩形,实际上它完全在里面。
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.geom.Line2D;
public class collision {
public static void main(String[] args) {
Area area1 = new Area(new Rectangle(0, 0, 100, 100));
Area area2 = new Area(new Line2D.Double(0, 0, 100, 100));
System.out.println(isColliding(area1, area2));
}
public static boolean isColliding(Area area1, Area area2) {
if (area2 != null) {
Area collide1 = new Area(area1);
collide1.subtract(area2);
if (!collide1.equals(area1)) {
return true;
}
}
return false;
}
}
答案 0 :(得分:1)
我能够通过创建一个检查事物点的递归函数来解决这个问题。 设置深度越高,检查的准确度越高,但完成时间越长。我一直使用10作为我的深度(我认为沿着线检查2047点)并且我没有遇到任何性能损失。除非你的Area对象包含非常薄的部分,否则我认为你不需要更多。
如果您认为可以通过任何方式改进,我可以随意评论和修改我的方法:)
感谢ajb建议使用PathIterator,这让我有机会检查沿线的点。
public static boolean findPoints(Area area1, Line2D line1, int depth) {
Point p1 = new Point((int) (line1.getX2() + line1.getX1()) / 2,
(int) (line1.getY2() + line1.getY1()) / 2);
if (depth == 0) {
return false;
}
pointMiddle = new Point(p1);
if (area1.contains(p1)) {
return true;
} else {
return findPoints(area1, new Line2D.Double(p1, line1.getP2()),
depth - 1)
|| findPoints(area1, new Line2D.Double(line1.getP1(), p1),
depth - 1);
}
}
答案 1 :(得分:0)
如果正如您在评论中所说的那样,您知道始终会检查Line2D
和Rectangle
是否有冲突,那么您可以使用intersects
Line2D
方法(见javadoc):
public static void main(String[] args) {
Rectangle rect1 = new Rectangle(0, 0, 100, 100);
Line2D line2 = new Line2D.Double(0, 0, 100, 100);
System.out.println(isColliding(rect1, line2));
}
public static boolean isColliding(Rectangle2D rect1, Line2D line2) {
if (line2 != null) {
return line2.intersects(rect1);
}
return false;
}
测试一条线是否与更一般的Area
发生碰撞更加困难;我不认为图书馆里有这样的方法。如果Area
由矩形构成,您可以尝试保存List
个对象的数组(或Rectangle
),并测试该线是否与其中任何一个相交。另一种方法:您可以尝试使用contains
Area
方法,该方法测试区域是否包含点。如果Line2D
包含 <{1}}的端点,则该行与该区域发生冲突。如果两个端点都在区域之外,但该区域由直线(Area
)组成,则可以从多边形中检索每个线段并测试该线是否与每个线段相交。您可以使用area.isPolygonal()
执行此操作,然后在生成的路径迭代器上使用类似的内容:
area.getPathIterator(null)
double[] coords = new double[6];
double moveX, moveY, prevX, prevY, newX, newY;
while (!pathIterator.isDone()) {
switch (pathIterator.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
moveX = coords[0]; moveY = coords[1];
prevX = moveX; prevY = moveY;
break;
case PathIterator.SEG_LINETO:
newX = coords[0]; newY = coords[1];
if ([line2 intersects the line from (prevX,prevY) to (newX,newY)]) {
return true;
}
prevX = newX; prevY = newY;
break;
case PathIterator.SEG_QUADTO:
case PathIterator.SEG_CUBICTO:
throw new RuntimeException("What is a curve doing in my rectangle?");
case PathIterator.SEG_CLOSE:
// go back to the last SEG_MOVETO point, usually the first point
if ([line2 intersects the line from (prevX,prevY) to (moveX,moveY)]) {
return true;
}
prevX = newX; prevY = newY;
break;
}
}
中有一些方法可以测试一个线段是否与另一个线段相交。
注意:我根本没有测试过这个。我希望它有效。