如何使用4个点定义java.awt.Rectangle?

时间:2017-02-27 19:26:20

标签: java awt

我想在A(16,14) B(12,18) C(8,14) D(12,10)处绘制一个带有四个四角的矩形。然后我想检查点P(12,11)是否在矩形内。

是否可以使用java.awt.Rectangle实现此目的?

我尝试了下面的代码并且无法正常工作(报告1, 1在矩形内部,当显然不是时):

Rectangle bounds = new Rectangle(16, 14);
bounds.add(12, 18);
bounds.add(8, 14);
bounds.add(12, 10);

System.out.println(bounds.contains(1,1)); // printing true which is not right

3 个答案:

答案 0 :(得分:1)

创建一个包含4个点的矩形非常容易。

首先,您需要选择一个任意点,并将点的x和y分别指定给xy。然后,创建一个带有参数(x, y, 0, 0)的矩形。之后,请致电add三次以添加其他积分。

在您的情况下,这将起作用:

Rectangle rect = new Rectangle(8, 14, 0, 0); // 8 and 14 are the smallerst x and y
rect.add(16, 14);
rect.add(12, 18);
rect.add(12, 10);
System.out.println(rect.contains(1,1)); // false

我为你写了一个方法:

public static Rectangle createRectangeWithPoints(Point p1, Point p2, Point p3, Point p4) {
    int x = p1.getX();
    int y = p1.getY();
    Rectangle rect = new Rectangle(x, y, 0, 0);
    rect.add(p2);
    rect.add(p3);
    rect.add(p4);
    return rect;
}

答案 1 :(得分:1)

java.awt.Rectangle不适合您的工作。 Rectangles用于表示屏幕绘制区域,其边长始终与x-y坐标系的轴平行。没有提供旋转角度。您指定的四边形是旋转的,因此检查Rectangle上的边界将包含您不想要的(8, 13)之类的点。见下图:

enter image description here

更好的选择是java.awt.Polygon。你可以通过

构建它
Polygon p = new Polygon(new int[] {16, 12, 8, 12}, new int[] {14, 18, 14, 10}, 4);

或者

Polygon p = new Polygon();
p.add(16, 14);
p.add(12, 18);
p.add(8, 14);
p.add(12, 10);

使用Polygon的主要问题是它实际上是用于操作图形元素,而不是真正设计用于非常好地处理非整数数学。如果您阅读Polygon.contains(double, double)的文档并按照说明内部性定义的链接,您会看到Polygon在其左下边界与Regtangle具有相同的问题。解决这个问题的一种方法是使用Polygon.contains(x, y, 1, 1),但这看起来有点矫枉过正。

更好的选择可能是使用java.awt.geom中的类。我个人的建议是使用Path2D.DoublePath2D.FloatGeneralPath也是选项,但它们的精确度有限。如果您没问题,请使用Path2D.Float作为偏好。

您将使用default constructor

构建路径
Path2D.Double p = new Path2D.Double();

你可以忽略容量和缠绕,因为你有一个微小和凸起的形状。现在使用moveTo填充路径以启动路径,lineTo添加点,然后closePath填写矩形并进行遏制工作:

p.moveTo(16, 14);
p.lineTo(12, 18);
p.lineTo(8, 14);
p.lineTo(12, 10);
p.closePath();

现在你应该看到点(8, 13)确实在你的形状之外:

System.out.println(p.contains(8, 13));

同样适用于(1, 1)

System.out.println(p.contains(1, 1));

答案 2 :(得分:0)

您的方法很聪明,但您使用的是Rectangle的错误构造函数。 two-int构造函数是Rectangle(int width, int height),它隐式地将左上角设置为(0, 0),这就是代码打印true的原因。

在添加剩余点之前,您需要将第一个点指定为零左宽度矩形的左上角。使用four-int构造函数:Rectangle(int x, int y, int width, int height)

Rectangle bounds = new Rectangle(16, 14, 0, 0);
bounds.add(12, 18);
bounds.add(8, 14);
bounds.add(12, 10);

System.out.println(bounds.contains(1,1));

现在请记住Rectangle.add(Point)文档中的以下引用:

  

添加一个点后,使用添加的点作为参数调用contains不一定返回true。对于Rectangle右边或底边的点,contains方法不返回true。因此,如果添加的点落在放大的Rectangle的右边缘或底边缘上,则contains为该点返回false。如果指定的点必须包含在新的Rectangle中,则应添加1x1矩形:

r.add(newx, newy, 1, 1);

正如OP在他的评论中指出的那样,这在技术上是不正确的,因为没有相应的四元add方法。但是,如果矩形是数学结构而不是绘制对象,则可以使用add(Rectangle)方法:

Rectangle bounds = new Rectangle(16, 14, 1, 1);
bounds.add(new Rectangle(12, 18, 1, 1));
bounds.add(new Rectangle(8, 14, 1, 1));
bounds.add(new Rectangle(12, 10, 1, 1));

System.out.println(bounds.contains(1,1));