Turtle programming game that was never finished to a playable state (but had cute graphics and sounds)
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.
tortuga/src/com/porcupine/coord/Rect.java

805 lines
11 KiB

package com.porcupine.coord;
import com.porcupine.math.Calc;
/**
* Rectangle determined by two coordinates - min and max.
*
* @author Ondřej Hruška (MightyPork)
*/
public class Rect {
/** Rect [0, 0, 1, 1] */
public static final Rect ONE = new Rect(0, 0, 1, 1);
/** Rect all zeros */
public static final Rect ZERO = new Rect(0, 0, 0, 0);
/**
* Rectangle from size
*
* @param min min coord
* @param size rect size
* @return the rect
*/
public static Rect fromSize(Coord min, Coord size)
{
return fromSize(min, size.xi(), size.yi());
}
/**
* Make rect from min coord and size
*
* @param min min coord
* @param width size x
* @param height size y
* @return the new rect
*/
public static Rect fromSize(Coord min, int width, int height)
{
return new Rect(min, min.add(width, height));
}
/**
* Rectangle from size
*
* @param i min X
* @param j min Y
* @param size rect size
* @return the rect
*/
public static Rect fromSize(int i, int j, CoordI size)
{
return fromSize(i, j, size.x, size.y);
}
/**
* Make rect from min coord and size
*
* @param x1 min x
* @param y1 min y
* @param width size x
* @param height size y
* @return the new rect
*/
public static Rect fromSize(int x1, int y1, int width, int height)
{
return new Rect(x1, y1, x1 + width, y1 + height);
}
/** Highest coordinates xy */
protected Coord max = new Coord();
/** Lowest coordinates xy */
protected Coord min = new Coord();
/**
* New Rect [0, 0, 0, 0]
*/
public Rect() {
this(0, 0, 0, 0);
}
/**
* Rect [0, 0, size.x, size.y]
*
* @param size size coord
*/
public Rect(Coord size) {
this(0, 0, size.x, size.y);
}
/**
* New rect of two coords
*
* @param c1 coord 1
* @param c2 coord 2
*/
public Rect(Coord c1, Coord c2) {
this(c1.x, c1.y, c2.x, c2.y);
}
/**
* New Rect
*
* @param x1 lower x
* @param y1 lower y
* @param x2 upper x
* @param y2 upper y
*/
public Rect(double x1, double y1, double x2, double y2) {
setTo(x1, y1, x2, y2);
}
/**
* Rect [0, 0, x, y]
*
* @param x width
* @param y height
*/
public Rect(int x, int y) {
this(0, 0, x, y);
}
/**
* New rect as a copy of other rect
*
* @param r other rect
*/
public Rect(Rect r) {
this(r.min.x, r.min.y, r.max.x, r.max.y);
}
/**
* Get offset copy (add)
*
* @param move offset vector
* @return offset copy
*/
public Rect add(Coord move)
{
return copy().add_ip(move);
}
/**
* Add X and Y to all coordinates in a copy
*
* @param x x to add
* @param y y to add
* @return copy changed
*/
public Rect add(double x, double y)
{
return add(new Vec(x, y));
}
/**
* Offset in place (add)
*
* @param move offset vector
* @return this
*/
public Rect add_ip(Coord move)
{
min.add_ip(move);
max.add_ip(move);
return this;
}
/**
* Add X and Y to all coordinates in place
*
* @param x x to add
* @param y y to add
* @return this
*/
public Rect add_ip(double x, double y)
{
return add_ip(new Vec(x, y));
}
/**
* Get a copy
*
* @return copy
*/
public Rect copy()
{
return new Rect(this);
}
/**
* Divide in copy
*
* @param factor divisor
* @return offset copy
*/
public Rect div(double factor)
{
return copy().div_ip(factor);
}
/**
* Divide coord in place
*
* @param factor divisor
* @return this
*/
public Rect div_ip(double factor)
{
min.div_ip(factor);
max.div_ip(factor);
return this;
}
/**
* Get copy with the same center and height=0
*
* @return line
*/
public Rect getAxisH()
{
return new Rect(getCenterLeft(), getCenterRight());
}
/**
* Get copy with the same center and width=0
*
* @return line
*/
public Rect getAxisV()
{
return new Rect(getCenterDown(), getCenterTop());
}
/**
* Get rect center
*
* @return center
*/
public Coord getCenter()
{
return min.midTo(max);
}
/**
* Get center of the lower edge.
*
* @return center
*/
public Coord getCenterDown()
{
return new Coord((max.x + min.x) / 2, min.y);
}
/**
* Get center of the left edge.
*
* @return center
*/
public Coord getCenterLeft()
{
return new Coord(min.x, (max.y + min.y) / 2);
}
/**
* Get center of the right edge.
*
* @return center
*/
public Coord getCenterRight()
{
return new Coord(max.x, (max.y + min.y) / 2);
}
/**
* Get center of the top edge.
*
* @return center
*/
public Coord getCenterTop()
{
return new Coord((max.x + min.x) / 2, max.y);
}
/**
* Get bottom edge rect
*
* @return line
*/
public Rect getEdgeBottom()
{
return new Rect(getLeftBottom(), getRightBottom());
}
/**
* Get left edge rect
*
* @return line
*/
public Rect getEdgeLeft()
{
return new Rect(getLeftBottom(), getLeftTop());
}
/**
* Get right edge rect
*
* @return line
*/
public Rect getEdgeRight()
{
return new Rect(getRightBottom(), getRightTop());
}
/**
* Get top edge rect
*
* @return line
*/
public Rect getEdgeTop()
{
return new Rect(getLeftTop(), getRightTop());
}
/**
* Get left bottom
*
* @return center
*/
public Coord getLeftBottom()
{
return new Coord(min.x, min.y);
}
/**
* Get left top
*
* @return center
*/
public Coord getLeftTop()
{
return new Coord(min.x, max.y);
}
/**
* @return highjest coordinates xy
*/
public Coord getMax()
{
return max;
}
/**
* @return lowest coordinates xy
*/
public Coord getMin()
{
return min;
}
/**
* Get right bottom
*
* @return center
*/
public Coord getRightBottom()
{
return new Coord(max.x, min.y);
}
/**
* Get right top
*
* @return center
*/
public Coord getRightTop()
{
return new Coord(max.x, max.y);
}
/**
* Get size (width, height) as (x,y)
*
* @return coord of width,height
*/
public Coord getSize()
{
return new Coord(Math.abs(min.x - max.x), Math.abs(min.y - max.y));
}
/**
* Grow to sides in copy
*
* @param grow grow size (added to each side)
* @return grown copy
*/
public Rect grow(Coord grow)
{
return copy().grow_ip(grow);
}
/**
* Grow to sides in copy
*
* @param x x to add
* @param y y to add
* @return grown copy
*/
public Rect grow(double x, double y)
{
return copy().grow_ip(x, y);
}
/**
* Grow to sides in place
*
* @param grow grow size (added to each side)
* @return this
*/
public Rect grow_ip(Coord grow)
{
min.sub_ip(grow);
max.add_ip(grow);
return this;
}
/**
* Grow to sides in place
*
* @param x x to add
* @param y y to add
* @return this
*/
public Rect grow_ip(double x, double y)
{
min.sub_ip(x, y);
max.add_ip(x, y);
return this;
}
/**
* Grow down in copy
*
* @param down added pixels
* @return grown copy
*/
public Rect growDown(double down)
{
return copy().growDown_ip(down);
}
/**
* Grow down in place
*
* @param down added pixels
* @return this
*/
public Rect growDown_ip(double down)
{
min.sub_ip(0, down);
return this;
}
/**
* Grow to left in copy
*
* @param left added pixels
* @return grown copy
*/
public Rect growLeft(double left)
{
return copy().growLeft_ip(left);
}
/**
* Grow to left in place
*
* @param left added pixels
* @return this
*/
public Rect growLeft_ip(double left)
{
min.sub_ip(left, 0);
return this;
}
/**
* Grow to right in copy
*
* @param right added pixels
* @return grown copy
*/
public Rect growRight(double right)
{
return copy().growRight_ip(right);
}
/**
* Grow to right in place
*
* @param right added pixels
* @return this
*/
public Rect growRight_ip(double right)
{
max.add_ip(right, 0);
return this;
}
/**
* Grow up in copy
*
* @param add added pixels
* @return grown copy
*/
public Rect growUp(double add)
{
return copy().growUp_ip(add);
}
/**
* Grow up in place
*
* @param add added pixels
* @return this
*/
public Rect growUp_ip(double add)
{
max.add_ip(0, add);
return this;
}
/**
* Check if point is inside this rectangle
*
* @param point point to test
* @return is inside
*/
public boolean isInside(Coord point)
{
return Calc.inRange(point.x, min.x, max.x) && Calc.inRange(point.y, min.y, max.y);
}
/**
* Multiply in copy
*
* @param factor multiplier
* @return offset copy
*/
public Rect mul(double factor)
{
return copy().mul_ip(factor);
}
/**
* Multiply by number (useful for centered rects)
*
* @param x x multiplier
* @param y y multiplier
* @return copy multiplied
*/
public Rect mul(double x, double y)
{
return copy().mul_ip(x, y);
}
/**
* Multiply coord in place
*
* @param factor multiplier
* @return this
*/
public Rect mul_ip(double factor)
{
min.mul_ip(factor);
max.mul_ip(factor);
return this;
}
/**
* Multiply coord in place
*
* @param x multiplier x
* @param y multiplier y
* @return this
*/
public Rect mul_ip(double x, double y)
{
min.mul_ip(x, y, 1);
max.mul_ip(x, y, 1);
return this;
}
/**
* Round coords in copy
*
* @return copy, rounded
*/
public Rect round()
{
return new Rect(min.round(), max.round());
}
/**
* Round this in place
*
* @return this
*/
public Rect round_ip()
{
min.round_ip();
max.round_ip();
return this;
}
/**
* Set to [0,0,coord.x,coord.y]
*
* @param coord size coord
*/
public void setTo(Coord coord)
{
setTo(0, 0, coord.x, coord.y);
}
/**
* Set to coordinates
*
* @param x1 lower x
* @param y1 lower y
* @param x2 upper x
* @param y2 upper y
*/
public void setTo(double x1, double y1, double x2, double y2)
{
min.x = Calc.min(x1, x2);
min.y = Calc.min(y1, y2);
max.x = Calc.max(x1, x2);
max.y = Calc.max(y1, y2);
}
/**
* Set to other rect's coordinates
*
* @param r other rect
*/
public void setTo(Rect r)
{
min.setTo(r.min);
max.setTo(r.max);
}
/**
* Subtract X and Y from all coordinates in a copy
*
* @param x x to subtract
* @param y y to subtract
* @return copy changed
*/
public Rect sub(double x, double y)
{
return sub(new Vec(x, y));
}
/**
* Get offset copy (subtract)
*
* @param move offset vector
* @return offset copy
*/
public Rect sub(Vec move)
{
return copy().sub_ip(move);
}
/**
* Subtract X and Y from all coordinates in place
*
* @param x x to subtract
* @param y y to subtract
* @return this
*/
public Rect sub_ip(double x, double y)
{
return sub_ip(new Vec(x, y));
}
/**
* Offset in place (subtract)
*
* @param move offset vector
* @return this
*/
public Rect sub_ip(Vec move)
{
min.sub_ip(move);
max.sub_ip(move);
return this;
}
@Override
public String toString()
{
return "rect{ " + min + " - " + max + " }";
}
/**
* @return lower x
*/
public double x1()
{
return min.x;
}
/**
* @return upper x
*/
public double x2()
{
return max.x;
}
/**
* @return lower y
*/
public double y1()
{
return min.y;
}
/**
* @return upper y
*/
public double y2()
{
return max.y;
}
}