问题
I'm trying to write a program that decides whether a circle is inside/touching a rectangle. The user puts in the center point for the circle and the radius, and two diagonal points for the rectangle.
I'm not sure how to include all points of the circumference of the circle, to tell that there is at least one point in/touching the rectangle. Anyone sure how to do this?
When I run my current program, I'll purposely enter points of a circle being inside of a rectangle, and should work with the if statements I put, but it prints out the wrong answer.
import java.util.Scanner;
public class lab4 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double cx, cy, x, y, r, p1x, p1y, p2x, p2y, max;//input
String a;
System.out.print("Enter cx: ");
cx = in.nextDouble();
System.out.print("Enter cy: ");
cy = in.nextDouble();
System.out.print("Enter r: ");
r = in.nextDouble();
System.out.println("Enter x value of point 1:");
p1x = in.nextDouble();
System.out.println("Enter y value of point 1:");
p1y = in.nextDouble();
System.out.println("Enter x value of point 2:");
p2x = in.nextDouble();
System.out.println("Enter y value of point 2:");
p2y = in.nextDouble();
max = p2x;
if (p1x > max)
max = p1x;
max = p2y;
if (p1y > max)
max = p1y;
if (cx >= p1x && cx <= p2x)
a = "Circle is inside of Rectangle";
if (cx >= p1x && cx <= p2x)
a = "Circle is inside of Rectangle";
if (cx+r >= p1x && cx+r <= p2x)
a = "Circle is inside of Rectangle";
if (cx-r >= p1x && cx-r <= p2x)
a = "Circle is inside of Rectangle";
if (cy >= p1y && cy <= p2y)
a = "Circle is inside of Rectangle";
if (cy >= p1y && cy <= p2y)
a = "Circle is inside of Rectangle";
if (cy+r >= p1y && cy+r <= p2y)
a = "Circle is inside of Rectangle";
if (cy-r >= p1y && cy-r <= p2y)
a = "Circle is inside of Rectangle";
else
a = "Circle is outside of Rectangle";
System.out.println(a);
回答1:
Your else statement is only conditional on the last if statement. So if the last if statement is false, your else statement gets executed. You probably instead want:
if ...
else if ...
else if ...
else
which executes the else only if all the previous "if" statements are false.
回答2:
Because you didn't use else if
for each of the conditions, the last if
and else
pair of statements will override all of the previous if
s.
if (cx >= p1x && cx <= p2x)
a = "Circle is inside of Rectangle";
if (cx >= p1x && cx <= p2x)
a = "Circle is inside of Rectangle";
if (cx+r >= p1x && cx+r <= p2x)
a = "Circle is inside of Rectangle";
if (cx-r >= p1x && cx-r <= p2x)
a = "Circle is inside of Rectangle";
if (cy >= p1y && cy <= p2y)
a = "Circle is inside of Rectangle";
if (cy >= p1y && cy <= p2y)
a = "Circle is inside of Rectangle";
if (cy+r >= p1y && cy+r <= p2y)
a = "Circle is inside of Rectangle";
if (cy-r >= p1y && cy-r <= p2y)
a = "Circle is inside of Rectangle";
else
a = "Circle is outside of Rectangle";
Make sure to use else if
for each of the alternatives to ensure only one of the blocks gets executed.
if (cx >= p1x && cx <= p2x)
a = "Circle is inside of Rectangle";
else if (cx >= p1x && cx <= p2x)
a = "Circle is inside of Rectangle";
else if (cx+r >= p1x && cx+r <= p2x)
a = "Circle is inside of Rectangle";
else if (cx-r >= p1x && cx-r <= p2x)
a = "Circle is inside of Rectangle";
else if (cy >= p1y && cy <= p2y)
a = "Circle is inside of Rectangle";
else if (cy >= p1y && cy <= p2y)
a = "Circle is inside of Rectangle";
else if (cy+r >= p1y && cy+r <= p2y)
a = "Circle is inside of Rectangle";
else if (cy-r >= p1y && cy-r <= p2y)
a = "Circle is inside of Rectangle";
else
a = "Circle is outside of Rectangle";
(This correction will fix the immediate issue, but the algorithm as a whole is still incorrect.)
回答3:
As others have said, you need a chain of if ... else if ... else if ... else
for your logic to work properly.
However, there's an easier approach. To test whether any part of a circle touches or is inside a rectangle, just expand the rectangle by the circle radius and then test whether the center of the circle is inside or on the expanded rectangle. Since you are using double coordinates, you can use a Rectangle.Double to do all the heavy lifting:
public static void main(String[] args) {
double cx, cy, r, p1x, p1y, p2x, p2y;
// first input cx, cy, r, p1x, p1y, p2x, and p2y
// construct a zero-width/height rectangle at p1
Rectangle2D.Double p1 = new Rectangle2D.Double(p1x, p1y, 0, 0);
// construct another one at p1
Rectangle2D.Double p2 = new Rectangle2D.Double(p2x, p2y, 0, 0);
// construct the union of the two
Rectangle2D.Double rect = p1.createUnion(p2);
// expand the rectangle
rect.setBounds(rect.x - r, rect.y - r, rect.w + 2 * r, rect.h + 2 * r);
// test for containment
if (rect.contains(cx, cy) {
a = "Circle is inside of Rectangle";
} else {
a = "Circle is outside of Rectangle";
}
System.out.println(a);
}
回答4:
Some pseudocode:
Shift the circle to the origin to make things simpler. Shift the rectangle the same amount.
p1x = p1x - cx
p2x = p2x - cx
p1y = p1y - cy
p2y - p2y - cy
x^2 + y^2 = r^2
y = +- sqrt( r^2 - x^2)
For x = -r to r
y = + sqrt( r^2 - x^2 )
if ( Inbounds(x,y) )return true;
y = - sqrt( r^2 - x^2 )
if ( Inbounds(x,y) )return true;
End For
To increase precision you could do something like:
For x = -r to r Step 0.01 (use doubles and increment by 0.01 )
回答5:
because you treat every case separately without else if
,so if condition is you override value of a if the if condition is true ,your else if is related to the last if statement , not for all .
I suggest to concatenate every result to variable a
like this to see which conditions are valid:
if (cx >= p1x && cx <= p2x)
a += "Circle is inside of Rectangle \n";
if (cx >= p1x && cx <= p2x)
a += "Circle is inside of Rectangle\n";
if (cx+r >= p1x && cx+r <= p2x)
a += "Circle is inside of Rectangle\n";
if (cx-r >= p1x && cx-r <= p2x)
a += "Circle is inside of Rectangle\n";
if (cy >= p1y && cy <= p2y)
a += "Circle is inside of Rectangle\n";
if (cy >= p1y && cy <= p2y)
a += "Circle is inside of Rectangle\n";
if (cy+r >= p1y && cy+r <= p2y)
a += "Circle is inside of Rectangle\n";
if (cy-r >= p1y && cy-r <= p2y)
a += "Circle is inside of Rectangle\n";
else
a += "Circle is outside of Rectangle\n";
Or if that's not what you want add else if to all your if statements like this :
if (cx >= p1x && cx <= p2x)
a = "Circle is inside of Rectangle";
else if (cx >= p1x && cx <= p2x)
a = "Circle is inside of Rectangle";
else if (cx+r >= p1x && cx+r <= p2x)
a = "Circle is inside of Rectangle";
else if (cx-r >= p1x && cx-r <= p2x)
a = "Circle is inside of Rectangle";
else if (cy >= p1y && cy <= p2y)
a = "Circle is inside of Rectangle";
else if (cy >= p1y && cy <= p2y)
a = "Circle is inside of Rectangle";
else if (cy+r >= p1y && cy+r <= p2y)
a = "Circle is inside of Rectangle";
else if (cy-r >= p1y && cy-r <= p2y)
a = "Circle is inside of Rectangle";
else
a = "Circle is outside of Rectangle";
来源:https://stackoverflow.com/questions/18794943/if-statement-seems-to-be-skipping-to-else