/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy 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.
*
* Icy 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 Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.type.rectangle;
import icy.type.dimension.Dimension5D;
import icy.type.point.Point5D;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
/**
* Rectangle5D class.<br>
* Incomplete implementation (work in progress...)
*
* @author Stephane
*/
public abstract class Rectangle5D implements Cloneable
{
/**
* Intersects the pair of specified source <code>Rectangle5D</code> objects and puts the result
* into the specified destination <code>Rectangle5D</code> object. One of the source rectangles
* can also be the destination to avoid creating a third Rectangle5D object, but in this case
* the original points of this source rectangle will be overwritten by this method.
*
* @param src1
* the first of a pair of <code>Rectangle5D</code> objects to be intersected with each
* other
* @param src2
* the second of a pair of <code>Rectangle5D</code> objects to be intersected with each
* other
* @param dest
* the <code>Rectangle5D</code> that holds the
* results of the intersection of <code>src1</code> and <code>src2</code>.<br>
* If set to <code>null</code> then a new Rectangle5D is created.
* @return resulting <code>Rectangle5D</code> from the intersect process.
*/
public static Rectangle5D intersect(Rectangle5D src1, Rectangle5D src2, Rectangle5D dest)
{
final Rectangle5D result;
if (dest == null)
result = new Rectangle5D.Double();
else
result = dest;
final double x1 = Math.max(src1.getMinX(), src2.getMinX());
final double y1 = Math.max(src1.getMinY(), src2.getMinY());
final double z1 = Math.max(src1.getMinZ(), src2.getMinZ());
final double t1 = Math.max(src1.getMinT(), src2.getMinT());
final double c1 = Math.max(src1.getMinC(), src2.getMinC());
final double x2 = Math.min(src1.getMaxX(), src2.getMaxX());
final double y2 = Math.min(src1.getMaxY(), src2.getMaxY());
final double z2 = Math.min(src1.getMaxZ(), src2.getMaxZ());
final double t2 = Math.min(src1.getMaxT(), src2.getMaxT());
final double c2 = Math.min(src1.getMaxC(), src2.getMaxC());
double dx;
double dy;
double dz;
double dt;
double dc;
// special infinite case
if (x2 == java.lang.Double.POSITIVE_INFINITY)
dx = java.lang.Double.POSITIVE_INFINITY;
else
dx = x2 - x1;
// special infinite case
if (y2 == java.lang.Double.POSITIVE_INFINITY)
dy = java.lang.Double.POSITIVE_INFINITY;
else
dy = y2 - y1;
// special infinite case
if (z2 == java.lang.Double.POSITIVE_INFINITY)
dz = java.lang.Double.POSITIVE_INFINITY;
else
dz = z2 - z1;
// special infinite case
if (t2 == java.lang.Double.POSITIVE_INFINITY)
dt = java.lang.Double.POSITIVE_INFINITY;
else
dt = t2 - t1;
// special infinite case
if (c2 == java.lang.Double.POSITIVE_INFINITY)
dc = java.lang.Double.POSITIVE_INFINITY;
else
dc = c2 - c1;
result.setRect(x1, y1, z1, t1, c1, dx, dy, dz, dt, dc);
return result;
}
/**
* Returns a new <code>Rectangle5D</code> object representing the intersection of this
* <code>Rectangle5D</code> with the specified <code>Rectangle5D</code>.
*
* @param r
* the <code>Rectangle5D</code> to be intersected with this <code>Rectangle5D</code>
* @return the largest <code>Rectangle5D</code> contained in both the specified
* <code>Rectangle5D</code> and in this <code>Rectangle5D</code>.
*/
public abstract Rectangle5D createIntersection(Rectangle5D r);
/**
* Unions the pair of source <code>Rectangle5D</code> objects and puts the result into the
* specified destination <code>Rectangle5D</code> object. One of the source rectangles can also
* be the destination to avoid creating a third Rectangle5D object, but in this case the
* original points of this source rectangle will be overwritten by this method.
*
* @param src1
* the first of a pair of <code>Rectangle5D</code> objects to be combined with each other
* @param src2
* the second of a pair of <code>Rectangle5D</code> objects to be combined with each
* other
* @param dest
* the <code>Rectangle5D</code> that holds the
* results of the union of <code>src1</code> and <code>src2</code>.<br>
* If set to <code>null</code> then a new Rectangle5D is created.
* @return resulting <code>Rectangle5D</code> from the intersect process.
*/
public static Rectangle5D union(Rectangle5D src1, Rectangle5D src2, Rectangle5D dest)
{
final Rectangle5D result;
if (dest == null)
result = new Rectangle5D.Double();
else
result = dest;
double x1 = Math.min(src1.getMinX(), src2.getMinX());
double y1 = Math.min(src1.getMinY(), src2.getMinY());
double z1 = Math.min(src1.getMinZ(), src2.getMinZ());
double t1 = Math.min(src1.getMinT(), src2.getMinT());
double c1 = Math.min(src1.getMinC(), src2.getMinC());
double x2 = Math.max(src1.getMaxX(), src2.getMaxX());
double y2 = Math.max(src1.getMaxY(), src2.getMaxY());
double z2 = Math.max(src1.getMaxZ(), src2.getMaxZ());
double t2 = Math.max(src1.getMaxT(), src2.getMaxT());
double c2 = Math.max(src1.getMaxC(), src2.getMaxC());
double dx;
double dy;
double dz;
double dt;
double dc;
// special infinite case
if (x2 == java.lang.Double.POSITIVE_INFINITY)
dx = java.lang.Double.POSITIVE_INFINITY;
else
dx = x2 - x1;
// special infinite case
if (y2 == java.lang.Double.POSITIVE_INFINITY)
dy = java.lang.Double.POSITIVE_INFINITY;
else
dy = y2 - y1;
// special infinite case
if (z2 == java.lang.Double.POSITIVE_INFINITY)
dz = java.lang.Double.POSITIVE_INFINITY;
else
dz = z2 - z1;
// special infinite case
if (t2 == java.lang.Double.POSITIVE_INFINITY)
dt = java.lang.Double.POSITIVE_INFINITY;
else
dt = t2 - t1;
// special infinite case
if (c2 == java.lang.Double.POSITIVE_INFINITY)
dc = java.lang.Double.POSITIVE_INFINITY;
else
dc = c2 - c1;
result.setRect(x1, y1, z1, t1, c1, dx, dy, dz, dt, dc);
return result;
}
/**
* Returns a new <code>Rectangle5D</code> object representing the union of this
* <code>Rectangle5D</code> with the specified <code>Rectangle5D</code>.
*
* @param r
* the <code>Rectangle5D</code> to be combined with this <code>Rectangle5D</code>
* @return the smallest <code>Rectangle5D</code> containing both the specified
* <code>Rectangle5D</code> and this <code>Rectangle5D</code>.
*/
public abstract Rectangle5D createUnion(Rectangle5D r);
/**
* Sets the position and size of this <code>Rectangle5D</code> to the specified
* <code>double</code> values.
*
* @param x
* the X coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param y
* the Y coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param z
* the Z coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param t
* the T coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param c
* the C coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param sizeX
* size for X dimension of this <code>Rectangle5D</code>
* @param sizeY
* size for Y dimension of this <code>Rectangle5D</code>
* @param sizeZ
* size for Z dimension of this <code>Rectangle5D</code>
* @param sizeT
* size for T dimension of this <code>Rectangle5D</code>
* @param sizeC
* size for C dimension of this <code>Rectangle5D</code>
*/
public abstract void setRect(double x, double y, double z, double t, double c, double sizeX, double sizeY,
double sizeZ, double sizeT, double sizeC);
/**
* Returns the minimum X coordinate.
*/
public abstract double getX();
/**
* Returns the minimum Y coordinate.
*/
public abstract double getY();
/**
* Returns the minimum Z coordinate.
*/
public abstract double getZ();
/**
* Returns the minimum T coordinate.
*/
public abstract double getT();
/**
* Returns the minimum C coordinate.
*/
public abstract double getC();
/**
* Returns the size of X dimension.
*/
public abstract double getSizeX();
/**
* Returns the size of Y dimension.
*/
public abstract double getSizeY();
/**
* Returns the size of Z dimension.
*/
public abstract double getSizeZ();
/**
* Returns the size of T dimension.
*/
public abstract double getSizeT();
/**
* Returns the size of C dimension.
*/
public abstract double getSizeC();
/**
* Returns the point coordinate.
*/
public abstract Point5D getPosition();
/**
* Returns the dimension.
*/
public abstract Dimension5D getDimension();
/**
* Returns an integer {@link Rectangle5D} that completely encloses the
* double <code>Rectangle</code>. The returned <code>Rectangle</code> might also fail to
* completely enclose the original double <code>Rectangle</code> if it overflows
* the limited range of the integer data type.
*
* @return an integer <code>Rectangle</code> that completely encloses
* the actual double <code>Rectangle</code>.
*/
public Rectangle5D.Integer toInteger()
{
double sx = getSizeX();
double sy = getSizeY();
double sz = getSizeZ();
double st = getSizeT();
double sc = getSizeC();
double x = getX();
double y = getY();
double z = getZ();
double t = getT();
double c = getC();
int ix = (int) Math.floor(x);
int iy = (int) Math.floor(y);
int iz = (int) Math.floor(z);
int it = (int) Math.floor(t);
int ic = (int) Math.floor(c);
int isx;
int isy;
int isz;
int ist;
int isc;
if (sx < 0d)
isx = 0;
else if (sx >= java.lang.Integer.MAX_VALUE)
isx = java.lang.Integer.MAX_VALUE;
else
isx = ((int) Math.ceil(x + sx)) - ix;
if (sy < 0d)
isy = 0;
else if (sy >= java.lang.Integer.MAX_VALUE)
isy = java.lang.Integer.MAX_VALUE;
else
isy = ((int) Math.ceil(y + sy)) - iy;
if (sz < 0d)
isz = 0;
else if (sz >= java.lang.Integer.MAX_VALUE)
isz = java.lang.Integer.MAX_VALUE;
else
isz = ((int) Math.ceil(z + sz)) - iz;
if (st < 0d)
ist = 0;
else if (st >= java.lang.Integer.MAX_VALUE)
ist = java.lang.Integer.MAX_VALUE;
else
ist = ((int) Math.ceil(t + st)) - it;
if (sc < 0d)
isc = 0;
else if (sc >= java.lang.Integer.MAX_VALUE)
isc = java.lang.Integer.MAX_VALUE;
else
isc = ((int) Math.ceil(c + sc)) - ic;
return new Rectangle5D.Integer(ix, iy, iz, it, ic, isx, isy, isz, ist, isc);
}
/**
* Sets the minimum X coordinate.
*/
public abstract void setX(double x);
/**
* Sets the minimum Y coordinate.
*/
public abstract void setY(double y);
/**
* Sets the minimum Z coordinate.
*/
public abstract void setZ(double z);
/**
* Sets the minimum T coordinate.
*/
public abstract void setT(double t);
/**
* Sets the minimum C coordinate.
*/
public abstract void setC(double c);
/**
* Sets the size of X dimension.
*/
public abstract void setSizeX(double value);
/**
* Sets the size of Y dimension.
*/
public abstract void setSizeY(double value);
/**
* Sets the size of Z dimension.
*/
public abstract void setSizeZ(double value);
/**
* Sets the size of T dimension.
*/
public abstract void setSizeT(double value);
/**
* Sets the size of C dimension.
*/
public abstract void setSizeC(double value);
/**
* Returns the smallest X coordinate of the rectangle.
*/
public double getMinX()
{
return getX();
}
/**
* Returns the smallest Y coordinate of the rectangle.
*/
public double getMinY()
{
return getY();
}
/**
* Returns the smallest Z coordinate of the rectangle.
*/
public double getMinZ()
{
return getZ();
}
/**
* Returns the smallest T coordinate of the rectangle.
*/
public double getMinT()
{
return getT();
}
/**
* Returns the smallest C coordinate of the rectangle.
*/
public double getMinC()
{
return getC();
}
/**
* Returns the largest X coordinate of the rectangle.
*/
public double getMaxX()
{
// handle this special case
if (getSizeX() == java.lang.Double.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return getX() + getSizeX();
}
/**
* Returns the largest Y coordinate of the rectangle.
*/
public double getMaxY()
{
// handle this special case
if (getSizeY() == java.lang.Double.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return getY() + getSizeY();
}
/**
* Returns the largest Z coordinate of the rectangle.
*/
public double getMaxZ()
{
// handle this special case
if (getSizeZ() == java.lang.Double.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return getZ() + getSizeZ();
}
/**
* Returns the largest T coordinate of the rectangle.
*/
public double getMaxT()
{
// handle this special case
if (getSizeT() == java.lang.Double.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return getT() + getSizeT();
}
/**
* Returns the largest C coordinate of the rectangle.
*/
public double getMaxC()
{
// handle this special case
if (getSizeC() == java.lang.Double.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return getC() + getSizeC();
}
/**
* Returns the X coordinate of the center of the rectangle.
*/
public double getCenterX()
{
// handle this special case
if (isInfiniteX())
return 0d;
return getX() + (getSizeX() / 2d);
}
/**
* Returns the Y coordinate of the center of the rectangle.
*/
public double getCenterY()
{
// handle this special case
if (isInfiniteY())
return 0d;
return getY() + (getSizeY() / 2d);
}
/**
* Returns the Z coordinate of the center of the rectangle.
*/
public double getCenterZ()
{
// handle this special case
if (isInfiniteZ())
return 0d;
return getZ() + (getSizeZ() / 2d);
}
/**
* Returns the T coordinate of the center of the rectangle.
*/
public double getCenterT()
{
// handle this special case
if (isInfiniteT())
return 0d;
return getT() + (getSizeT() / 2d);
}
/**
* Returns the C coordinate of the center of the rectangle.
*/
public double getCenterC()
{
// handle this special case
if (isInfiniteC())
return 0d;
return getC() + (getSizeC() / 2d);
}
/**
* Determines whether the <code>Rectangle5D</code> is empty.
*
* @return <code>true</code> if the <code>Rectangle5D</code> is empty; <code>false</code>
* otherwise.
*/
public boolean isEmpty()
{
return (getSizeX() <= 0d) || (getSizeY() <= 0d) || (getSizeZ() <= 0d) || (getSizeT() <= 0d)
|| (getSizeC() <= 0d);
}
/**
* Returns <code>true</code> if the X dimension should be considered as infinite.
*/
public boolean isInfiniteX()
{
return (getX() == java.lang.Double.NEGATIVE_INFINITY) && (getSizeX() == java.lang.Double.POSITIVE_INFINITY);
}
/**
* Returns <code>true</code> if the Y dimension should be considered as infinite.
*/
public boolean isInfiniteY()
{
return (getY() == java.lang.Double.NEGATIVE_INFINITY) && (getSizeY() == java.lang.Double.POSITIVE_INFINITY);
}
/**
* Returns <code>true</code> if the Z dimension should be considered as infinite.
*/
public boolean isInfiniteZ()
{
return (getZ() == java.lang.Double.NEGATIVE_INFINITY) && (getSizeZ() == java.lang.Double.POSITIVE_INFINITY);
}
/**
* Returns <code>true</code> if the T dimension should be considered as infinite.
*/
public boolean isInfiniteT()
{
return (getT() == java.lang.Double.NEGATIVE_INFINITY) && (getSizeT() == java.lang.Double.POSITIVE_INFINITY);
}
/**
* Returns <code>true</code> if the C dimension should be considered as infinite.
*/
public boolean isInfiniteC()
{
return (getC() == java.lang.Double.NEGATIVE_INFINITY) && (getSizeC() == java.lang.Double.POSITIVE_INFINITY);
}
/**
* Sets the X dimension to infinite.
*/
public void setInfiniteX()
{
setX(java.lang.Double.NEGATIVE_INFINITY);
setSizeX(java.lang.Double.POSITIVE_INFINITY);
}
/**
* Sets the Y dimension to infinite.
*/
public void setInfiniteY()
{
setY(java.lang.Double.NEGATIVE_INFINITY);
setSizeY(java.lang.Double.POSITIVE_INFINITY);
}
/**
* Sets the Z dimension to infinite.
*/
public void setInfiniteZ()
{
setZ(java.lang.Double.NEGATIVE_INFINITY);
setSizeZ(java.lang.Double.POSITIVE_INFINITY);
}
/**
* Sets the T dimension to infinite.
*/
public void setInfiniteT()
{
setT(java.lang.Double.NEGATIVE_INFINITY);
setSizeT(java.lang.Double.POSITIVE_INFINITY);
}
/**
* Sets the C dimension to infinite.
*/
public void setInfiniteC()
{
setC(java.lang.Double.NEGATIVE_INFINITY);
setSizeC(java.lang.Double.POSITIVE_INFINITY);
}
/**
* Tests if the specified coordinates are inside the boundary of the <code>Rectangle5D</code>.
*
* @param x
* the specified X coordinate to be tested
* @param y
* the specified Y coordinate to be tested
* @param z
* the specified Z coordinate to be tested
* @param t
* the specified T coordinate to be tested
* @param c
* the specified C coordinate to be tested
* @return <code>true</code> if the specified coordinates are inside
* the <code>Rectangle5D</code> boundary; <code>false</code> otherwise.
*/
public boolean contains(double x, double y, double z, double t, double c)
{
return (x >= getMinX()) && (y >= getMinY()) && (z >= getMinZ()) && (t >= getMinT()) && (c >= getMinC())
&& (x < getMaxX()) && (y < getMaxY()) && (z < getMaxZ()) && (t < getMaxT()) && (c < getMaxC());
}
/**
* Tests if the <code>Rectangle5D</code> entirely contains the specified 5D rectangular area.<br>
* All coordinates that lie inside the 5D rectangular area must lie within the
* <code>Rectangle5D</code>.
*
* @param x
* the X coordinate of the minimum corner position of the specified rectangular area
* @param y
* the Y coordinate of the minimum corner position of the specified rectangular area
* @param z
* the Z coordinate of the minimum corner position of the specified rectangular area
* @param t
* the T coordinate of the minimum corner position of the specified rectangular area
* @param c
* the C coordinate of the minimum corner position of the specified rectangular area
* @param sizeX
* size for X dimension of the specified rectangular area
* @param sizeY
* size for Y dimension of the specified rectangular area
* @param sizeZ
* size for Z dimension of the specified rectangular area
* @param sizeT
* size for T dimension of the specified rectangular area
* @param sizeC
* size for C dimension of the specified rectangular area
* @return <code>true</code> if the <code>Rectangle5D</code> entirely contains the
* specified 5D rectangular area; <code>false</code> otherwise
* @see #intersects
*/
public boolean contains(double x, double y, double z, double t, double c, double sizeX, double sizeY, double sizeZ,
double sizeT, double sizeC)
{
final double maxX;
final double maxY;
final double maxZ;
final double maxT;
final double maxC;
// special infinite case
if (sizeX == java.lang.Double.POSITIVE_INFINITY)
maxX = java.lang.Double.POSITIVE_INFINITY;
else
maxX = x + sizeX;
// special infinite case
if (sizeY == java.lang.Double.POSITIVE_INFINITY)
maxY = java.lang.Double.POSITIVE_INFINITY;
else
maxY = y + sizeY;
// special infinite case
if (sizeZ == java.lang.Double.POSITIVE_INFINITY)
maxZ = java.lang.Double.POSITIVE_INFINITY;
else
maxZ = z + sizeZ;
// special infinite case
if (sizeT == java.lang.Double.POSITIVE_INFINITY)
maxT = java.lang.Double.POSITIVE_INFINITY;
else
maxT = t + sizeT;
// special infinite case
if (sizeC == java.lang.Double.POSITIVE_INFINITY)
maxC = java.lang.Double.POSITIVE_INFINITY;
else
maxC = c + sizeC;
return (x >= getMinX()) && (y >= getMinY()) && (z >= getMinZ()) && (t >= getMinT()) && (c >= getMinC())
&& (maxX <= getMaxX()) && (maxY <= getMaxY()) && (maxZ <= getMaxZ()) && (maxT <= getMaxT())
&& (maxC <= getMaxC());
}
/**
* Tests if the <code>Rectangle5D</code> entirely contains the specified
* <code>Rectangle5D</code>.
*
* @see #contains(double, double, double, double, double, double, double, double, double,
* double)
*/
public boolean contains(Rectangle5D rect)
{
return contains(rect.getX(), rect.getY(), rect.getZ(), rect.getT(), rect.getC(), rect.getSizeX(),
rect.getSizeY(), rect.getSizeZ(), rect.getSizeT(), rect.getSizeC());
}
/**
* Tests if the interior of the <code>Rectangle5D</code> intersects the interior of a specified
* 5D rectangular area.<br>
* The 5D rectangular area is considered to intersect the <code>Rectangle5D</code> if any point
* is contained in both the interior of the <code>Rectangle5D</code> and the specified
* rectangular area.
*
* @param x
* the X coordinate of the minimum corner position of the specified rectangular area
* @param y
* the Y coordinate of the minimum corner position of the specified rectangular area
* @param z
* the Z coordinate of the minimum corner position of the specified rectangular area
* @param t
* the T coordinate of the minimum corner position of the specified rectangular area
* @param c
* the C coordinate of the minimum corner position of the specified rectangular area
* @param sizeX
* size for X dimension of the specified rectangular area
* @param sizeY
* size for Y dimension of the specified rectangular area
* @param sizeZ
* size for Z dimension of the specified rectangular area
* @param sizeT
* size for T dimension of the specified rectangular area
* @param sizeC
* size for C dimension of the specified rectangular area
* @return <code>true</code> if the interior of the <code>Rectangle5D</code> and
* the interior of the 5D rectangular area intersect.
*/
public boolean intersects(double x, double y, double z, double t, double c, double sizeX, double sizeY,
double sizeZ, double sizeT, double sizeC)
{
final double maxX;
final double maxY;
final double maxZ;
final double maxT;
final double maxC;
// special infinite case
if (sizeX == java.lang.Double.POSITIVE_INFINITY)
maxX = java.lang.Double.POSITIVE_INFINITY;
else
maxX = x + sizeX;
// special infinite case
if (sizeY == java.lang.Double.POSITIVE_INFINITY)
maxY = java.lang.Double.POSITIVE_INFINITY;
else
maxY = y + sizeY;
// special infinite case
if (sizeZ == java.lang.Double.POSITIVE_INFINITY)
maxZ = java.lang.Double.POSITIVE_INFINITY;
else
maxZ = z + sizeZ;
// special infinite case
if (sizeT == java.lang.Double.POSITIVE_INFINITY)
maxT = java.lang.Double.POSITIVE_INFINITY;
else
maxT = t + sizeT;
// special infinite case
if (sizeC == java.lang.Double.POSITIVE_INFINITY)
maxC = java.lang.Double.POSITIVE_INFINITY;
else
maxC = c + sizeC;
return (maxX > getMinX()) && (maxY > getMinY()) && (maxZ > getMinZ()) && (maxT > getMinT())
&& (maxC > getMinC()) && (x < getMaxX()) && (y < getMaxY()) && (z < getMaxZ()) && (t < getMaxT())
&& (c < getMaxC());
}
/**
* Tests if the interior of the <code>Rectangle5D</code> intersects the interior of a specified
* <code>Rectangle5D</code>.<br>
*
* @see #intersects(double, double, double, double, double, double, double, double, double,
* double)
*/
public boolean intersects(Rectangle5D rect)
{
return intersects(rect.getX(), rect.getY(), rect.getZ(), rect.getT(), rect.getC(), rect.getSizeX(),
rect.getSizeY(), rect.getSizeZ(), rect.getSizeT(), rect.getSizeC());
}
/**
* Adds a 5D point, specified by the double precision coordinates arguments, to this
* <code>Rectangle5D</code>. The resulting <code>Rectangle5D</code> is the smallest
* <code>Rectangle5D</code> that contains both the original <code>Rectangle5D</code> and the
* specified 5D point.
* <p>
* After adding a 5D point, a call to <code>contains</code> with the added point as an argument
* does not necessarily return <code>true</code>. The <code>contains</code> method does not
* return <code>true</code> for points on the edges of a rectangle. Therefore, if the added 5D
* point falls on edge of the enlarged rectangle, <code>contains</code> returns
* <code>false</code> for that point.
*
* @param newx
* the X coordinate of the new point
* @param newy
* the Y coordinate of the new point
* @param newz
* the Z coordinate of the new point
* @param newt
* the T coordinate of the new point
* @param newc
* the C coordinate of the new point
*/
public void add(double newx, double newy, double newz, double newt, double newc)
{
double x1 = Math.min(getMinX(), newx);
double x2 = Math.max(getMaxX(), newx);
double y1 = Math.min(getMinY(), newy);
double y2 = Math.max(getMaxY(), newy);
double z1 = Math.min(getMinZ(), newz);
double z2 = Math.max(getMaxZ(), newz);
double t1 = Math.min(getMinT(), newt);
double t2 = Math.max(getMaxT(), newt);
double c1 = Math.min(getMinC(), newc);
double c2 = Math.max(getMaxC(), newc);
double dx;
double dy;
double dz;
double dt;
double dc;
// special infinite case
if (x2 == java.lang.Double.POSITIVE_INFINITY)
dx = java.lang.Double.POSITIVE_INFINITY;
else
dx = x2 - x1;
// special infinite case
if (y2 == java.lang.Double.POSITIVE_INFINITY)
dy = java.lang.Double.POSITIVE_INFINITY;
else
dy = y2 - y1;
// special infinite case
if (z2 == java.lang.Double.POSITIVE_INFINITY)
dz = java.lang.Double.POSITIVE_INFINITY;
else
dz = z2 - z1;
// special infinite case
if (t2 == java.lang.Double.POSITIVE_INFINITY)
dt = java.lang.Double.POSITIVE_INFINITY;
else
dt = t2 - t1;
// special infinite case
if (c2 == java.lang.Double.POSITIVE_INFINITY)
dc = java.lang.Double.POSITIVE_INFINITY;
else
dc = c2 - c1;
setRect(x1, y1, z1, t1, c1, dx, dy, dz, dt, dc);
}
/**
* Adds the <code>Point5D</code> object <code>pt</code> to this <code>Rectangle5D</code>.
* The resulting <code>Rectangle5D</code> is the smallest <code>Rectangle5D</code> that contains
* both the original <code>Rectangle5D</code> and the specified <code>Point5D</code>.
* <p>
* After adding a point, a call to <code>contains</code> with the added point as an argument
* does not necessarily return <code>true</code>. The <code>contains</code> method does not
* return <code>true</code> for points on the edges of a rectangle. Therefore, if the added
* point falls on edge of the enlarged rectangle, <code>contains</code> returns
* <code>false</code> for that point.
*
* @param pt
* the new <code>Point5D</code> to add to this <code>Rectangle5D</code>.
*/
public void add(Point5D pt)
{
add(pt.getX(), pt.getY(), pt.getZ(), pt.getT(), pt.getC());
}
/**
* Adds a <code>Rectangle5D</code> object to this <code>Rectangle5D</code>. The resulting
* <code>Rectangle5D</code> is the union of the two <code>Rectangle5D</code> objects.
*
* @param r
* the <code>Rectangle5D</code> to add to this <code>Rectangle5D</code>.
*/
public void add(Rectangle5D r)
{
union(this, r, this);
}
/**
* Convert to 2D rectangle
*/
public abstract Rectangle2D toRectangle2D();
/**
* Convert to 3D rectangle
*/
public abstract Rectangle3D toRectangle3D();
/**
* Convert to 4D rectangle
*/
public abstract Rectangle4D toRectangle4D();
@Override
public boolean equals(Object obj)
{
if (obj == this)
return true;
if (obj instanceof Rectangle5D)
{
final Rectangle5D rect = (Rectangle5D) obj;
return (getX() == rect.getX()) && (getY() == rect.getY()) && (getC() == rect.getC())
&& (getZ() == rect.getZ()) && (getT() == rect.getT()) && (getSizeX() == rect.getSizeX())
&& (getSizeY() == rect.getSizeY()) && (getSizeC() == rect.getSizeC())
&& (getSizeZ() == rect.getSizeZ()) && (getSizeT() == rect.getSizeT());
}
return super.equals(obj);
}
@Override
public int hashCode()
{
long bits = java.lang.Double.doubleToLongBits(getX());
bits ^= java.lang.Double.doubleToLongBits(getY());
bits ^= java.lang.Double.doubleToLongBits(getC());
bits ^= java.lang.Double.doubleToLongBits(getZ());
bits ^= java.lang.Double.doubleToLongBits(getT());
bits ^= java.lang.Double.doubleToLongBits(getSizeX());
bits ^= java.lang.Double.doubleToLongBits(getSizeY());
bits ^= java.lang.Double.doubleToLongBits(getSizeC());
bits ^= java.lang.Double.doubleToLongBits(getSizeZ());
bits ^= java.lang.Double.doubleToLongBits(getSizeT());
return (((int) bits) ^ ((int) (bits >> 32)));
}
/**
* Creates a new object of the same class as this object.
*
* @return a clone of this instance.
* @exception OutOfMemoryError
* if there is not enough memory.
* @see java.lang.Cloneable
*/
@Override
public Object clone()
{
try
{
return super.clone();
}
catch (CloneNotSupportedException e)
{
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
@Override
public String toString()
{
return getClass().getName() + "[" + getX() + "," + getY() + "," + getZ() + "," + getT() + "," + getC() + " - "
+ getSizeX() + "," + getSizeY() + "," + getSizeZ() + "," + getSizeT() + "," + getSizeC() + "]";
}
public static class Double extends Rectangle5D
{
public double x;
public double y;
public double z;
public double t;
public double c;
public double sizeX;
public double sizeY;
public double sizeZ;
public double sizeT;
public double sizeC;
public Double(double x, double y, double z, double t, double c, double sizeX, double sizeY, double sizeZ,
double sizeT, double sizeC)
{
super();
this.x = x;
this.y = y;
this.z = z;
this.t = t;
this.c = c;
this.sizeX = sizeX;
this.sizeY = sizeY;
this.sizeZ = sizeZ;
this.sizeT = sizeT;
this.sizeC = sizeC;
}
public Double(Rectangle5D r)
{
this(r.getX(), r.getY(), r.getZ(), r.getT(), r.getC(), r.getSizeX(), r.getSizeY(), r.getSizeZ(), r
.getSizeT(), r.getSizeC());
}
public Double()
{
this(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
@Override
public void setRect(double x, double y, double z, double t, double c, double sizeX, double sizeY, double sizeZ,
double sizeT, double sizeC)
{
this.x = x;
this.y = y;
this.z = z;
this.t = t;
this.c = c;
this.sizeX = sizeX;
this.sizeY = sizeY;
this.sizeZ = sizeZ;
this.sizeT = sizeT;
this.sizeC = sizeC;
}
@Override
public double getX()
{
return x;
}
@Override
public void setX(double value)
{
x = value;
}
@Override
public double getY()
{
return y;
}
@Override
public void setY(double value)
{
y = value;
}
@Override
public double getZ()
{
return z;
}
@Override
public void setZ(double value)
{
z = value;
}
@Override
public double getT()
{
return t;
}
@Override
public void setT(double value)
{
t = value;
}
@Override
public double getC()
{
return c;
}
@Override
public void setC(double value)
{
c = value;
}
@Override
public double getSizeX()
{
return sizeX;
}
@Override
public void setSizeX(double value)
{
sizeX = value;
}
@Override
public double getSizeY()
{
return sizeY;
}
@Override
public void setSizeY(double value)
{
sizeY = value;
}
@Override
public double getSizeZ()
{
return sizeZ;
}
@Override
public void setSizeZ(double value)
{
sizeZ = value;
}
@Override
public double getSizeT()
{
return sizeT;
}
@Override
public void setSizeT(double value)
{
sizeT = value;
}
@Override
public double getSizeC()
{
return sizeC;
}
@Override
public void setSizeC(double value)
{
sizeC = value;
}
@Override
public Point5D.Double getPosition()
{
return new Point5D.Double(x, y, z, t, c);
}
@Override
public Dimension5D.Double getDimension()
{
return new Dimension5D.Double(sizeX, sizeY, sizeZ, sizeT, sizeC);
}
@Override
public Rectangle5D createIntersection(Rectangle5D r)
{
final Rectangle5D.Double result = new Rectangle5D.Double();
intersect(this, r, result);
return result;
}
@Override
public Rectangle5D createUnion(Rectangle5D r)
{
final Rectangle5D.Double result = new Rectangle5D.Double();
union(this, r, result);
return result;
}
@Override
public Rectangle2D toRectangle2D()
{
return new Rectangle2D.Double(x, y, sizeX, sizeY);
}
@Override
public Rectangle3D toRectangle3D()
{
return new Rectangle3D.Double(x, y, z, sizeX, sizeY, sizeZ);
}
@Override
public Rectangle4D toRectangle4D()
{
return new Rectangle4D.Double(x, y, z, t, sizeX, sizeY, sizeZ, sizeT);
}
}
public static class Float extends Rectangle5D
{
public float x;
public float y;
public float z;
public float t;
public float c;
public float sizeX;
public float sizeY;
public float sizeZ;
public float sizeT;
public float sizeC;
public Float(float x, float y, float z, float t, float c, float sizeX, float sizeY, float sizeZ, float sizeT,
float sizeC)
{
super();
this.x = x;
this.y = y;
this.z = z;
this.t = t;
this.c = c;
this.sizeX = sizeX;
this.sizeY = sizeY;
this.sizeZ = sizeZ;
this.sizeT = sizeT;
this.sizeC = sizeC;
}
public Float(Rectangle5D r)
{
this((float) r.getX(), (float) r.getY(), (float) r.getZ(), (float) r.getT(), (float) r.getC(), (float) r
.getSizeX(), (float) r.getSizeY(), (float) r.getSizeZ(), (float) r.getSizeT(), (float) r.getSizeC());
}
public Float()
{
this(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
@Override
public void setRect(double x, double y, double z, double t, double c, double sizeX, double sizeY, double sizeZ,
double sizeT, double sizeC)
{
this.x = (float) x;
this.y = (float) y;
this.z = (float) z;
this.t = (float) t;
this.c = (float) c;
this.sizeX = (float) sizeX;
this.sizeY = (float) sizeY;
this.sizeZ = (float) sizeZ;
this.sizeT = (float) sizeT;
this.sizeC = (float) sizeC;
}
@Override
public double getX()
{
// special infinite case
if (x == java.lang.Float.NEGATIVE_INFINITY)
return java.lang.Double.NEGATIVE_INFINITY;
if (x == java.lang.Float.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return x;
}
@Override
public void setX(double value)
{
x = (float) value;
}
@Override
public double getY()
{
// special infinite case
if (y == java.lang.Float.NEGATIVE_INFINITY)
return java.lang.Double.NEGATIVE_INFINITY;
if (y == java.lang.Float.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return y;
}
@Override
public void setY(double value)
{
y = (float) value;
}
@Override
public double getZ()
{
// special infinite case
if (z == java.lang.Float.NEGATIVE_INFINITY)
return java.lang.Double.NEGATIVE_INFINITY;
if (z == java.lang.Float.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return z;
}
@Override
public void setZ(double value)
{
z = (float) value;
}
@Override
public double getT()
{
// special infinite case
if (t == java.lang.Float.NEGATIVE_INFINITY)
return java.lang.Double.NEGATIVE_INFINITY;
if (t == java.lang.Float.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return t;
}
@Override
public void setT(double value)
{
t = (float) value;
}
@Override
public double getC()
{
// special infinite case
if (c == java.lang.Float.NEGATIVE_INFINITY)
return java.lang.Double.NEGATIVE_INFINITY;
if (c == java.lang.Float.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return c;
}
@Override
public void setC(double value)
{
c = (float) value;
}
@Override
public double getSizeX()
{
// special infinite case
if (sizeX == java.lang.Float.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return sizeX;
}
@Override
public void setSizeX(double value)
{
sizeX = (float) value;
}
@Override
public double getSizeY()
{
// special infinite case
if (sizeY == java.lang.Float.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return sizeY;
}
@Override
public void setSizeY(double value)
{
sizeY = (float) value;
}
@Override
public double getSizeZ()
{
// special infinite case
if (sizeZ == java.lang.Float.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return sizeZ;
}
@Override
public void setSizeZ(double value)
{
sizeZ = (float) value;
}
@Override
public double getSizeT()
{
// special infinite case
if (sizeT == java.lang.Float.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return sizeT;
}
@Override
public void setSizeT(double value)
{
sizeT = (float) value;
}
@Override
public double getSizeC()
{
// special infinite case
if (sizeC == java.lang.Float.POSITIVE_INFINITY)
return java.lang.Double.POSITIVE_INFINITY;
return sizeC;
}
@Override
public void setSizeC(double value)
{
sizeC = (float) value;
}
@Override
public Point5D.Float getPosition()
{
return new Point5D.Float(x, y, z, t, c);
}
@Override
public Dimension5D.Float getDimension()
{
return new Dimension5D.Float(sizeX, sizeY, sizeZ, sizeT, sizeC);
}
@Override
public Rectangle5D createIntersection(Rectangle5D r)
{
final Rectangle5D.Float result = new Rectangle5D.Float();
intersect(this, r, result);
return result;
}
@Override
public Rectangle5D createUnion(Rectangle5D r)
{
final Rectangle5D.Float result = new Rectangle5D.Float();
union(this, r, result);
return result;
}
@Override
public Rectangle2D toRectangle2D()
{
return new Rectangle2D.Float(x, y, sizeX, sizeY);
}
@Override
public Rectangle3D toRectangle3D()
{
return new Rectangle3D.Float(x, y, z, sizeX, sizeY, sizeZ);
}
@Override
public Rectangle4D toRectangle4D()
{
return new Rectangle4D.Float(x, y, z, t, sizeX, sizeY, sizeZ, sizeT);
}
}
public static class Integer extends Rectangle5D
{
public int x;
public int y;
public int z;
public int t;
public int c;
public int sizeX;
public int sizeY;
public int sizeZ;
public int sizeT;
public int sizeC;
public Integer(int x, int y, int z, int t, int c, int sizeX, int sizeY, int sizeZ, int sizeT, int sizeC)
{
super();
this.x = x;
this.y = y;
this.z = z;
this.t = t;
this.c = c;
this.sizeX = sizeX;
this.sizeY = sizeY;
this.sizeZ = sizeZ;
this.sizeT = sizeT;
this.sizeC = sizeC;
}
public Integer(Rectangle5D.Integer r)
{
this(r.x, r.y, r.z, r.t, r.c, r.sizeX, r.sizeY, r.sizeZ, r.sizeT, r.sizeC);
}
public Integer(Rectangle5D r)
{
this(r.toInteger());
}
public Integer()
{
this(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
/**
* Sets the bounds of this {@code Rectangle5D} to the integer bounds
* which encompass the specified double bounds.
*
* @param x
* the X coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param y
* the Y coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param z
* the Z coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param t
* the T coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param c
* the C coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param sizeX
* size for X dimension of this <code>Rectangle5D</code>
* @param sizeY
* size for Y dimension of this <code>Rectangle5D</code>
* @param sizeZ
* size for Z dimension of this <code>Rectangle5D</code>
* @param sizeT
* size for T dimension of this <code>Rectangle5D</code>
* @param sizeC
* size for C dimension of this <code>Rectangle5D</code>
*/
@Override
public void setRect(double x, double y, double z, double t, double c, double sizeX, double sizeY, double sizeZ,
double sizeT, double sizeC)
{
final Rectangle5D.Integer r = new Rectangle5D.Double(x, y, z, t, c, sizeX, sizeY, sizeZ, sizeT, sizeC)
.toInteger();
setRect(r.x, r.y, r.z, r.t, r.c, r.sizeX, r.sizeY, r.sizeZ, r.sizeT, r.sizeC);
}
/**
* Sets the position and size of this <code>Rectangle5D</code> to the specified
* <code>integer</code> values.
*
* @param x
* the X coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param y
* the Y coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param z
* the Z coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param t
* the T coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param c
* the C coordinate of the minimum corner position of this <code>Rectangle5D</code>
* @param sizeX
* size for X dimension of this <code>Rectangle5D</code>
* @param sizeY
* size for Y dimension of this <code>Rectangle5D</code>
* @param sizeZ
* size for Z dimension of this <code>Rectangle5D</code>
* @param sizeT
* size for T dimension of this <code>Rectangle5D</code>
* @param sizeC
* size for C dimension of this <code>Rectangle5D</code>
*/
public void setRect(int x, int y, int z, int t, int c, int sizeX, int sizeY, int sizeZ, int sizeT, int sizeC)
{
this.x = x;
this.y = y;
this.z = z;
this.t = t;
this.c = c;
this.sizeX = sizeX;
this.sizeY = sizeY;
this.sizeZ = sizeZ;
this.sizeT = sizeT;
this.sizeC = sizeC;
}
@Override
public double getX()
{
// special infinite case
if (x == java.lang.Integer.MIN_VALUE)
return java.lang.Double.NEGATIVE_INFINITY;
if (x == java.lang.Integer.MAX_VALUE)
return java.lang.Double.POSITIVE_INFINITY;
return x;
}
@Override
public void setX(double value)
{
x = (int) value;
}
@Override
public double getY()
{
// special infinite case
if (y == java.lang.Integer.MIN_VALUE)
return java.lang.Double.NEGATIVE_INFINITY;
if (y == java.lang.Integer.MAX_VALUE)
return java.lang.Double.POSITIVE_INFINITY;
return y;
}
@Override
public void setY(double value)
{
y = (int) value;
}
@Override
public double getZ()
{
// special infinite case
if (z == java.lang.Integer.MIN_VALUE)
return java.lang.Double.NEGATIVE_INFINITY;
if (z == java.lang.Integer.MAX_VALUE)
return java.lang.Double.POSITIVE_INFINITY;
return z;
}
@Override
public void setZ(double value)
{
z = (int) value;
}
@Override
public double getT()
{
// special infinite case
if (t == java.lang.Integer.MIN_VALUE)
return java.lang.Double.NEGATIVE_INFINITY;
if (t == java.lang.Integer.MAX_VALUE)
return java.lang.Double.POSITIVE_INFINITY;
return t;
}
@Override
public void setT(double value)
{
t = (int) value;
}
@Override
public double getC()
{
// special infinite case
if (c == java.lang.Integer.MIN_VALUE)
return java.lang.Double.NEGATIVE_INFINITY;
if (c == java.lang.Integer.MAX_VALUE)
return java.lang.Double.POSITIVE_INFINITY;
return c;
}
@Override
public void setC(double value)
{
c = (int) value;
}
@Override
public double getSizeX()
{
// special infinite case
if (sizeX == java.lang.Integer.MAX_VALUE)
return java.lang.Double.POSITIVE_INFINITY;
return sizeX;
}
@Override
public void setSizeX(double value)
{
sizeX = (int) value;
}
@Override
public double getSizeY()
{
// special infinite case
if (sizeY == java.lang.Integer.MAX_VALUE)
return java.lang.Double.POSITIVE_INFINITY;
return sizeY;
}
@Override
public void setSizeY(double value)
{
sizeY = (int) value;
}
@Override
public double getSizeZ()
{
// special infinite case
if (sizeZ == java.lang.Integer.MAX_VALUE)
return java.lang.Double.POSITIVE_INFINITY;
return sizeZ;
}
@Override
public void setSizeZ(double value)
{
sizeZ = (int) value;
}
@Override
public double getSizeT()
{
// special infinite case
if (sizeT == java.lang.Integer.MAX_VALUE)
return java.lang.Double.POSITIVE_INFINITY;
return sizeT;
}
@Override
public void setSizeT(double value)
{
sizeT = (int) value;
}
@Override
public double getSizeC()
{
// special infinite case
if (sizeC == java.lang.Integer.MAX_VALUE)
return java.lang.Double.POSITIVE_INFINITY;
return sizeC;
}
@Override
public void setSizeC(double value)
{
sizeC = (int) value;
}
@Override
public Point5D.Integer getPosition()
{
return new Point5D.Integer(x, y, z, t, c);
}
@Override
public Dimension5D.Integer getDimension()
{
return new Dimension5D.Integer(sizeX, sizeY, sizeZ, sizeT, sizeC);
}
@Override
public Rectangle5D.Integer toInteger()
{
return (Integer) clone();
}
@Override
public Rectangle5D createIntersection(Rectangle5D r)
{
final Rectangle5D.Integer result = new Rectangle5D.Integer();
intersect(this, r, result);
return result;
}
@Override
public Rectangle5D createUnion(Rectangle5D r)
{
final Rectangle5D.Integer result = new Rectangle5D.Integer();
union(this, r, result);
return result;
}
@Override
public Rectangle2D toRectangle2D()
{
return new Rectangle(x, y, sizeX, sizeY);
}
@Override
public Rectangle3D toRectangle3D()
{
return new Rectangle3D.Integer(x, y, z, sizeX, sizeY, sizeZ);
}
@Override
public Rectangle4D toRectangle4D()
{
return new Rectangle4D.Integer(x, y, z, t, sizeX, sizeY, sizeZ, sizeT);
}
}
}