java 找到直线和矩形的交集
java find intersection of Line and Rectangle
所以,我正在编写一个小游戏。
作为玩家,您在 2d space 中驾驶 space 飞船。
如果在扫描仪中被选中,我想要一个指向选定对象(如太阳或行星)的标记。
除了在屏幕边框处绘制标记外,一切正常。
这是我目前的程序:
我先画了一个马克笔
Marker
为了旋转标记,让它指向屏幕外对象的方向,我使用了这个算法。
double Marker_vec = Math.toDegrees(Vector2F.getAngle( SolarSystem.object_vectors[marker],center,player.pos));
public static double getAngle(Vector2F v1, Vector2F v2, Vector2F fixed)
{
double angle1 = Math.atan2(v1.ypos - fixed.ypos, v1.xpos - fixed.xpos);
double angle2 = Math.atan2(v2.ypos - fixed.ypos, v2.xpos - fixed.xpos);
return angle1 - angle2;
}
基本上我所做的是,在屏幕左侧取一个固定点,玩家船和对象的固定点,并获得这两条线之间的角度。
结果值是我必须打开我的标记的度数。
效果很好
Get angle
我的问题是显示在屏幕边缘。
我这样做的尝试是创建一个适合屏幕的矩形:
screen_rec = new Rectangle(0,0,Main.width-1,Main.height-1);
然后我使用 X、Y、宽度和高度的矩形值创建 4 条线,它们一起形成屏幕周围的矩形。
现在我想看看玩家和所选对象之间绘制的一条线是否与矩形的任何一条线相交并得到该点。
最后在这些坐标处显示旋转后的标记图像。
这是我的代码
marker_vec = Vector2F.getIntersectionPoint(line, Player.screen_rec);
public static Point intersection(Line2D lineA, Line2D lineB)
{
double x1 = lineA.getX1();
double y1 = lineA.getY1();
double x2 = lineA.getX2();
double y2 = lineA.getY2();
double x3 = lineB.getX1();
double y3 = lineB.getY1();
double x4 = lineB.getX2();
double y4 = lineB.getY2();
double d = (x1-x2)*(y3-y4) - (y1-y2)*(x3-x4);
if (d == 0) return null;
double xi = ((x3-x4)*(x1*y2-y1*x2)-(x1-x2)*(x3*y4-y3*x4))/d;
double yi = ((y3-y4)*(x1*y2-y1*x2)-(y1-y2)*(x3*y4-y3*x4))/d;
return new Point((int)xi,(int)yi);
}
public static Point[] getIntersectionPoint(Line2D line, Rectangle2D rectangle) {
Point[] p1 = new Point[4];
// Top line
p1[0] = intersection(line,
new Line2D.Double(
rectangle.getX(),
rectangle.getY(),
rectangle.getX() + rectangle.getWidth(),
rectangle.getY()));
// Bottom line
p1[1] = intersection(line,
new Line2D.Double(
rectangle.getX(),
rectangle.getY() + rectangle.getHeight(),
rectangle.getX() + rectangle.getWidth(),
rectangle.getY() + rectangle.getHeight()));
// Left side...
p1[2] = intersection(line,
new Line2D.Double(
rectangle.getX(),
rectangle.getY(),
rectangle.getX(),
rectangle.getY() + rectangle.getHeight()));
// Right side
p1[3] = intersection(line,
new Line2D.Double(
rectangle.getX() + rectangle.getWidth(),
rectangle.getY(),
rectangle.getX() + rectangle.getWidth(),
rectangle.getY() + rectangle.getHeight()));
return p1;
}
但不知何故标记只显示在屏幕的左上角。
我试图通过在绘图函数中减去 x 轴的宽度来解决它,但这没有用。
而且这些线无论如何都不应该有任何交点,因为玩家和对象之间的线不与该矩形线相交。
我将在评论中 post 图片展示它的外观
我刚刚尝试了几天,但找不到任何解决方案。
提前致谢
Spytrycer
我解决了。我摆脱了这条线:
if (d == 0) return null;
我画标记的时间不够长。
另外,我用 if 包围了绘图函数,并确保仅当角度为特定值时才显示标记。
所以,我正在编写一个小游戏。 作为玩家,您在 2d space 中驾驶 space 飞船。 如果在扫描仪中被选中,我想要一个指向选定对象(如太阳或行星)的标记。 除了在屏幕边框处绘制标记外,一切正常。
这是我目前的程序:
我先画了一个马克笔 Marker
为了旋转标记,让它指向屏幕外对象的方向,我使用了这个算法。
double Marker_vec = Math.toDegrees(Vector2F.getAngle( SolarSystem.object_vectors[marker],center,player.pos));
public static double getAngle(Vector2F v1, Vector2F v2, Vector2F fixed)
{
double angle1 = Math.atan2(v1.ypos - fixed.ypos, v1.xpos - fixed.xpos);
double angle2 = Math.atan2(v2.ypos - fixed.ypos, v2.xpos - fixed.xpos);
return angle1 - angle2;
}
基本上我所做的是,在屏幕左侧取一个固定点,玩家船和对象的固定点,并获得这两条线之间的角度。 结果值是我必须打开我的标记的度数。 效果很好
Get angle
我的问题是显示在屏幕边缘。
我这样做的尝试是创建一个适合屏幕的矩形:
screen_rec = new Rectangle(0,0,Main.width-1,Main.height-1);
然后我使用 X、Y、宽度和高度的矩形值创建 4 条线,它们一起形成屏幕周围的矩形。 现在我想看看玩家和所选对象之间绘制的一条线是否与矩形的任何一条线相交并得到该点。 最后在这些坐标处显示旋转后的标记图像。
这是我的代码
marker_vec = Vector2F.getIntersectionPoint(line, Player.screen_rec);
public static Point intersection(Line2D lineA, Line2D lineB)
{
double x1 = lineA.getX1();
double y1 = lineA.getY1();
double x2 = lineA.getX2();
double y2 = lineA.getY2();
double x3 = lineB.getX1();
double y3 = lineB.getY1();
double x4 = lineB.getX2();
double y4 = lineB.getY2();
double d = (x1-x2)*(y3-y4) - (y1-y2)*(x3-x4);
if (d == 0) return null;
double xi = ((x3-x4)*(x1*y2-y1*x2)-(x1-x2)*(x3*y4-y3*x4))/d;
double yi = ((y3-y4)*(x1*y2-y1*x2)-(y1-y2)*(x3*y4-y3*x4))/d;
return new Point((int)xi,(int)yi);
}
public static Point[] getIntersectionPoint(Line2D line, Rectangle2D rectangle) {
Point[] p1 = new Point[4];
// Top line
p1[0] = intersection(line,
new Line2D.Double(
rectangle.getX(),
rectangle.getY(),
rectangle.getX() + rectangle.getWidth(),
rectangle.getY()));
// Bottom line
p1[1] = intersection(line,
new Line2D.Double(
rectangle.getX(),
rectangle.getY() + rectangle.getHeight(),
rectangle.getX() + rectangle.getWidth(),
rectangle.getY() + rectangle.getHeight()));
// Left side...
p1[2] = intersection(line,
new Line2D.Double(
rectangle.getX(),
rectangle.getY(),
rectangle.getX(),
rectangle.getY() + rectangle.getHeight()));
// Right side
p1[3] = intersection(line,
new Line2D.Double(
rectangle.getX() + rectangle.getWidth(),
rectangle.getY(),
rectangle.getX() + rectangle.getWidth(),
rectangle.getY() + rectangle.getHeight()));
return p1;
}
但不知何故标记只显示在屏幕的左上角。 我试图通过在绘图函数中减去 x 轴的宽度来解决它,但这没有用。 而且这些线无论如何都不应该有任何交点,因为玩家和对象之间的线不与该矩形线相交。 我将在评论中 post 图片展示它的外观 我刚刚尝试了几天,但找不到任何解决方案。 提前致谢
Spytrycer
我解决了。我摆脱了这条线:
if (d == 0) return null;
我画标记的时间不够长。
另外,我用 if 包围了绘图函数,并确保仅当角度为特定值时才显示标记。