如何检查圆圈是否相互交叉?

时间:2016-03-05 20:22:59

标签: java algorithm runtime-error

这是我的测试课,

public class Shape2DTester {
public static void main(String[] args) {
GeometricObject2D geoObject1 = new ComparableCircle2D(0, 5, 2); 
GeometricObject2D geoObject3 = new ComparableCircle2D(0, 0, 2);
System.out.println("geoObject1 overlaps geoObject3: "
                + geoObject1.intersect(geoObject3));
}
}

这是我的圈子类,

 public class ComparableCircle2D extends GeometricObject2D<ComparableCircle2D> {

            public double x, y;
            public double radius;

            ComparableCircle2D() {
                super();
                this.radius = 1.0;
            }

            ComparableCircle2D(double radius) {
                super();
                this.radius = Math.abs(radius);
            }

            ComparableCircle2D(double x, double y, double radius) {
                super(x, y);
                this.radius = Math.abs(radius);
            }

            public double getArea() {
                return Math.PI * getRadius() * getRadius();
            }

            public double getPerimeter() {
                return 2 * Math.PI * getRadius();
            }

            public void setRadius(double setRadius) {
                this.radius = Math.abs(setRadius);
            }

            public double getRadius() {
                return radius;
            }
            public double getX() {
                    return x;
            }

            public void setX(double x) {
                    this.x = x;
            }

            public double getY() {
                    return y;
            }

            public void setY(double y) {
                    this.y = y;
            }

           @Override
            public boolean intersect(GeometricObject2D g) {
                    ComparableCircle2D other = (ComparableCircle2D) g;
                    double dx = other.x - getX();
                    double dy = other.y - getY();
                    double radi = other.radius + getRadius();
                    return (dx * dx + dy * dy < radi * radi);
            }

            }
        }

这是我的超类,

public abstract class GeometricObject2D<T extends GeometricObject2D> implements
        Comparable<GeometricObject2D> {
    public double x, y;

    GeometricObject2D() {
        this.x = 0;
        this.y = 0;
    }

    GeometricObject2D(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public abstract double getArea();

    public abstract double getPerimeter();

    public abstract boolean intersect(GeometricObject2D g);

    @Override
    public int compareTo(GeometricObject2D o) {
        // TODO Auto-generated method stub
        return 0;
    }
}

我想找出交叉两个圆圈的可能性,但我的代码中有一个我没有意识到的错误。

例如,我创建了两个圆形对象坐标-1(0,0) radius-1 = 2 坐标-2(0,5) radius-2 = 2 。上面的方法必须返回false但返回true。我没有发现错误。

System.out.println("geoObject1 intersects geoObject3: "
                + geoObject1.intersect(geoObject3));

打印geoObject1 intersects geoObject3: true

3 个答案:

答案 0 :(得分:3)

正如@Pshemo所说,你的代码(现在你已经显示它)在最后还有一个额外的dx² + dy² = 0 < dr²,不应该存在。

如果我们将所有代码粘贴到IDEONE并运行它,我们会确认您的错误。

如果我们通过添加单个}语句 DEBUG 代码,我们会看到:

print

嗯,为什么dx=0.0, dy=0.0, radi=4.0 应该是dy = 0

答案:因为您已将另一个5x字段集添加到您的子类中,即隐藏基类中的字段!!!!

简单的调试会自己向您展示。这就是@PeterLawrey在评论中所说的话:

  你错了很可能是;价值观不是你认为的。这是调试代码可以显示的地方。

当然,如果您使用了一个好的IDE,您甚至不需要调试,因为 IDE会警告您隐藏字段

答案 1 :(得分:1)

而不是Math.pow(x,2),更有效的做x * x,而不是使用Math.sqrt,你可以平方半径之和。

public boolean intersect(GeometricObject2D g) {
    ComparableCircle2D other = (ComparableCircle2D) g;
    double dx = other.x - x;  // e.g. 0 - 0
    double dy = other.y - y;  // e.g. 5 - 0
    double radii = other.radius + radius; // e.g. 2 + 2
    return dx * dx + dy * dy < radii * radii ; // e.g. 0 + 25 < 16 is false.
}

答案 2 :(得分:0)

您永远不会指定字段xy。因此dx = dy = 0。

您必须分配字段的值或使用超类中的字段(但您不应该在同一个对象中包含具有相同信息的字段,因此请删除在{{1}中创建的字段}})。

此外,如果您的圆圈被定义为轮廓而不是区域,则截取圆圈的测试不正确。考虑具有相同中心的2个圆具有不同半径的情况:ComparableCircle2D,但轮廓不相交;只有圆圈内的区域重叠。