我的“包含”算法出了什么问题?

时间:2013-12-08 20:20:59

标签: java algorithm geometry

与Java AWT的Rectangle2D课程密切建模,我有Rectangle POJO:

public class Rectangle {
    // The Coordinate of the upper-left corner of the Rectangle.
    private Coordinate upperLeft;   // upperLeft.getXVal() and upperLeft.getYVal()

    // The width of the Rectangle.
    private BigDecimal width;

    // The height of the Rectangle.
    private BigDecimal height;

    // Determine if we wholly contains otherRectangle. (no touching sides).
    @Override
    public boolean contains(Rectangle otherRectangle) {
        BigDecimal x = otherRectangle.getUpperLeft().getXVal();
        BigDecimal y = otherRectangle.getUpperLeft().getYVal();
        BigDecimal w = otherRectangle.getWidth();
        BigDecimal h = otherRectangle.getHeight();
        BigDecimal x0 = getUpperLeft().getXVal();
        BigDecimal y0 = getUpperLeft().getYVal();

        if(isSingularity() || w.doubleValue() <= 0.0 || h.doubleValue() <= 0.0)
            return false;

        return (
            x.doubleValue() >= x0.doubleValue() &&
            y.doubleValue() >= y0.doubleValue() &&
            (x.doubleValue() + w.doubleValue()) <= (x0.doubleValue() + getWidth().doubleValue()) &&
            (y.doubleValue() + h.doubleValue()) <= (y0.doubleValue() + getHeight().doubleValue())
        );
    }
}

当我执行以下代码时:

// r1 has upperLeft corner at (0,4), width = 6, height = 4
// r2 has upperLeft corner at (1,2), width = 1, height = 1
Rectangle r1 = new Rectangle(new Coordinate(0,4), 6, 4);
Rectangle r2 = new Rectangle(new Coordinate(1,2), 1, 1);

boolean result = r1.contains(r2);

答案是错误的!

注意,我用以下假设写了这个:

  • upperLeft坐标字段就是那个 - 矩形的左上角;这意味着:
  • 用于获得右上角坐标的伪代码是(upperLeft.x + width, upperLeft.y)
  • 用于获得左下角坐标的伪代码是(upperLeft.x, upperLeft.y - height)
  • 用于获得右下方坐标的伪代码是(upperLeft.x + width, upperLeft.y - height)

现在,我相信我的回报值有些不妥:

    return (
        x.doubleValue() >= x0.doubleValue() &&
        y.doubleValue() >= y0.doubleValue() &&
        (x.doubleValue() + w.doubleValue()) <= (x0.doubleValue() + getWidth().doubleValue()) &&
        (y.doubleValue() + h.doubleValue()) <= (y0.doubleValue() + getHeight().doubleValue())
    );

但我无法弄清楚我哪里出错了。有任何想法吗?

2 个答案:

答案 0 :(得分:2)

你的y不等式混淆了。因为您使用左上角作为起点,所以需要检查负方向的遏制。

enter image description here

上图显示r1(绿色)和r2(粉红色)。要修复代码,请进行以下调整

// y must be less than y0
y.doubleValue() <= y0.doubleValue()

// y - h must be greater than y0 - h0
(y.doubleValue() - h.doubleValue()) >= (y0.doubleValue() - getHeight().doubleValue())

答案 1 :(得分:1)

您似乎混淆了两个不同的坐标系。您的代码使用Y轴从上到下指向的坐标系(这通常用于计算机图形)。同时,您的注释参考标准数学坐标系,其中Y轴从下到上指向。

这就是为什么您的代码无法按预期运行的原因。

您需要决定使用哪个坐标系,然后修复代码或更改计算头部坐标的方式。