/*
* This file is part of NodeBox.
*
* Copyright (C) 2008 Frederik De Bleser (frederik@pandora.be)
*
* NodeBox 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
* (at your option) any later version.
*
* NodeBox 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 NodeBox. If not, see <http://www.gnu.org/licenses/>.
*/
package nodebox.graphics;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import java.awt.geom.Rectangle2D;
import java.util.Iterator;
public class Rect implements Iterable {
public static Rect centeredRect(double cx, double cy, double width, double height) {
return new Rect(cx - width / 2, cy - height / 2, width, height);
}
public static Rect centeredRect(Rect r) {
return centeredRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
public static Rect corneredRect(double cx, double cy, double width, double height) {
return new Rect(cx + width / 2, cy + height / 2, width, height);
}
public static Rect corneredRect(Rect r) {
return corneredRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
public final double x, y, width, height;
public Rect() {
this(0, 0, 0, 0);
}
public Rect(double x, double y, double width, double height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public Rect(Rect r) {
this(r.x, r.y, r.width, r.height);
}
public Rect(java.awt.geom.Rectangle2D r) {
this(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
public double getHeight() {
return height;
}
public double getWidth() {
return width;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public Point getPosition() {
return new Point(x, y);
}
public Point getCentroid() {
return new Point(x + width / 2, y + height / 2);
}
public boolean isEmpty() {
Rect n = normalized();
return n.width <= 0 || n.height <= 0;
}
public Rect normalized() {
double x = this.x;
double y = this.y;
double width = this.width;
double height = this.height;
if (width < 0) {
x += width;
width = -width;
}
if (height < 0) {
y += height;
height = -height;
}
return new Rect(x, y, width, height);
}
public Rect united(Rect r) {
Rect r1 = normalized();
Rect r2 = r.normalized();
double x, y, width, height;
x = Math.min(r1.x, r2.x);
y = Math.min(r1.y, r2.y);
width = Math.max(r1.x + r1.width, r2.x + r2.width) - x;
height = Math.max(r1.y + r1.height, r2.y + r2.height) - y;
return new Rect(x, y, width, height);
}
public boolean intersects(Rect r) {
Rect r1 = normalized();
Rect r2 = r.normalized();
return Math.max(r1.x, r1.y) < Math.min(r1.x + r1.width, r2.width) &&
Math.max(r1.y, r2.y) < Math.min(r1.y + r1.height, r2.y + r2.height);
}
public boolean contains(Point p) {
Rect r = normalized();
return p.getX() >= r.x && p.getX() <= r.x + r.width &&
p.getY() >= r.y && p.getY() <= r.y + r.height;
}
public boolean contains(Rect r) {
Rect r1 = normalized();
Rect r2 = r.normalized();
return r2.x >= r1.x && r2.x + r2.width <= r1.x + r1.width &&
r2.y >= r1.y && r2.y + r2.height <= r1.y + r1.height;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Rect)) return false;
final Rect other = (Rect) o;
return Objects.equal(x, other.x)
&& Objects.equal(y, other.y)
&& Objects.equal(width, other.width)
&& Objects.equal(height, other.height);
}
@Override
public int hashCode() {
return Objects.hashCode(x, y, width, height);
}
@Override
public String toString() {
return "Rect(" + x + ", " + y + ", " + width + ", " + height + ")";
}
public Rectangle2D getRectangle2D() {
return new Rectangle2D.Double(x, y, width, height);
}
public Iterator<Double> iterator() {
return ImmutableList.<Double>of(x, y, width, height).iterator();
}
}