Rogue: Savage Rats, a retro-themed dungeon crawler
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
rogue-savage-rats/src/mightypork/utils/math/rect/Rect.java

398 lines
5.8 KiB

package mightypork.utils.math.rect;
import mightypork.utils.math.constraints.RectConstraint;
import mightypork.utils.math.constraints.VecConstraint;
import mightypork.utils.math.coord.MutableCoord;
import mightypork.utils.math.coord.SynthCoord2D;
import mightypork.utils.math.coord.Vec;
import mightypork.utils.math.coord.VecMutable;
import mightypork.utils.math.coord.VecView;
public class Rect {
public static final Rect ONE = new Rect(0, 0, 1, 1); // FIXME
private final VecMutable pos = new MutableCoord();
private final VecMutable size = new MutableCoord();
private final VecView center = new SynthCoord2D() {
@Override
public double y()
{
return pos.x() + size.x() / 2;
}
@Override
public double x()
{
return pos.y() + size.y() / 2;
}
};
/**
* Create at 0,0 with zero size
*/
public Rect() {
// keep default zeros
}
/**
* Create at 0,0 with given size
*
* @param width
* @param height
*/
public Rect(double width, double height) {
this.pos.setTo(0, 0);
this.size.setTo(width, height);
norm();
}
/**
* Create at given origin, with given size.
*
* @param origin
* @param width
* @param height
*/
public Rect(Vec origin, double width, double height) {
this.pos.setTo(origin);
this.size.setTo(width, height);
norm();
}
/**
* make sure the rect doesn't have negative size.
*/
private void norm()
{
if (size.x() < 0) {
pos.sub(-size.x(), 0);
size.mul(-1, 1);
}
if (size.y() < 0) {
pos.sub(0, -size.y());
size.mul(1, -1);
}
}
/**
* Create at given origin, with given size.
*
* @param origin
* @param size
*/
public Rect(Vec origin, Vec size) {
this.pos.setTo(origin);
this.size.setTo(size);
norm();
}
/**
* Create at given origin, with given size.
*
* @param x
* @param y
* @param width
* @param height
*/
public Rect(double x, double y, double width, double height) {
pos.setTo(x, y);
size.setTo(width, height);
norm();
}
/**
* Create as copy of another
*
* @param other copied
*/
public Rect(Rect other) {
this(other.pos, other.size);
}
/**
* Set to other rect's coordinates
*
* @param rect other rect
*/
public void setTo(Rect rect)
{
setTo(rect.pos, rect.size);
}
public void setTo(Vec origin, Vec size)
{
this.pos.setTo(origin);
this.size.setTo(size);
norm();
}
public void setOrigin(Vec origin)
{
this.pos.setTo(origin);
norm();
}
public void setSize(Vec size)
{
this.size.setTo(size);
norm();
}
/**
* Add vector to origin
*
* @param move offset vector
* @return result
*/
public Rect move(Vec move)
{
move(move.x(), move.y());
return this;
}
/**
* Add X and Y to origin
*
* @param x x to add
* @param y y to add
* @return result
*/
public Rect move(double x, double y)
{
pos.add(x, y);
return this;
}
/**
* Get a copy
*
* @return copy
*/
public Rect copy()
{
return new Rect(this);
}
/**
* Shrink to sides
*
* @param shrink shrink size (horisontal and vertical)
* @return result
*/
public Rect shrink(Vec shrink)
{
return shrink(shrink.x(), shrink.y());
}
/**
* Shrink to sides at sides
*
* @param x horizontal shrink
* @param y vertical shrink
* @return result
*/
public Rect shrink(double x, double y)
{
return shrink(x, y, x, y);
}
/**
* Shrink the rect
*
* @param left shrink
* @param top shrink
* @param right shrink
* @param bottom shrink
* @return result
*/
public Rect shrink(double left, double top, double right, double bottom)
{
pos.add(left, top);
size.sub(left + right, top + bottom);
norm();
return this;
}
/**
* Grow to sides
*
* @param grow grow size (added to each side)
* @return grown copy
*/
public Rect grow(Vec grow)
{
return grow(grow.x(), grow.y());
}
/**
* Grow to sides
*
* @param x horizontal grow
* @param y vertical grow
* @return result
*/
public Rect grow(double x, double y)
{
return grow(x, y, x, y);
}
/**
* Grow the rect
*
* @param left growth
* @param top growth
* @param right growth
* @param bottom growth
* @return result
*/
public Rect grow(double left, double top, double right, double bottom)
{
pos.sub(left, top);
size.add(left + right, top + bottom);
norm();
return this;
}
/**
* Check if point is inside this rectangle
*
* @param point point to test
* @return is inside
*/
public boolean contains(Vec point)
{
final double x = point.x(), y = point.y();
final double x1 = pos.x(), y1 = pos.y();
final double x2 = x1 + size.x(), y2 = y1 + size.y();
return x >= x1 && y >= y1 && x <= x2 && y <= y2;
}
/**
* Round coords
*
* @return result
*/
public Rect round()
{
pos.round();
size.round();
return this;
}
/**
* Get offset copy (subtract)
*
* @param move offset vector
* @return result
*/
public Rect sub(Vec move)
{
return sub(move.x(), move.y());
}
/**
* Subtract X and Y from all coordinates
*
* @param x x to subtract
* @param y y to subtract
* @return result
*/
Rect sub(double x, double y)
{
pos.sub(x, y);
norm();
return this;
}
public VecView getOrigin()
{
return pos.view();
}
public VecView getSize()
{
return size.view();
}
public VecView getCenter()
{
return center;
}
public double getWidth()
{
return size.x();
}
public double getHeight()
{
return size.y();
}
@Override
public String toString()
{
return String.format("[%s-%s]", pos.toString(), pos.view().add(size).toString());
}
public double xMin()
{
return pos.x();
}
public double xMax()
{
return pos.x() + size.x();
}
public double yMin()
{
return pos.y();
}
public double yMax()
{
return pos.y() + size.y();
}
}