Region in n-dimensional space. More precisely, this class defines a random set of points with integer coordinates in n-dimensional space. Though some kinds of regions are defined in terms of real coordinates, this class is useful for processing only integer points belonging to the region. This class is designed for copying/filling regions in {@link Matrix AlgART matrices} by
- {@link Matrices#copyRegion(ArrayContext,Matrix,Matrix,net.algart.arrays.Matrices.Region,long)},
- {@link Matrices#copyRegion(ArrayContext,Matrix,Matrix,net.algart.arrays.Matrices.Region,long[],Object)}and
- {@link Matrices#fillRegion(ArrayContext,Matrix,net.algart.arrays.Matrices.Region,Object)}
methods, where non-integer coordinates are needless.
This class is abstract and describes the region (set of points) by the only one simple abstract method {@link #contains(long coordinates)}, which returns true if and only if the point with the specified coordinates belongs to the region. It is enough to implement this method to define a new region. In addition, this class always requires to specify {@link #coordRanges() coordinate ranges}: such ranges that coordinates of all region points guaranteedly belong to them.
However, the region, constructed by this way, provides low performance of {@link Matrices#copyRegion Matrices.copyRegion} / {@link Matrices#fillRegion Matrices.fillRegion} methods,because the only way to process it is checking all points separately by {@link #contains(long)} method. Therefore, this class provides the additional method {@link #sectionAtLastCoordinate(long sectionCoordinateValue)}, which builds an intersection of this region with some hyperplane and returns this intersection as one or several regions with less number of dimensions. This method is not abstract (it is implemeneted via {@link #contains(long)} method by default), but an inheritor can offer much faster implementation for most cases — and all inheritors from this package really do it.
An idea of this method is the following. It allows to represent the n-dimensional region (a set of integer points) as a union of its (n−1)-dimensional sections: results of calls of {@link #sectionAtLastCoordinate(long) sectionAtLastCoordinate}for all possible values of its argument sectionCoordinateValue. Then every (n−1)-dimensional section can be similarly represented as a union of its (n−2)-dimensional sections, etc. But for 2-dimensional case most region types (in particular, all inhertiros of this class from this package) can return the required intersection (with a horizontal line) as one or several continuous segments: regions of special type (1-dimensional {@link Matrices.Hyperparallelepiped Hyperparallelepiped}), which can be processes very quickly.
If an inheritor correctly implements {@link #sectionAtLastCoordinate(long) sectionAtLastCoordinate}and if this method does not use {@link #contains(long)} method and the parent (default) implementation {@link #sectionAtLastCoordinate(long) Region.sectionAtLastCoordinate}, then the inheritor is allowed not to implement {@link #contains(long)} method. Instead, it is enough to override {@link #isContainsSupported()} method and return false by it.In this case, {@link #contains(long)} method should throw UnsupportedOperationException.
This class can represent an empty region (containing no points). The number of dimensions of the range is always positive (1, 2, ...).
This package offers the following implementations of the regions:
- {@link Matrices.Hyperparallelepiped}: the simplest possible region (a segment in 1-dimensional case, a rectangle in 2-dimensional case, a parallelepiped in 3-dimensional case);
- {@link Matrices.ConvexHyperpolyhedron}: an intersection of several n-dimensional half-spaces (in other words, a convex hyperpolyhedron);
- {@link Matrices.Simplex}: the simplest kind of n-dimensional hyperpolyhedron — a hyperpolyhedron with n+1 vertices (a segment in 1-dimensional case, a triangle in 2-dimensional case, a tetrahedron in 3-dimensional case);
- {@link Matrices.Polygon2D}: a random 2-dimensional polygon, maybe non-convex and even self-intersecting.
Note that all region types are always restricted by the hyperparallelepiped, defined by the {@link #coordRanges() coordinate ranges}, so a region cannot be infinite.
Also note: this class and its inheritors from this package do not implement own equals and hashCode methods. So, this class does not provide a mechanism for comparing different regions.
Inheritors of this abstract class are usually immutable and always thread-safe: all methods of this class may be freely used while simultaneous accessing the same instance from several threads. All inheritors of this class from this package are immutable.