GRectangle.java
/*
* ..::jDrawingLib::..
*
* Copyright (C) Federico Vera 2012 - 2023 <[email protected]>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or any later
* version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.dkt.graphics.elements;
import com.dkt.graphics.exceptions.InvalidArgumentException;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Area;
/**
*
* @author Federico Vera {@literal<[email protected]>}
*/
public class GRectangle extends GFillableE {
protected int x;
protected int y;
protected int w;
protected int h;
protected int cx;
protected int cy;
/**
* Copy constructor
*
* @param e {@code GRectangle} to copy
* @throws IllegalArgumentException if {@code e} is {@code null}
*/
public GRectangle(GRectangle e) {
super(e);
cx = e.cx;
cy = e.cy;
x = e.x;
y = e.y;
h = e.h;
w = e.w;
}
/**
* Creates a new rectangle (square) on with center in {@code (0, 0)}
*
* @param s side of the square
* @throws InvalidArgumentException if {@code s} is less or equal than 0
*/
public GRectangle(final int s) {
this(0, 0, s);
}
/**
* Creates a new rectangle (square) given the coordinates of the center,
* and the size of it's side
*
* @param x x coordinate of the center of the rectangle
* @param y y coordinate of the center of the rectangle
* @param s side of the square
* @throws InvalidArgumentException if {@code s} is less or equal than 0
*/
public GRectangle(final int x, final int y, final int s) {
this(x, y, s, s);
}
/**
* Creates a new rectangle given the coordinates of the center, it's width
* and height
*
* @param x x coordinate of the center of the rectangle
* @param y y coordinate of the center of the rectangle
* @param w width of the rectangle
* @param h height of the rectangle
* @throws InvalidArgumentException if either {@code w} or {@code h} are
* less or equal than 0
*/
public GRectangle(
final int x,
final int y,
final int w,
final int h)
{
if (w <= 0 || h <= 0){
String msg = "The size must be a non-zero positive integer";
throw new InvalidArgumentException(msg);
}
this.cx = x;
this.cy = y;
this.x = x - w / 2;
this.y = y - h / 2;
this.w = w;
this.h = h;
}
/**
* Tells whether a rectangle is intersecting this rectangle
*
* @param r {@link GRectangle} to check
* @return {@code true} if the rectangles intersect and {@code false}
* otherwise
* @throws IllegalArgumentException if {@code r} is {@code null}
*/
public boolean intersects(final GRectangle r) {
if (r == null){
throw new IllegalArgumentException("The rectangle can't be null");
}
return !((x + w < r.x) | (r.x + r.w < x) |
(y + h < r.y) | (r.y + r.h < y));
}
/**
* Tells whether a rectangle is contained on this rectangle
*
* @param r {@link GRectangle} to check
* @return {@code true} if the rectangle is contained and {@code false}
* otherwise
* @throws IllegalArgumentException if {@code r} is {@code null}
*/
public boolean contains(final GRectangle r) {
if (r == null){
throw new IllegalArgumentException("The rectangle can't be null");
}
return contains( r.x , r.y ) & contains(r.x + r.w, r.y ) &
contains(r.x + r.w, r.y + r.h) & contains( r.x , r.y + r.h);
}
/**
* Tells whether a line is contained on this rectangle
*
* @param l {@link GLine} to check
* @return {@code true} if the line is contained and {@code false} otherwise
* @throws IllegalArgumentException if {@code l} is {@code null}
*/
public boolean contains(final GLine l) {
if (l == null){
throw new IllegalArgumentException("The line can't be null");
}
return contains(l.getStartPoint()) && contains(l.getEndPoint());
}
/**
* Tells whether a point is contained on this rectangle
*
* @param p {@link GPoint} to check
* @return {@code true} if the point is contained and {@code false}
* otherwise
* @throws IllegalArgumentException if {@code p} is {@code null}
*/
public boolean contains(final GPoint p) {
if (p == null){
throw new IllegalArgumentException("The point can't be null");
}
return contains(p.x(), p.y());
}
/**
* Tells whether a point is contained on this rectangle
*
* @param xx x coordinate of the point
* @param yy y coordinate of the point
* @return {@code true} if the point is contained and {@code false}
* otherwise
*/
public boolean contains(final int xx, final int yy) {
return (x <= xx) & (xx <= x + w) & (y <= yy) & (yy <= y + h);
}
/**
* Retrieves the X coordinate of the center of this rectangle
*
* @return x coordinate
*/
public int getCX() {
return cx;
}
/**
* Retrieves the Y coordinate of the center of this rectangle
*
* @return y coordinate
*/
public int getCY() {
return cy;
}
/**
* Retrieves x coordinate of the right limit of this rectangle
*
* @return x coordinate of the right limit
*/
public int getRightL() {
return x + w;
}
/**
* Retrieves x coordinate of the left limit of this rectangle
*
* @return x coordinate of the left limit
*/
public int getLeftL() {
return x;
}
/**
* Retrieves y coordinate of the lower limit of this rectangle
*
* @return y coordinate of the lower limit
*/
public int getLowerL() {
return y;
}
/**
* Retrieves y coordinate of the upper limit of this rectangle
*
* @return y coordinate of the upper limit
*/
public int getUpperL() {
return y + h;
}
/**
* Calculates the area of this rectangle
*
* @return area
*/
public double area() {
return h * w;
}
/**
* Calculated the perimeter of this rectangle
*
* @return perimeter
*/
public double perimeter() {
return h + h + w + w;
}
/**
* Retrieves the height of this rectangle
*
* @return height
*/
public int getHeight() {
return h;
}
/**
* Retrieves the width of this rectangle
*
* @return width
*/
public int getWidth() {
return w;
}
@Override
public void traslate(final int x, final int y) {
this.cx += x;
this.cy += y;
this.x += x;
this.y += y;
}
/**
* Moves the center of this rectangle to the given coordinates
*
* @param x new x coordinate
* @param y new y coordinate
*/
public void move(final int x, final int y) {
this.cx = x;
this.cy = y;
this.x = x - w / 2;
this.y = y - h / 2;
}
@Override
public void draw(final Graphics2D g) {
g.setStroke(getStroke());
if (fill()){
g.setPaint(getFillPaint());
g.fillRect(x, y, w, h);
}
g.setPaint(getPaint());
g.drawRect(x, y, w, h);
}
@Override
public GRectangle clone() {
return new GRectangle(this);
}
@Override
public int hashCode() {
int hash = super.hashCode();
hash = 83 * hash + x;
hash = 83 * hash + y;
hash = 83 * hash + w;
hash = 83 * hash + h;
hash = 83 * hash + cx;
hash = 83 * hash + cy;
return hash;
}
@Override
public boolean equals(Object obj) {
if (!super.equals(obj)) {
return false;
}
final GRectangle other = (GRectangle) obj;
return !(
x != other.x |
y != other.y |
w != other.w |
h != other.h |
cx != other.cx |
cy != other.cy
);
}
@Override
public Area getShape() {
return new Area(new Rectangle(x, y, w, h));
}
}