Programming question determining two circle's relation

B

byhesed

What's wrong with contains and overlaps method in Circle2D class?
It returns incorrect answers.

- A method contains(double x, double y) returns true if the specified
point(x,y) is inside this circle.
- A method contains(Circle2D circle) returns true if the specified
circle is inside this circle.
- A method overlaps(Circle2D circle) return true if the specified
circle overlaps with this circle.

I calculate the distance between two circles:
- double distance = Math.sqrt(Math.pow(circle.x - getX(), 2.0) +
Math.pow(circle.y - getY(), 2.0));

It's wired too me because I think it is not wrong.


// TEST CODE
public class Exercise10_11 {
public static void main(String[] args) {
Circle2D c1 = new Circle2D(2, 2, 5.5);
System.out.println("Area is " + c1.getArea());
System.out.println("Perimeter is " + c1.getPerimeter());
System.out.println(c1.contains(3, 3));
System.out.println(c1.contains(new Circle2D(4, 5, 10.5)));
System.out.println(c1.overlaps(new Circle2D(3, 5, 2.3)));
}
}

// Circle2D Class
public class Circle2D {
private double x;
private double y;
private double radius;

public Circle2D() {
x = 0;
y = 0;
radius = 1;
}

public Circle2D(double x, double y, double radius) {
this.x = x;
this.y = y;
this.radius = radius;
}

public double getX() {
return x;
}

public double getY() {
return y;
}

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

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

public boolean contains(double x, double y) {
double distance = Math.pow(getX() - x, 2.0) + Math.pow(getY() - y,
2.0);
if (distance <= radius)
return true;
else
return false;
}

public boolean contains(Circle2D circle) {
double distance = Math.sqrt(Math.pow(circle.x - getX(), 2.0) +
Math.pow(circle.y - getY(), 2.0));
if (distance <= Math.abs(radius - circle.radius))
return true;
else
return false;

}

public boolean overlaps(Circle2D circle) {
double distance = Math.sqrt(Math.pow(circle.x - getX(), 2.0) +
Math.pow(circle.y - getY(), 2.0));
if (distance > Math.abs(radius - circle.radius) && distance <
Math.abs(radius + circle.radius))
return true;
else
return false;
}
}
 
B

byhesed

What's wrong with contains and overlaps method in Circle2D class?
It returns incorrect answers.

- A method contains(double x, double y) returns true if the specified
point(x,y) is inside this circle.
- A method contains(Circle2D circle) returns true if the specified
circle is inside this circle.
- A method overlaps(Circle2D circle) return true if the specified
circle overlaps with this circle.

I calculate the distance between two circles:
- double distance = Math.sqrt(Math.pow(circle.x - getX(), 2.0) +
Math.pow(circle.y - getY(), 2.0));

It's wired too me because I think it is not wrong.

// TEST CODE
public class Exercise10_11 {
        public static void main(String[] args) {
                Circle2D c1 = new Circle2D(2, 2, 5.5);
                System.out.println("Area is " + c1.getArea());
                System.out.println("Perimeter is " + c1.getPerimeter());
                System.out.println(c1.contains(3, 3));
                System.out.println(c1.contains(new Circle2D(4, 5, 10.5)));
                System.out.println(c1.overlaps(new Circle2D(3, 5, 2.3)));
        }

}

// Circle2D Class
public class Circle2D {
        private double x;
        private double y;
        private double radius;

        public Circle2D() {
                x = 0;
                y = 0;
                radius = 1;
        }

        public Circle2D(double x, double y, double radius) {
                this.x = x;
                this.y = y;
                this.radius = radius;
        }

        public double getX() {
                return x;
        }

        public double getY() {
                return y;
        }

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

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

        public boolean contains(double x, double y) {
                double distance = Math.pow(getX() - x, 2.0) + Math.pow(getY() - y,
2.0);
                if (distance <= radius)
                        return true;
                else
                        return false;
        }

        public boolean contains(Circle2D circle) {
                double distance = Math.sqrt(Math.pow(circle.x - getX(), 2.0) +
Math.pow(circle.y - getY(), 2.0));
                if (distance <= Math.abs(radius - circle.radius))
                        return true;
                else
                        return false;

        }

        public boolean overlaps(Circle2D circle) {
                double distance = Math.sqrt(Math.pow(circle.x - getX(), 2.0) +
Math.pow(circle.y - getY(), 2.0));
                if (distance > Math.abs(radius - circle.radius) && distance <
Math.abs(radius + circle.radius))
                        return true;
                else
                        return false;
        }







}

Sorry, I found answers. Formulas were wrong. :)
 
B

byhesed

Here is the correct answer.


public class Circle2D {
private double x;
private double y;
private double radius;

public Circle2D() {
x = 0;
y = 0;
radius = 1;
}

public Circle2D(double x, double y, double radius) {
this.x = x;
this.y = y;
this.radius = radius;
}

public double getX() {
return x;
}

public double getY() {
return y;
}

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

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

public boolean contains(double x, double y) {
double distance = Math.pow(getX() - x, 2.0) + Math.pow(getY() - y,
2.0);
if (distance <= Math.pow(radius, 2.0))
return true;
else
return false;
}

public boolean contains(Circle2D circle) {
double distance = Math.pow(circle.x - getX(), 2.0) +
Math.pow(circle.y - getY(), 2.0);
if (distance <= (Math.pow(radius, 2.0) - Math.pow(circle.radius,
2.0)))
return true;
else
return false;

}

public boolean overlaps(Circle2D circle) {
double distance = Math.pow(circle.x - getX(), 2.0) +
Math.pow(circle.y - getY(), 2.0);
if (distance < Math.abs(Math.pow(radius, 2.0) -
Math.pow(circle.radius, 2.0)))
return true;

else
return false;
}
}
 
B

byhesed

On 4/30/2011 1:33 AM, byhesed wrote:
...> - double distance = Math.sqrt(Math.pow(circle.x - getX(), 2.0) +

...

I suggest comparing the distance calculation you actually use in the
contains(double x, double y) method to the distance calculation you
described.

If you have a calculation you need to do a lot, why not write and test a
separate method to do it, rather than writing the calculation in-line
repeatedly?

What is the contains(Circle2D circle) method supposed to return if
circle contains this?
Patricia

I know the source code I had posted is silly.
I do not perform any optimization because it is just an example.
It is an exercise from a Java book, Introduction to Java Programming 8/
e.
The reason I don't add a separate method is the author suggests not
adding any other data fields and methods.

Anyway, thank you for your advice.
 
B

byhesed

I know the source code I had posted is silly.
I do not perform any optimization because it is just an example.
It is an exercise from a Java book, Introduction to Java Programming 8/
e.
The reason I don't add a separate method is the author suggests not
adding any other data fields and methods.

Anyway, thank you for your advice.

Sorry, there were errors in my source code in determining the position
of two circles.

public boolean contains(double x, double y) {
double distance = Math.sqrt(Math.pow(getX() - x, 2.0) +
Math.pow(getY() - y, 2.0));
if (distance <= Math.sqrt(radius))
return true;
else
return false;
}

public boolean contains(Circle2D circle) {
double distance = Math.sqrt(Math.pow(getX() - circle.getX(), 2.0) +
Math.pow(getY() - circle.getY(), 2.0));
if (distance <= Math.abs(Math.sqrt(radius) -
Math.sqrt(circle.radius)))
return true;
else
return false;

}

public boolean overlaps(Circle2D circle) {
double distance = Math.sqrt(Math.pow(getX() - circle.getX(), 2.0) +
Math.pow(getY() - circle.getY(), 2.0));
if (Math.abs(Math.sqrt(radius) - Math.sqrt(circle.radius)) <
distance && distance < Math.abs(Math.sqrt(radius) +
Math.sqrt(circle.radius)))
return true;
else
return false;
}
 
G

Gavino

byhesed said:
Here is the correct answer.

public boolean contains(Circle2D circle) {
double distance = Math.pow(circle.x - getX(), 2.0) +
Math.pow(circle.y - getY(), 2.0);
if (distance <= (Math.pow(radius, 2.0) - Math.pow(circle.radius,
2.0)))
return true;
else
return false;

}

public boolean overlaps(Circle2D circle) {
double distance = Math.pow(circle.x - getX(), 2.0) +
Math.pow(circle.y - getY(), 2.0);
if (distance < Math.abs(Math.pow(radius, 2.0) -
Math.pow(circle.radius, 2.0)))
return true;

else
return false;
}

That's still wrong.
'contains' should have
return Math.sqrt(distance) <= radius-circle.radius;
and 'overlaps' should have
return Math.sqrt(distance) <= radius+circle.radius;
as can easily be seen by drawing a simple picture.

Here I have retained your name 'distance' for what is actually the square of
the distance.
 
G

Gavino

Sorry, there were errors in my source code in determining the position
of two circles.
public boolean contains(double x, double y) {
double distance = Math.sqrt(Math.pow(getX() - x, 2.0) +
Math.pow(getY() - y, 2.0));
if (distance <= Math.sqrt(radius))

You're going backwards.
This should be
if (distance <= radius)

The others are still wrong too - see my previous post.
 
B

byhesed

That's still wrong.
'contains' should have
return Math.sqrt(distance) <= radius-circle.radius;
and 'overlaps' should have
return Math.sqrt(distance) <= radius+circle.radius;
as can easily be seen by drawing a simple picture.

Here I have retained your name 'distance' for what is actually the squareof
the distance.

No, it's totally correct.

In the source code, distance means the distance between center of two
circles.
So, distance = Math.sqrt((x0-x1)^2 + (y0-y1)^2)

Here is conditions for determining positions of two circles.

Contains: d <= |r1 - r2|
Overlaps: |r1 - r2| < d < r1 + r2

Remember, circle is shown as x^2 + y^2 = r^2.
 
G

Gavino

No, it's totally correct.
In the source code, distance means the distance between center of two
circles.
So, distance = Math.sqrt((x0-x1)^2 + (y0-y1)^2)

Yes, but in that version of your code you didn't have the sqrt.
Here is conditions for determining positions of two circles.
Contains: d <= |r1 - r2|
Overlaps: |r1 - r2| < d < r1 + r2

So you are defining c1.contains(c2) to include the case where c1 is inside
c2?
That's a strange definition of containment.

Conversely, your definition of 'overlaps' gives false when one circle is
inside the other, which I would expect to count as overlapping.

Still, it's your function and you can define it how you like (but if you are
producing this for someone else, you'd better be sure the definition matches
what is expected).
 
R

Roedy Green

What's wrong with contains and overlaps method in Circle2D class?
It returns incorrect answers.

Usually inside/outside weirdness is caused by winding direction. A
shape defined clockwise is not the same as a shape defined
anti-clockwise.

Whenever you define a shape, you really define two, the obvious one,
and the one containing everything but the obvious one.

It might help to draw some shapes and fill them with colours to make
sure you have them defined properly.
--
Roedy Green Canadian Mind Products
http://mindprod.com
Politicians complain that Kindles and iBooks are killing jobs by
destroying the paper book industry. I see it that they have create a way
to produce books for less than a third the cost without destroying forests
and emitting greenhouse gases in the process. They have created wealth.
They are encouraging literacy and cutting the costs of education.
 
J

John B. Matthews

byhesed said:
[...]

If you have a calculation you need to do a lot, why not write and
test a separate method to do it, rather than writing the
calculation in-line repeatedly?

[...]

I know the source code I had posted is silly.
I do not perform any optimization because it is just an example.

I would argue that the re-factoring suggested by Patricia is an
opportunity to reduce error, both now and in future development or
maintenance. I know it's tempting to dismiss the work as temporary, but
we've all seen a prototype sneak into production.
 
J

John B. Matthews

Patricia Shanahan said:
byhesed said:
[...]

If you have a calculation you need to do a lot, why not write and
test a separate method to do it, rather than writing the
calculation in-line repeatedly?

[...]

I know the source code I had posted is silly.
I do not perform any optimization because it is just an example.

I would argue that the re-factoring suggested by Patricia is an
opportunity to reduce error, both now and in future development or
maintenance. I know it's tempting to dismiss the work as temporary, but
we've all seen a prototype sneak into production.

I certainly proposed it as a means to the achieving correct code.

Not taking the square root, and doing some comparisons between squares
of distances, is a performance optimization that may or may not be
useful, depending on how often the code is run. It is premature
optimization, and a very bad idea, until the code is running correctly.

I see what you mean, now. I had thought some re-factoring would lend
clarity, but I over-estimated the benefit.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top