public final class Extent extends Object implements Serializable, Comparable<Extent>
When describing a 2D entity, the depth (Z-axis value) is always 1
.
Each size corresponds to the perpendicular Cartesian axes i.e. X, Y and Z axes.
This class is immutable. No operation will modify existing state.
The area (width by height) is pre-calculated to make certain operations like calculating
offsets (which may need to be called frequently) efficient. However, for sizes producing very
large areas that exceed the bounds of an int
these need to be handled separately and
carefully. These cases can be checked for by calling areaXY()
.
Constructor and Description |
---|
Extent(int x,
int y)
Creates with with only X and Y dimensions.
|
Extent(int x,
int y,
int z)
Creates with X and Y and Z dimensions.
|
Modifier and Type | Method and Description |
---|---|
boolean |
anyDimensionIsLargerThan(Extent other)
Returns true if any dimension in this extent is larger than the corresponding dimension in
other extent. |
int |
areaXY()
Size in X multiplied by size in Y.
|
double |
aspectRatioXY()
Derives an aspect-ratio, by dividing the X-dimension by the Y-dimension value.
|
ReadableTuple3i |
asTuple()
Exposes the extent as a tuple.
|
double |
calculateAreaXYAsDouble()
Calculates the area freshly by multiplying the x-size with y-size, as doubles.
|
long |
calculateVolume()
Calculates the volume of the
Extent when considered as a box. |
int |
calculateVolumeAsInt()
Like
calculateVolume() but uses an int to calculate the volume. |
int |
compareTo(Extent other) |
boolean |
contains(BoundingBox box)
Is
box entirely contained within the extent? |
boolean |
contains(int x,
int y,
int z)
Is a point contained within the extent?
|
boolean |
contains(Point2i point)
Is a point of type
Point2i contained within the extent in the XY plane? |
boolean |
contains(Point3d point)
Is a point of type
Point3d contained within the extent? |
boolean |
contains(ReadableTuple3i point)
Is a point of type
ReadableTuple3i contained within the extent? |
boolean |
containsX(double value)
Is a value contained within the extent on the X-axis?
|
boolean |
containsX(int value)
Is a value contained within the extent on the X-axis?
|
boolean |
containsY(double value)
Is a value contained within the extent on the Y-axis?
|
boolean |
containsY(int value)
Is a value contained within the extent on the Y-axis?
|
boolean |
containsZ(double value)
Is a value contained within the extent on the Z-axis?
|
boolean |
containsZ(int value)
Is a value contained within the extent on the Z-axis?
|
static Extent |
createFromTupleDuplicate(ReadableTuple3i tuple)
Creates from a
ReadableTuple3i representing the sizes in each dimension, where the
tuple is not used internally. |
static Extent |
createFromTupleReuse(ReadableTuple3i tuple)
Creates from a
ReadableTuple3i representing the sizes in each dimension, where the
tuple is used internally. |
Point3i |
createMinusOne()
Creates a new
Extent with each dimension decreased by one. |
Extent |
duplicateChangeX(int xToAssign)
Creates a copy of the current
Extent with the value for the X-dimension changed. |
Extent |
duplicateChangeY(int yToAssign)
Creates a copy of the current
Extent with the value for the Y-dimension changed. |
Extent |
duplicateChangeZ(int zToAssign)
Creates a copy of the current
Extent with the value for the Z-dimension changed. |
boolean |
equals(Object obj) |
boolean |
equalsIgnoreZ(Extent other)
Checks for equality with another extent ignoring any differences in the Z dimension.
|
Extent |
flattenZ()
Collapses the Z dimension.
|
Extent |
growBy(int toAdd)
Creates a new
Extent with toAdd size added to each dimension. |
Extent |
growBy(ReadableTuple3i toAdd)
Creates a new
Extent with toAdd size added to each respective
dimension. |
int |
hashCode() |
Extent |
intersectWith(Extent other)
Intersects this extent with another (i.e.
|
boolean |
isEmpty()
Does the extent contain zero voxels?
|
<E extends Exception> |
iterateOverXY(OffsettedScalarTwoDimensionalConsumer<E> pointConsumer)
Calls processor once for each x and y-values in the range.
|
void |
iterateOverXY(PointTwoDimensionalConsumer pointConsumer)
Calls processor once for each x and y-values in the range.
|
<E extends Exception> |
iterateOverXYOffset(CheckedIntConsumer<E> offsetConsumer)
Calls processor once for each x and y-values but only passing an offset.
|
void |
iterateOverXYOffset(OffsettedPointTwoDimensionalConsumer pointConsumer)
Calls processor once for each x and y-values in the range.
|
void |
iterateOverXYWithShift(Point2i shift,
PointTwoDimensionalConsumer pointConsumer)
Calls processor once for each x and y-values in the range, with a shift added.
|
void |
iterateOverYXOffset(OffsettedPointTwoDimensionalConsumer pointConsumer)
Calls processor once for each x and y-values in the range.
|
<E extends Exception> |
iterateOverZ(CheckedIntConsumer<E> indexConsumer)
Calls processor once for each z-value in the range.
|
boolean |
iterateOverZUntil(java.util.function.IntPredicate indexPredicate)
Calls processor once for each z-value in the range unless
indexPredicate returns
false. |
Extent |
minimum(Extent extent)
An extent that contains the minimum of two extents for each dimension respectively.
|
int |
offset(int x,
int y)
Calculates a XY-offset of a point in a buffer whose dimensions are this extent.
|
int |
offset(int x,
int y,
int z)
Calculates a XYZ-offset of a point in a buffer whose dimensions are this extent.
|
int |
offset(Point2i point)
Calculates a XY-offset of a point in a buffer whose dimensions are this extent.
|
int |
offset(ReadableTuple3i point)
Calculates a XYZ-offset of a point in a buffer whose dimensions are this extent.
|
int |
offsetSlice(ReadableTuple3i point)
Calculates a XY-offset of a point in a buffer whose dimensions are this extent.
|
Extent |
scaleXYBy(double scaleFactor,
boolean round)
Scales all dimensions by a scaling-factor.
|
Extent |
scaleXYBy(ScaleFactor scaleFactor,
boolean round)
Scales the X- and Y- dimensions by a scaling-factor.
|
Extent |
shrinkBy(ReadableTuple3i toSubtract)
Creates a new
Extent with toSubtract size subtracted from each
respective dimension. |
java.util.stream.IntStream |
streamOverZ()
Streams over the range of z values.
|
int[] |
toArray()
Derives an three-element array with each dimension in the extent.
|
String |
toString() |
int |
valueByDimension(Axis axis)
The size in the dimension identified by
axis . |
int |
valueByDimension(int dimensionIndex)
The size in the dimension identified by
dimensionIndex . |
int |
x()
The size in the X dimension.
|
int |
y()
The size in the Y dimension.
|
int |
z()
The size in the Z dimension.
|
public Extent(int x, int y)
The z-dimension is assigned a value of 1
.
x
- size along the X-axis dimension.y
- size along the Y-axis dimension.public Extent(int x, int y, int z)
x
- size along the X-axis dimension.y
- size along the Y-axis dimension.z
- size along the Z-axis dimension.public static Extent createFromTupleDuplicate(ReadableTuple3i tuple)
ReadableTuple3i
representing the sizes in each dimension, where the
tuple is not used internally.
The tuple is not used internally, with its values being copied in the constructor.
tuple
- a tuple with the extent size's for each dimension.tuple
internally.public static Extent createFromTupleReuse(ReadableTuple3i tuple)
ReadableTuple3i
representing the sizes in each dimension, where the
tuple is used internally.tuple
- a tuple with the extent size's for each dimension.tuple
internally.public int areaXY()
This may be convenient for calculating offsets and for iterations.
Note that for very large sizes (e.g. the sizes of whole-slide images) an int may be
insufficiently large to capture the area. Consider instead using calculateAreaXYAsDouble()
in these cases.
AnchorFriendlyRuntimeException
- if the area is too large to be expressed as an int
.public double calculateAreaXYAsDouble()
This is useful if the area would otherwise be too large to be represented as an int.
Any previously calculated area is ignored.
public long calculateVolume()
Extent
when considered as a box.
This is is the size in the X, Y and Z dimensions multiplied together.
public int calculateVolumeAsInt()
calculateVolume()
but uses an int
to calculate the volume.
A AnchorFriendlyRuntimeException
is thrown if an overflow occurs.
public boolean isEmpty()
public int x()
public int y()
public int z()
public int valueByDimension(int dimensionIndex)
dimensionIndex
.dimensionIndex
- the dimension to return a size for, as per ReadableTuple3i#valueByDimension(int)
.public int valueByDimension(Axis axis)
axis
.axis
- the dimension to return a size for, as per ReadableTuple3i#valueByDimension(Axis)
.public ReadableTuple3i asTuple()
Importantly, this class is designed to be immutable, so this tuple should be treated as read-only, and never modified.
public boolean equalsIgnoreZ(Extent other)
other
- the extent to check for equality with.obj
ignoring the Z dimension.public final int offset(int x, int y)
x
- the value in the X-dimension for the point.y
- the value in the Y-dimension for the point.public final int offset(int x, int y, int z)
To be computationally efficient, this does not actively check that areaXY
is
non-negative. It is the responsibility of the caller of this function to otherwise check
this, or infer it from context.
x
- the value in the X-dimension for the point.y
- the value in the Y-dimension for the point.z
- the value in the Z-dimension for the point.public final int offset(ReadableTuple3i point)
To be computationally efficient, this does not actively check that areaXY
is
non-negative. It is the responsibility of the caller of this function to otherwise check
this, or infer it from context.
point
- the point to calculate an offset for.public final int offset(Point2i point)
To be computationally efficient, this does not actively check that areaXY
is
non-negative. It is the responsibility of the caller of this function to otherwise check
this, or infer it from context.
point
- the point to calculate an offset for.public final int offsetSlice(ReadableTuple3i point)
To be computationally efficient, this does not actively check that areaXY
is
non-negative. It is the responsibility of the caller of this function to otherwise check
this, or infer it from context.
point
- the point to calculate an offset for.public Extent duplicateChangeX(int xToAssign)
Extent
with the value for the X-dimension changed.xToAssign
- the value to assign for the x-dimension.public Extent duplicateChangeY(int yToAssign)
Extent
with the value for the Y-dimension changed.yToAssign
- the value to assign for the y-dimension.public Extent duplicateChangeZ(int zToAssign)
Extent
with the value for the Z-dimension changed.zToAssign
- the value to assign for the z-dimension.public boolean containsX(double value)
value
- the value to check.public boolean containsY(double value)
value
- the value to check.public boolean containsZ(double value)
value
- the value to check.public boolean containsX(int value)
value
- the value to check.public boolean containsY(int value)
value
- the value to check.public boolean containsZ(int value)
value
- the value to check.public boolean contains(Point2i point)
Point2i
contained within the extent in the XY plane?
The z-dimension is ignored.
point
- the point to check.public boolean contains(Point3d point)
Point3d
contained within the extent?point
- the point to check.public boolean contains(ReadableTuple3i point)
ReadableTuple3i
contained within the extent?point
- the point to check.public boolean contains(int x, int y, int z)
x
- the value of the point on the x-axis.y
- the value of the point on the y-axis.z
- the value of the point on the z-axis.public boolean contains(BoundingBox box)
box
entirely contained within the extent?box
- the bounding-box to check.public Extent scaleXYBy(ScaleFactor scaleFactor, boolean round)
scaleFactor
- the scaling-factor to multiply the respective X and Y dimension values by.round
- if true, each dimension is rounded to the nearest whole number. If false, it is
ceiled upwards to the nearest number.Extent
whose X and Y values are scaled versions of the current values,
and Z value is unchanged.public Extent scaleXYBy(double scaleFactor, boolean round)
scaleFactor
- the scaling-factor to multiply the respective dimension values by.round
- if true, each dimension is rounded to the nearest whole number. If false, it is
ceiled upwards to the nearest number.Extent
whose dimension values are scaled versions of the current
values, with a minimum of 1.public Point3i createMinusOne()
Extent
with each dimension decreased by one.public Extent growBy(int toAdd)
Extent
with toAdd
size added to each dimension.toAdd
- the number of voxels to add to all dimensions.Extent
grown as per above.public Extent growBy(ReadableTuple3i toAdd)
Extent
with toAdd
size added to each respective
dimension.toAdd
- the number of voxels to add to each dimension.Extent
grown as per above.public Extent shrinkBy(ReadableTuple3i toSubtract)
Extent
with toSubtract
size subtracted from each
respective dimension.toSubtract
- the number of voxels to subtract from each dimension.Extent
shrunk as per above.public Extent intersectWith(Extent other)
other
- the other.public Extent flattenZ()
public boolean anyDimensionIsLargerThan(Extent other)
other
extent.other
- extent to compare to.other
).public <E extends Exception> void iterateOverXY(OffsettedScalarTwoDimensionalConsumer<E> pointConsumer) throws E extends Exception
This occurs in ascending order (x-dimension increments first, y-dimension increments second).
E
- a checked-exception that indexConsumer
may throw.pointConsumer
- called for each point.E
- if indexConsumer
throws this exception.E extends Exception
public void iterateOverXY(PointTwoDimensionalConsumer pointConsumer)
This occurs in ascending order (x-dimension increments first, y-dimension increments second).
pointConsumer
- called for each point.public void iterateOverXYWithShift(Point2i shift, PointTwoDimensionalConsumer pointConsumer)
This occurs in ascending order (x-dimension increments first, y-dimension increments second).
shift
- a shift added to each point, so the effective iteration occurs over @extent + shift
.pointConsumer
- called for each point.public <E extends Exception> void iterateOverXYOffset(CheckedIntConsumer<E> offsetConsumer) throws E extends Exception
This occurs in ascending order (x-dimension increments first, y-dimension increments second).
E
- a checked-exception that offsetConsumer
may throw.offsetConsumer
- called for each point with the offset.E
- if indexConsumer
throws this exception.AnchorFriendlyRuntimeException
- if the area is too large to be expressed as an int
.E extends Exception
public void iterateOverXYOffset(OffsettedPointTwoDimensionalConsumer pointConsumer)
This occurs in ascending order (x-dimension increments first, y-dimension increments second).
pointConsumer
- called for each point.public void iterateOverYXOffset(OffsettedPointTwoDimensionalConsumer pointConsumer)
This occurs in ascending order (x-dimension increments first, y-dimension increments second).
pointConsumer
- called for each point.public <E extends Exception> void iterateOverZ(CheckedIntConsumer<E> indexConsumer) throws E extends Exception
This occurs sequentially from 0 (inclusive) to z()
(exclusive).
E
- a checked-exception that indexConsumer
may throwindexConsumer
- called for each index (z-value)E
- if indexConsumer
throws this exceptionE extends Exception
public boolean iterateOverZUntil(java.util.function.IntPredicate indexPredicate)
indexPredicate
returns
false.
This occurs sequentially from 0 (inclusive) to z()
(exclusive).
As soon as the indexPredicate
returns false, the iteration stops.
indexPredicate
- called for each index (z-value)indexPredicate
always returned true for every slice, false otherwise.public java.util.stream.IntStream streamOverZ()
The values range from 0 (inclusive) to z()
(exclusive).
public int[] toArray()
public Extent minimum(Extent extent)
This is an immutable operation.
extent
- the other extent to find a minimum with.public double aspectRatioXY()
Note that the Z-dimension is irrelevant to this calculation.
public int compareTo(Extent other)
compareTo
in interface Comparable<Extent>
Copyright © 2010–2023 Owen Feehan, ETH Zurich, University of Zurich, Hoffmann-La Roche. All rights reserved.