This question already has answers here:
Java check if two rectangles overlap at any point
(9 answers)
Closed 7 years ago.
My assignment is to check if two points are inside a rectangle, check if a rectangle is inside another rectangle, and also check if a rectangle overlaps another rectangle
I completed the first two steps but I can't solve the overlapping method.
This what I've done.
public class MyRectangle2D {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
MyRectangle2D rect = new MyRectangle2D();
//returns area of default rectangle
System.out.println(rect.getArea());
//returns perimeter of default rectangle
System.out.println(rect.getPerimeter());
//returns true if default (0,0) is inside rectangle
System.out.println(rect.contains(0,0));
//returns false if point is not in triangle
System.out.println(rect.contains(10,10));
MyRectangle2D r1 = new MyRectangle2D(10,2,6,4);
System.out.println("The area of your rectangle is " + r1.getArea() +
" \nthe perimeter of your rectangle is " + r1.getPerimeter());
System.out.println("Testing Rectangle 2 with points (1,8)...");
//following lines test the contain(x,y) method
System.out.println(r1.contains(1,8) ? "Point (1,8) is on Rectangle" : "Point(1,8) is not on Rectangle");
System.out.println("Testing Rectangle 2 with points (10,1)...");
System.out.println(r1.contains(10,1) ? "Point (10,1) is on Rectangle" : "Point(10,1) is not on Rectangle");
//following lines test contains(rect) method
System.out.println(r1.contains(new MyRectangle2D(9,1,1,1)) ? "Rectangle is inside" : "Not inside");
System.out.println(r1.contains(new MyRectangle2D(9,1,10,2)) ? "Rectangle is inside" : "Rectangle is not inside");
//following lines test if rectangles overlap
System.out.println(r1.overlaps(new MyRectangle2D(4,2,8,4)));
}
double x;
double y;
double width;
double height;
private MyRectangle2D(){
x = 0;
y = 0;
width = 1;
height = 1;
}
private MyRectangle2D(double newX, double newY,
double newWidth, double newHeight){
setX(newX);
setY(newY);
setHeight(newHeight);
setWidth(newWidth);
}
double getX(){
return x;
}
double getY(){
return y;
}
void setX(double newA){
x = newA;
}
void setY(double newA){
y = newA;
}
double getWidth(){
return width;
}
double getHeight(){
return height;
}
void setWidth(double newA){
width = newA;
}
void setHeight(double newA){
height = newA;
}
double getArea(){
double area = width * height;
return area;
}
double getPerimeter(){
double perimeter = (2 * width) + (2 * height);
return perimeter;
}
boolean contains(double x, double y){
boolean inside = false;
if(x<(getWidth()/2 + getX()) && x>getX()-(getWidth()/2)){
if(y<(getY() + getHeight()/2) && y>getY()-(getHeight()/2))
inside = true;
}
return inside;
}
boolean contains(MyRectangle2D r){
boolean inside = false;
if(r.getX()<(getWidth()/2 + getX()) && r.getX()>getX()-(getWidth()/2)){
if(r.getY()<(getY() + getHeight()/2) && r.getY()>getY()-(getHeight()/2)){
if(r.getWidth()<=getWidth() && r.getHeight()<=getHeight())
inside = true;
}
}
return inside;
}
boolean overlaps(MyRectangle2D r){
boolean inside = false;
if(contains(r.getX()+r.getWidth(),r.getY()+r.getHeight()))
inside = true;
if(contains(r.getX()-r.getWidth(),r.getY()-r.getHeight()))
inside = true;
return inside;
}
}
This will find if the rectangle is overlapping another rectangle, don't forget to mark this as the answer and vote up when you can.
public boolean overlaps (MyRectangle2D r) {
return x < r.x + r.width && x + width > r.x && y < r.y + r.height && y + height > r.y;
}
Related
I'm trying to write a program that checks if a circle contains another circle, if a certain point is inside a circle, or the one I'm having trouble with, if a circle overlaps with another circle.
import javafx.scene.shape.Circle;
public class Problem10_11 {
public static void main(String[] args) {
//Create circle with certain parameters.
Circle2D c1 = new Circle2D(2, 2, 5.5);
//Create output which will be tested by all our methods.
System.out.println("The area for circle 1 is " +c1.getArea()+
" and its perimeter is " + c1.getPerimeter());
System.out.println("Is (3,3) contained within circle 1? "
+ c1.contains(3, 3));
System.out.println("Does circle 1 contain circle 2? "
+ c1.contains(new Circle2D(4,5,10.5)));
System.out.println("Does circle 1 overlap with circle 3? "
+ c1.overlaps(new Circle2D(3, 5, 2.3)));
}
}
class Circle2D {
double x; //first parameter
double y; //second parameter
double radius; //third parameter
Circle2D() {
}
public Circle2D(double x, double y, double radius) {
this.x = x;
this.y = y;
this.radius = radius;
}
public void setX(double x) {
this.x = x; //set x
}
public double getX() {
return x; //grab x
}
public void setY(double y) {
this.y = y; //set y
}
public double getY() {
return y; //grab y
}
public void setRadius(double radius) {
this.radius = radius; //set radius
}
public double getRadius() {
return radius; //grab radius
}
public double getArea() {
double area = Math.PI*radius*radius; //formula for area
return area;
}
public double getPerimeter() {
double perimeter = 2*Math.PI*radius; //formula for perimeter
return perimeter;
}
public boolean contains(double x, double y) {
//Use distance formula to check if a specific point is within our circle.
double distance = Math.sqrt(Math.pow(this.x - x, 2) + (Math.pow(this.y - y, 2)));
if (distance <= radius * 2)
return true;
else {
return false;
}
}
public boolean contains(Circle2D circle) {
//Use distance formula to check if a circle is contained within another circle.
double distance = Math.sqrt(Math.pow(circle.getX() - x, 2) + (Math.pow(circle.getY() - y, 2)));
if (distance <= (this.radius - circle.radius)) {
return true;
} else {
return false;
}
}
public boolean overlaps(Circle2D circle) {
//Use distance formula to check if a circle overlaps with another circle.
double distance = Math.sqrt(Math.pow(circle.getX() - x, 2) + (Math.pow(circle.getY() - y, 2)));
}
}
So my overlap method is all the way at the bottom but I don't really have anything inside because I'm not sure exactly what to do. I tried this :
if (distance <= radius) return true;
else return false;
but that didnt work. So I'm not sure what else to try. FYI, I'm trying to check if c1 overlaps with a circle with parameters (3, 5, 2.3). I appreciate any suggestions/advice.
You can refer to Relative position of two circles.
public boolean overlaps(Circle2D circle) {
//Use distance formula to check if a circle overlaps with another circle.
double distance = Math.sqrt(Math.pow(circle.getX() - x, 2) + (Math.pow(circle.getY() - y, 2)));
return distance <= (this.radius + circle.radius) and distance >= Math.abs(this.radius - circle.radius)
}
if the distance between the centres of the circles is less than the sum of the radius of the two circles then they are overlapping.
double minDistance = Math.max(circle.getRadius(),this.radius) - Math.min(circle.getRadius(),this.radius);
if (distance <= (this.radius + circle.getRadius()) && distance>= minDistance) return true;
else return false;
1.- you have to to place both circles in space, give them some cordinates
2.- you have to get the vectors from 2 circles.
3.- you have to normailze those vectors and get the correct distance in units,
im gonna use pixels.
4.- finally you have to check if the distance between those 2 vectors are less that the radious of both circles, if so, then they are overlaped.
here you have a link that is better explained:
https://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769, actually this is something very common we use in game development when we want to check circle collisions ( for 2D games )
Most answers here are wrong.
There are three cases to consider:
Circles overlap and the center of the smaller circle is inside the bigger circle
Circles overlap and the center of the smaller circle is outside the bigger circle
3.
The two circles touch at their borders
The algorithm is this (in Java):
Calculate the distance between centers:
double centersDistance = Math.sqrt((x2 - x1)^2 + (y2 - y1)^2)
Check if one circle contains another:
boolean blueContainsRed = blue.radius > centersDistance + red.radius;
boolean redContainsBlue = red.radius > centersDistance + blue.radius;
Check if they overlap:
boolean circlesOverlap = centersDistance <= blue.radius + red.radius;
the <= would make sure that true is returned for case 3 (when borders only touch). If you don't want that, use < .
So the final formula would be:
return !blueContainsRed && !redContainsBlue && circlesOverlap;
This table might also prove useful (from https://planetcalc.com/8098/):
I have the getters and setters, default and overloaded constructors, toString and my area method on my Rectangle class. My RectangleTest is just my values and output statements. I have been trying to get my area method working but there is no calling of my height and width, no matter what I try.
public class Rectangle {
public double width ;
private double height;
private String color ;
private double area;
public double getWidth ( ) { return width; }
public void setWidth ( double w ) {
this.width = w; }
public double getHeight ( ) {return height; }
public void setHeight ( double h ) {
this.height = h; }
public String getColor ( ) {return color; }
public void setColor ( String co ) {
this.color = (co); }
public Rectangle ( ) {
height = 0;
width = 0;
color = (" ");
System.out.println("Default constructor");
//default constructor
}
public Rectangle ( double w, double h, String co) {
width = w;
height = h;
color = (co);
System.out.println("Overloaded constructor" );
//overloaded constructor
}
public double findArea (){
return area;
}
public void setArea (double width, double height){
area = width * height;
}
public String toString ( ) {
String x = "Rectangle width is " + width + ", height is " + height +
", color is " + color + " and the area is " + area;
return x;
}
}
public class RectangleTest {
public static void main(String[] args) {
Rectangle shape = new Rectangle(2.0, 4.0, "red");
Rectangle r2 = new Rectangle(2.0, 3.0, "Yellow");
Rectangle r3 = new Rectangle(2.0, 3.0, "Yellow");
do { r2.width++ ;
} while (r2.width == (r3.width));
if (r2.equals (r3))
System.out.println("r2 still equals r3" );
else
System.out.println("r2 is now a square");
System.out.println("First rectangle is " + shape );
System.out.println("Second rectangle is " + r2 );
if (r2.equals (r3))
System.out.println("\nShape 2 equals shape 3");
else
System.out.println("\nShape 2 and 3 are not equal");
//System.exit(0);
}
}
findArea is a calculable result, this means that it's result is based on the result of calculating other values. Based on your code example, the only place area is calculated is when setArea is called, but setArea is never called.
A better solution would be to have findArea perform the calculation itself
public double findArea (){
return width * height;
}
This has the benefit of not having you to remember to call the setArea method whenever the width or height changes
Your Rectangles are not fully constructed, because the method setArea(double width, double height) is never called, leaving the area of all objects with the default value of 0.0..... you should call the method it in the constructor.
public Rectangle ( double w, double h, String co) {
width = w;
height = h;
color = (co);
System.out.println("Overloaded constructor" );
//overloaded constructor
setArea (width, height); ///here!
}
Note:
area can be calculated immediately with w and h, which are class members, no need to define a method
setArea (width, height);
using parameters that are in the same class, setArea() will be enough
The method to calculate the area setArea is never invoked. With the way you're code is going, you can put it in toString
public String toString ( ) {
setArea(width, height);
String x = "Rectangle width is " + width + ", height is " + height +
", color is " + color + " and the area is " + area;
return x;
}
But your code is not the standard way of how it should be done.
I created a simple Application which is meant to display, in 2D, dots which are hypothetically on a 3D plane (these points are of type Vector, written below). The class uses the XYZ Coordinates of the Camera and the XYZ Coordinates of the Vector, and uses that information to quickly translate the Vector XYZ Coordinates into XY Coordinates.
The only class needed in this question is the Vector class given below. All other classes used are omitted because they essentially fire mouse movements and redraw the frame.
--My concern is that, as the camera moves, the Vector points jump around as if the formula that I'm using is totally unreliable. Are these formulas (found under Perspective Projection) completely incorrect? The use of those formulas can be found within my set2D method. Am I doing something completely wrong, skipping steps, or perhaps have I translated the formula into code incorrectly?
Thanks!
import java.awt.Color;
import java.awt.Graphics;
public class Vector
{
private int cX, cY, cZ; //Camera Coordinates
private int aX, aY, aZ; //Object Coordinates
private double bX, bY; //3D to 2D Plane Coordinates
public Vector(int aX, int aY, int aZ, int cX, int cY, int cZ)
{
this.aX = aX;
this.aY = aY;
this.aZ = aZ;
this.cX = cX;
this.cY = cY;
this.cY = cZ;
set2D();
}
//SETS
public void setCameraX(int cX)
{
this.cX = cX;
set2D();
}
public void setCameraY(int cY)
{
this.cY = cY;
set2D();
}
public void setCameraZ(int cZ)
{
this.cZ = cZ;
set2D();
}
public void setCameraXYZ(int cX, int cY, int cZ)
{
setCameraX(cX);
setCameraY(cY);
setCameraZ(cZ);
}
public void setObjX(int x)
{
this.aX = x;
}
public void setObjY(int y)
{
this.aY = y;
}
public void setObjZ(int z)
{
this.aZ = z;
}
public void setObjXYZ(int x, int y, int z)
{
this.aX = x;
this.aY = y;
this.aZ = z;
}
public void set2D()
{
//---
//the viewer's position relative to the display surface which goes through point C representing the camera.
double eX = aX - cX;
double eY = aY - cY;
double eZ = aZ - cZ;
//----
double cosX = Math.cos(eX);
double cosY = Math.cos(eY);
double cosZ = Math.cos(eZ);
double sinX = Math.sin(eX);
double sinY = Math.sin(eY);
double sinZ = Math.sin(eZ);
//---
//The position of point A with respect to a coordinate system defined by the camera, with origin in C and rotated by Theta with respect to the initial coordinate system.
double dX = ((cosY*sinZ*eY) + (cosY*cosZ*eX)) - (sinY * eZ);
double dY = ((sinX*cosY*eZ) + (sinX*sinY*sinZ*eY) + (sinX*sinY*cosZ*eX)) + ((cosX*cosZ*eY) - (cosX*sinZ*eX));
double dZ = ((cosX*cosY*eZ) + (cosX*sinY*sinZ*eY) + (cosX*sinY*cosZ*eX)) - ((-sinX*cosZ*eY) - (-sinX*sinZ*eX));
//---
//---
//The 2D projection coordinates of the 3D object
bX = (int)(((eZ / dZ) * dX) - eX);
bY = (int)(((eZ / dZ) * dY) - eY);
//---
System.out.println(bX + " " + bY);
}
//GETS
public int getCameraX()
{
return cX;
}
public int getCameraY()
{
return cY;
}
public int getCameraZ()
{
return cZ;
}
public int getObjX()
{
return aX;
}
public int getObjY()
{
return aY;
}
public int getObjZ()
{
return aY;
}
public int get2DX()
{
return (int)bX;
}
public int get2DY()
{
return (int)bY;
}
//DRAW
public void draw(Graphics g)
{
g.setColor(Color.red);
g.fillOval((int)bX, (int)bY, 3, 3);
}
//TO STRING
public String toString()
{
return (aX + " " + aY + " " + aZ);
}
}
The following line of your code does not match with the formula you are using:
double dZ = ((cosX*cosY*eZ) + (cosX*sinY*sinZ*eY) + (cosX*sinY*cosZ*eX)) - ((-sinX*cosZ*eY) - (-sinX*sinZ*eX));
Notice the part - ((-sinX*cosZ*eY) - (-sinX*sinZ*eX))
This should be - ((sinX*cosZ*eY) - (sinX*sinZ*eX))
Since if you take sinX and multiply it, the -ve sign stays outside. If however you multiple -sinX then the sign outside the brackets should become +ve.
I have a program to draw 20 circles w/ random rad x and y. After, I need to test which circles are overlapping and if they are, set them cyan, if not set them black. heres what I have so far, the problem, is it always sets it to cyan overlapping or not.
public class AppletP5 extends JApplet{
MyCircle[] circle = new MyCircle[20];
public AppletP5(){
for(int i = 0; i<20; i++){
int x0= (int) (Math.random()*500);
int y0= (int) (Math.random()*500);
int rad0= (int) (30 + Math.random()*70);
circle[i] = new MyCircle(x0,y0,rad0);
}
}
public void paint(Graphics g){
for(int i = 0; i<20; i++){
if(circle[i].isOverlapping(circle) == true){
g.setColor(Color.CYAN);
g.drawOval(circle[i].x,circle[i].y,circle[i].rad*2,circle[i].rad*2);
} else if(circle[i].isOverlapping(circle) == false){
g.setColor(Color.BLACK);
g.drawOval(circle[i].x,circle[i].y,circle[i].rad*2,circle[i].rad*2);
}
}
}
}
public class MyCircle {
protected int x, y, rad;
public MyCircle(int x, int y, int rad){
this.x = x;
this.y = y;
this.rad = rad;
}
public boolean isOverlapping(MyCircle[] circles){
for(MyCircle c : circles){
if(Math.pow(c.rad - rad , 2) >= Math.sqrt(Math.pow(x - c.x, 2) + Math.pow(y - c.y , 2))){
return true;
}
}
return false;
}
}
You need to exclude the current Circle from the comparison, since a circle trivially overlaps itself.
You could go with an easy check as long as you just have one instance of each Circle:
for (MyCirlce c : circles) {
if (c != this && ...)
In addition you are checking if the difference of radii between two circles squared by two is greater than the distance of the two centres? Shouldn't you check for the sum of the radii, eg:
r1 + r2 <= distance(c1, c2)
isOverLapping is incorrect implemented.
Two circles intersect, if the distance between their centers is smaller than the sum of their radii. So:
int radSum = c.rad + rad;
int radDif = c.rad - rad;
int distX = c.x - x + radDif;
int distY = c.y - y + radDif;
if(radSum * radSum < distX * distX + distY * distY)
return true;
Apart from that you'll have to ensure you don't compare a circle with itself. And finally: Math.pow is rather costly, so replace it with the simpler version, if you only want the square of a number.
here is my code:
public class Rectangles
{
private final double x;
private final double y;
private final double width;
private final double height;
public Rectangles(double x0, double y0, double w, double h)
{
x = x0;
y = y0;
width = w;
height = h;
}
public double area()
{
return width * height;
}
public double perimeter()
{
return 2*width + 2*height;
}
public boolean intersects(Rectangles b)
{
boolean leftof = ((b.x + b.width)<(x-width));
boolean rightof = ((b.x-b.width)>(x+width));
boolean above = ((b.y-b.height)>(y+height));
boolean below = ((b.y+b.height)<(y-height));
if (leftof==false && rightof==false && above==false && below==false)
return false;
else return true;
}
public void show()
{
StdDraw.setYscale((0),(y+height));
StdDraw.setXscale((0), (x+width));
StdDraw.setPenColor();
StdDraw.rectangle(x,y,.5*width,.5*height);
}
public static void main(String[] args)
{
Rectangles a = new Rectangles(Double.parseDouble(args[0]),
Double.parseDouble(args[1]),
Double.parseDouble(args[2]),
Double.parseDouble(args[3]));
Rectangles b = new Rectangles(0,0,1,1);
System.out.println(a.area());
System.out.println(a.perimeter());
System.out.println(a.intersects(b));
a.show();
b.show();
}
}
I am new to this. This is from a lab assignment based on creating data types. Everything is going well except that System.out.println(a.intersects(b)) is returning true for rectangles that definitely should not intersect. Worse still, the drawing created by show() is showing that they intersect when they definitely should not. For example, (and tell me if I'm completely wrong) %java Rectangles 5 5 3 6 should definitely not return true, right? because a rectangle centered at 5,5 whose width is three would definitely not intersect with a rectangle centered at 0,0 whose width is one.
help is appreciated. I would post a pic of the image displayed, but it says I have to have more reputation to post images. oh well. It was intersecting rectangles.
based on some comments, I edited my code and it now looks like this:
public class Rectangles
{
private final double x;
private final double y;
private final double width;
private final double height;
public Rectangles(double x0, double y0, double w, double h)
{
x = x0;
y = y0;
width = w;
height = h;
}
public double area()
{
return width * height;
}
public double perimeter()
{
return 2*width + 2*height;
}
public boolean intersects(Rectangles b)
{
boolean intersects = ((b.width / 2) + (width / 2) < Math.abs(b.x - x) &&
(b.height / 2) + (height / 2) < Math.abs(b.y - y));
if (intersects==false)
return false;
else return true;
}
public void show()
{
StdDraw.setYscale((0),(y+height));
StdDraw.setXscale((0), (x+width));
StdDraw.setPenColor();
StdDraw.rectangle(x,y,.5*width,.5*height);
}
public static void main(String[] args)
{
Rectangles a = new Rectangles(Double.parseDouble(args[0]),
Double.parseDouble(args[1]),
Double.parseDouble(args[2]),
Double.parseDouble(args[3]));
Rectangles b = new Rectangles(1.0,1.0,1.0,1.0);
System.out.println(a.area());
System.out.println(a.perimeter());
System.out.println(b.intersects(a));
a.show();
b.show();
}
}
I am still getting funky answers for intersects, and for some reason my drawings always have intersecting rectangles. I don't know what I'm doing wrong. After changing code I tried %java Rectangles 5 5 3 6 and it said they intersect and also drew an image of intersecting rectangles. What is going on?
I fixed it.
public class Rectangles
{
private final double x;
private final double y;
private final double width;
private final double height;
public Rectangles(double x0, double y0, double w, double h)
{
x = x0;
y = y0;
width = w;
height = h;
}
public double area()
{
return width * height;
}
public double perimeter()
{
return 2*width + 2*height;
}
public boolean intersects(Rectangles b)
{
boolean leftof = ((b.x + (0.5*b.width))<(x-(0.5*width)));
boolean rightof = ((b.x-(0.5*b.width))>(x+(0.5*width)));
boolean above = ((b.y-(0.5*b.height))>(y+(0.5*height)));
boolean below = ((b.y+(0.5*b.height))<(y-(0.5*height)));
if (leftof==true || rightof==true || above==true || below==true)
return false;
else return true;
}
public void show()
{
double j = Math.max((x+(0.5*height)), (y+(0.5*height)));
StdDraw.setYscale((0),j+1);
StdDraw.setXscale((0),j+1);
StdDraw.setPenColor();
StdDraw.rectangle(x,y,.5*width,.5*height);
}
public static void main(String[] args)
{
Rectangles a = new Rectangles(Double.parseDouble(args[0]),
Double.parseDouble(args[1]),
Double.parseDouble(args[2]),
Double.parseDouble(args[3]));
Rectangles b = new Rectangles(2,2,2,2);
System.out.println(a.area());
System.out.println(a.perimeter());
System.out.println(a.intersects(b));
a.show();
}
}
There is an error in formula for intersection, try this one
((x < b.x && (x + width) > b.x) || (x > b.x && x < (b.x + b.width))) &&
((y < b.y && (y + height) > b.y) || (y > b.y && y < (b.y + b.height)))
If we think geometrically,
(b.width / 2) + (width / 2) < abs(b.x - x) &&
(b.height / 2) + (height / 2) < abs(b.y - y)
should be enough and easier to understand.