net.algart.math.patterns.UniformGridPattern Maven / Gradle / Ivy
Show all versions of algart Show documentation
/*
* The MIT License (MIT)
*
* Copyright (c) 2007-2024 Daniel Alievsky, AlgART Laboratory (http://algart.net)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.algart.math.patterns;
import net.algart.math.IPoint;
import net.algart.math.IRange;
import net.algart.math.IRectangularArea;
import net.algart.math.Point;
import java.util.Collection;
import java.util.Set;
/**
* Interface, used by {@link Pattern} implementations to indicate that
* they are uniform-grid patterns, i.e.
* subsets of the set of all mesh nodes of some uniform grids.
* See also the section "Uniform-grid patterns" in the comments to {@link Pattern} interface.
*
* More precisely, a pattern, implementing this interface, is some set of N points (N>0)
* x(k) = (x0(k),
* x1(k), ...,
* xn−1(k))
* (k=0,1,...,N−1, n={@link #dimCount() dimCount()}),
* produced by the following formulas:
*
*
* x0(k) =
* o0 + i0(k)d0
* x1(k) =
* o1 + i1(k)d1
* . . .
* xn−1(k) =
* on−1
* + in−1(k)dn−1
*
*
* where oj and dj
* are some constants (dj>0)
* and ij(k) are any integer numbers.
* The point
* o=(o0,o1,...,on−1),
* named origin of the grid, and the vector
* d=(d0,d1,...,dn−1),
* named steps of the grid, are specified while creating the pattern.
* Moreover, these parameters about (o and d)
* are stored inside the object and can be quickly read at any time
* by {@link #originOfGrid()} and {@link #stepsOfGrid()} methods
* — this condition is a requirement for all implementations of this interface.
*
* The numbers ij(k) are called grid indexes
* of the points of the pattern (or, briefly, grid indexes of the pattern).
* The integer points
* i(k) = (i0(k),
* i1(k), ...,
* in−1(k))
* (k=0,1,...,N−1)
* form an integer pattern (see the section "Integer patterns" in the comments to {@link Pattern} interface),
* which is called grid index pattern and can be got at any time by
* {@link #gridIndexPattern()} method. If the number of points is not extremely large, the grid indexes
* can be also retrieved directly as Java set of i(k) points
* by {@link #gridIndexes()} method.
*
* Warning: not only patterns, implementing this interface, are actually such sets of points.
* Moreover, many patterns, created by this package, are really uniform grid
* (all their points really belong to set of mesh points of some uniform grid),
* but they do not implement this interface and are not considered to be "uniform-grid".
* The typical examples are Minkowski sums, created by
* {@link Patterns#newMinkowskiSum(Collection)} method,
* and unions, created by {@link Patterns#newUnion(Collection)} method.
* It is obvious that a Minkowski sum or a union of several uniform-grid patterns, having
* zero origin o=(0,0,...,0) and the same steps d, are also uniform-grid patterns
* with the same origin and steps. However, it is very probably that the objects, returned by
* {@link Patterns#newMinkowskiSum(Collection)} and {@link Patterns#newUnion(Collection)} methods,
* will not implement {@link UniformGridPattern} interface even in this "good" case.
*
* Grid index restrictions
*
* There are the following guarantees for grid indexes ij(k)
* of any uniform-grid pattern:
*
*
* - if p=(i0,i1,...,in−1) is
* the grid index of some point of the pattern, then
* −{@link #MAX_COORDINATE}≤ij≤{@link #MAX_COORDINATE}
* for all j;
* - if p=(i01,i11,...,in−11) and
* q=(i02,i12,...,in−12)
* are the grid indexes of some two points of the pattern, then
* |ij1−ij2|≤{@link
* #MAX_COORDINATE} for all j.
*
*
* Each implementation of this interface must fulfil both restriction.
* Any attempt to create a uniform-grid pattern, the grid indexes of which do not satisfy these restrictions,
* leads to {@link TooLargePatternCoordinatesException}.
*
* These restrictions are guaranteed together with the coordinate restrictions,
* described in the section "Coordinate restrictions" in the comments to {@link Pattern} interface.
* These restrictions provide a guarantee that the method {@link #gridIndexPattern()} always
* works successfully and creates a correct integer pattern.
*
* @author Daniel Alievsky
*/
public interface UniformGridPattern extends Pattern {
/**
* Returns the grid origin o of this pattern.
* See the {@link UniformGridPattern comments to this interface} for more details.
*
* There is a guarantee, that this method always works very quickly
* (O({@link #dimCount() dimCount()}) operations) and without exceptions.
*
* @return the origin o of the uniform grid of this pattern.
*/
Point originOfGrid();
/**
* Returns the array of grid steps d of this pattern.
* The length of the returned array is equal to {@link #dimCount() dimCount()},
* and the element #j contains the grid step dj along the coordinate #j.
* See the {@link UniformGridPattern comments to this interface} for more details.
*
*
The returned array is a clone of the internal array of the steps, stored in this object.
* The returned array is never empty (its length cannot be zero).
* The elements of the returned array are always positive (<0.0
).
*
*
There is a guarantee, that this method always works very quickly
* (O({@link #dimCount() dimCount()}) operations) and without exceptions.
*
* @return an array containing all grid steps of this pattern.
*/
double[] stepsOfGrid();
/**
* Returns the grid step dj along the coordinate #j of this pattern
* along the coordinate #j=coordIndex
.
* Equivalent to {@link #stepsOfGrid()}[coordIndex]
, but works faster.
*
*
There is a guarantee, that this method always works very quickly
* (maximally O({@link #dimCount() dimCount()}) operations) and without exceptions.
*
* @return the grid step of this pattern along the specified coordinate axis.
* @throws IndexOutOfBoundsException if coordIndex<0
or
* coordIndex>={@link #dimCount() dimCount()}
.
*/
double stepOfGrid(int coordIndex);
/**
* Indicates whether the other uniform-grid pattern has the same grid steps.
* In other words, returns true
if and only if
* both patterns have the same dimension count ({@link #dimCount() dimCount()})
* and the corresponding grid steps {@link #stepOfGrid(int) stepOfGrid((k)} are equal for every k
.
*
*
Note: this method does not compare the origin of grid.
*
*
Equality of grid steps is important, for example, while calculation of a Minkowski sum
* of this and another patterns by {@link #minkowskiAdd(Pattern)} method.
* If two uniform-grid patterns have identical grid steps, then a Minkowski sum of them
* can be also represented by uniform-grid pattern (with same grid steps).
* In another case, it is usually impossible — the Minkowski sum, returned by
* {@link #minkowskiAdd(Pattern)}, will not implement {@link UniformGridPattern}.
*
* @param pattern another uniform-grid pattern,
* the grid steps of which should be compared with grid steps of this one.
* @return true
if the specified pattern has the same steps of grid.
*/
boolean stepsOfGridEqual(UniformGridPattern pattern);
/**
* Returns a set of all grid indexes ij of this pattern.
* Namely, the elements of the returned set contain grid indexes
* i(k) = (i0(k),
* i1(k), ...,
* in−1(k))
* of all points x(k) = (x0(k),
* x1(k), ...,
* xn−1(k))
* of this pattern:
*
* x0(k) =
* o0 + i0(k)d0
* x1(k) =
* o1 + i1(k)d1
* . . .
* xn−1(k) =
* on−1
* + in−1(k)dn−1
*
*
* The result of this method is immutable (Collections.unmodifiableSet
).
* Moreover, the result is always the same for different calls of this method for the same instance —
* there are no ways to change it, in particular, via any custom methods of the implementation class
* (it is a conclusion from the common requirement, that all implementations of {@link Pattern} interface must be
* immutable).
*
*
The returned set is always non-empty,
* and the number of its elements is always equal to {@link #pointCount()}.
*
*
Warning! This method can work slowly for some forms of large patterns.
* In these cases, this method can also throw {@link TooManyPointsInPatternError}
* or OutOfMemoryError
.
* This method surely fails (throws one of these exception), if the total number of points
* {@link #pointCount()}>Integer.MAX_VALUE
, because Java Set
object
* cannot contain more than Integer.MAX_VALUE
elements.
*
*
For example, implementations of the {@link RectangularPattern rectangular patterns}
* allow to successfully define a very large 3D parallelepiped
* n x n x n.
* Fur such pattern, this method will require a lot of memory
* for n=1000 and will fail (probably with {@link TooManyPointsInPatternError})
* for n=2000 (20003>Integer.MAX_VALUE
).
*
*
There is a guarantee, that if this object implements {@link DirectPointSetPattern} interface,
* then this method requires not greater than O(N) operations and memory
* (N={@link #pointCount() pointCount()})
* and never throws {@link TooManyPointsInPatternError}.
*
*
Note: if you do not really need to get a Java collection of all grid indexes,
* you can use {@link #gridIndexPattern()} method, which returns the same result in a form
* of another (integer) pattern. That method, unlike this one, never spends extreme amount of memory
* and time and has no risk to fail with {@link TooManyPointsInPatternError} / OutOfMemoryError
.
*
* @return all grid indexes of this pattern.
* @throws TooManyPointsInPatternError if the number of points is greater than Integer.MAX_VALUE
or,
* in some rare situations, is near this limit
* (OutOfMemoryError
can be also thrown instead of this exception).
* @see #gridIndexPattern()
*/
Set gridIndexes();
/**
* Returns the minimal and maximal grid index ij
* among all points of this pattern
* for the specified coordinate index j==coordIndex
.
* The minimal grid index will be r.{@link net.algart.math.IRange#min() min()}
,
* the maximal grid index will be r.{@link net.algart.math.IRange#max() max()}
,
* where r
is the result of this method.
* See the {@link UniformGridPattern comments to this interface} for more details.
*
* There is a guarantee, that if this object implements {@link RectangularPattern} interface,
* then this method works very quickly (O(1) operations) and without exceptions.
*
*
Moreover, all patterns, implemented in this package, have very quick implementations of this method
* (O(1) operations). Also, the implementations of this method in this package never throw exceptions.
*
*
It is theoretically possible, that in custom implementations of this interface
* (outside this package) this method will work slowly, up to O(N) operations,
* N is the number of points in this pattern.
* However, even in such implementations this method must not lead to
* {@link TooManyPointsInPatternError} / OutOfMemoryError
, like {@link #points()} method.
*
* @param coordIndex the index j of the coordinate (0 for x, 1 for y, 2 for z, etc.).
* @return the range from minimal to maximal grid index ij.
* @throws IndexOutOfBoundsException if coordIndex<0
or
* coordIndex>={@link #dimCount() dimCount()}
.
* @see #gridIndexMin()
* @see #gridIndexMax()
* @see #gridIndexArea()
*/
IRange gridIndexRange(int coordIndex);
/**
* Returns the minimal and maximal grid index ij
* among all points of this pattern
* for all coordinate axes j
* If a
is the result of this method,
* then a.{@link IRectangularArea#coordCount() coordCount()}=={@link #dimCount() dimCount()}
* and a.{@link IRectangularArea#range(int) range}(k)
* is equal to {@link #gridIndexRange(int) gridIndexRange}(k)
for all k
.
*
*
All, said in the comments to {@link #gridIndexRange(int)} method
* about the speed and impossibility of {@link TooManyPointsInPatternError} / OutOfMemoryError
,
* is also true for this method.
*
* @return the ranges from minimal to maximal grid index for all space dimensions.
*/
IRectangularArea gridIndexArea();
/**
* Returns the point, each coordinate #j of which
* is equal to the minimal corresponding grid index ij
* among all points of this pattern.
* Equivalent to {@link #gridIndexArea()}.{@link IRectangularArea#min() min()}
.
*
*
All, said in the comments to {@link #gridIndexRange(int)} method
* about the speed and impossibility of {@link TooManyPointsInPatternError} / OutOfMemoryError
,
* is also true for this method.
*
* @return minimal grid index for all space dimensions as a point.
*/
IPoint gridIndexMin();
/**
* Returns the point, each coordinate #j of which
* is equal to the maximal corresponding grid index ij
* among all points of this pattern.
* Equivalent to {@link #gridIndexArea()}.{@link IRectangularArea#max() max()}
.
*
*
All, said in the comments to {@link #gridIndexRange(int)} method
* about the speed and impossibility of {@link TooManyPointsInPatternError} / OutOfMemoryError
,
* is also true for this method.
*
* @return maximal grid index for all space dimensions as a point.
*/
IPoint gridIndexMax();
/**
* Returns true
if and only if this uniform-grid pattern is an ordinary integer pattern,
* i.e. if the grid origin o is the origin of coordinates (0,0,...,0)
* and all grid steps dj are 1.0.
* Equivalent to
* {@link #originOfGrid()}.{@link Point#isOrigin() isOrigin()}
* && {@link #gridIndexRange(int) gridIndexRange}(0)==1.0
* && {@link #gridIndexRange(int) gridIndexRange}(1)==1.0
* && ...
* Ordinary integer patterns are a simplest form of integer pattern:
* see comments to {@link Pattern} interface, section "Uniform-grid patterns".
*
*
There is a guarantee, that this method always works very quickly
* (maximally O({@link #dimCount() dimCount()}) operations) and without exceptions.
*
* @return whether the grid origin o=(0,0,...,0) and also all grid steps dj=1.0.
*/
boolean isOrdinary();
/**
* Returns true
if this pattern is n-dimensional rectangular parallelepiped.
* (For 2D patterns it means a rectangle, for 1D pattern it means an interval.)
* In other words, it returns true
if this pattern is the set of all points
* (o0+i0d0,
* o1+i1d1, ...,
* on−1+in−1dn−1),
* where oj are coordinates of the {@link #originOfGrid() origin of the grid},
* dj are {@link #stepsOfGrid() steps of the grid}
* and ij are all integers in the ranges
* {@link #gridIndexRange(int) gridIndexRange(j)}.{@link net.algart.math.IRange#min()
* min()}<=ij<={@link #gridIndexRange(int)
* gridIndexRange(j)}.{@link net.algart.math.IRange#max()
* max()}, j=0,1,...,{@link #dimCount() dimCount()}−1.
*
*
Note that this condition is the same as in the definition of rectangular patterns, represented by
* {@link RectangularPattern} interface. Really, if the object implements {@link RectangularPattern},
* this method always returns true
. However, this method tries to investigate
* the actual point set for other types of patterns.
*
*
There are no strict guarantees that this method always returns true
if the pattern is
* n-dimensional rectangular parallelepiped. (In some complex situations, such analysis can
* be too difficult.) But there is this guarantee for all uniform-grid patterns, created by this package.
* And, of course, there is the reverse guarantee: if this method returns true
, the pattern is
* really a rectangular parallelepiped.
*
* You may be also sure that this method always works quickly enough and without exceptions.
* In the worst case, it can require O(N) operations,
* N={@link #pointCount() pointCount()},
* but usually it works much more quickly.
* (So, if you implement this method yourself and there is a risk, that calculations
* can lead to {@link TooManyPointsInPatternError}, OutOfMemory
or another exception due to
* extremely large number of points, you must return false
instead of
* throwing an exception. Please compare this with {@link #pointCount()} and {@link #points()} methods,
* which do not provide such guarantees and may lead to an exception.)
*
* @return true
if this pattern is n-dimensional rectangular parallelepiped.
*/
boolean isActuallyRectangular();
/**
* Returns an {@link #isOrdinary() ordinary} integer pattern with the same set of grid indexes
* ij(k) as this pattern.
* In other words, if this pattern is a set of points
*
*
* x0(k) =
* o0 + i0(k)d0
* x1(k) =
* o1 + i1(k)d1
* . . .
* xn−1(k) =
* on−1
* + in−1(k)dn−1
*
*
* (k=0,1,...,N−1, n={@link #dimCount() dimCount()}), then the returned pattern
* consists of points
*
*
* y0(k) = (double)
i0(k)
* y1(k) = (double)
i1(k)
* . . .
* yn−1(k) =
* (double)
in−1(k)
*
*
* Note: here is a guarantee, that all grid indexes ij will be strictly
* represented by double
type.
* Moreover, there is a guarantee that the returned pattern is correct, i.e. will be successfully built
* without a risk of {@link TooLargePatternCoordinatesException}.
* See the comments to {@link Pattern#MAX_COORDINATE}
* and the section "Grid index restrictions" in the comments to {@link UniformGridPattern} interface.
*
*
You can use this method to get a set of all grid indexes (integer values):
* it is enough to call {@link #roundedPoints()} in the returned pattern.
* The results will be the same as the result of {@link #gridIndexes()} method.
*
*
The returned pattern always implements {@link DirectPointSetPattern}
* if this pattern implements {@link DirectPointSetPattern}.
*
*
The returned pattern always implements {@link RectangularPattern}
* if this pattern implements {@link RectangularPattern}.
*
*
There is a guarantee, that this method does not try to allocate much more memory,
* that it is required for storing this pattern itself, and that it
* never throws {@link TooManyPointsInPatternError}.
*
*
This method works quickly enough: in the worst case,
* it can require O(N) operations (N={@link #pointCount() pointCount()}).
*
*
* @return an ordinary integer pattern, consisting of all grid indexes of this pattern (represented
* by double
values).
* @see #gridIndexes()
*/
UniformGridPattern gridIndexPattern();
/**
* Returns another uniform-grid pattern, identical to this one with the only difference, that
* the grid index
* i(k) = (i0(k),
* i1(k), ...,
* in−1(k))
* for each point #k of the result is shifted by the argument of this method via the call
* i(k).{@link IPoint#add(IPoint) add}(shift)
.
*
* In other words, if this pattern is a set of points
*
*
* x0(k) =
* o0 + i0(k)d0
* x1(k) =
* o1 + i1(k)d1
* . . .
* xn−1(k) =
* on−1
* + in−1(k)dn−1
*
*
* (k=0,1,...,N−1, n={@link #dimCount() dimCount()}), then the returned pattern
* has the same {@link #originOfGrid() grid oridin}, the same {@link #stepsOfGrid() grid steps}
* and consists of points
*
*
* y0(k) =
* o0 + (i0(k)+shift.{@link IPoint#coord(int)
* coord}(0)
)*d0
* y1(k) =
* o1 + (i1(k)+shift.{@link IPoint#coord(int)
* coord}(1)
)*d1
* . . .
* yn−1(k) =
* on−1
* + (in−1(k)+shift.{@link IPoint#coord(int)
* coord}(n−1)
)*dn−1
*
*
* The returned pattern always implements {@link DirectPointSetPattern}
* if this pattern implements {@link DirectPointSetPattern}
*
*
The returned pattern always implements {@link RectangularPattern}
* if this pattern implements {@link RectangularPattern}.
*
*
There is a guarantee, that this method does not try to allocate much more memory,
* that it is required for storing this pattern itself, and that it
* never throws {@link TooManyPointsInPatternError}.
* For comparison, an attempt to do the same operation via getting all grid indexes via
* {@link #gridIndexes()} call, correcting them and forming a new pattern via
* {@link Patterns#newUniformGridPattern(Point, double[], java.util.Collection)}
* will lead to {@link TooManyPointsInPatternError} / OutOfMemoryError
for some forms of large patterns.
*
*
Warning: this method can fail with {@link TooLargePatternCoordinatesException}, if some of new points
* violate restrictions, described in the comments to {@link Pattern} interface,
* section "Coordinate restrictions", and in the comments to {@link UniformGridPattern} interface,
* section "Coordinate restrictions" (for example, due to very large shift).
*
*
Note: the similar results can be got with help of {@link #shift(Point)} method
* with a corresponding floating-point shift. However, this method
* guarantees that the returned pattern has the same origin of the grid, but corrected grid indexes.
* Unlike this, a good implementation of {@link #shift(Point)} method just corrects the grid origin,
* but does not change grid indexes. This difference is important, if you are going to get
* the grid indexes from the shifted pattern via {@link #gridIndexPattern()} or {@link #gridIndexes()} method.
*
* @param shift the shift of the grid indexes.
* @return the shifted pattern.
* @throws NullPointerException if the argument is {@code null}.
* @throws IllegalArgumentException if point.{@link Point#coordCount() coordCount()}!={@link #dimCount()}
.
* @throws TooLargePatternCoordinatesException if the set of shifted points does not fulfil the restrictions,
* described in the comments to {@link Pattern} interface,
* section "Coordinate restrictions", and in the comments
* to {@link UniformGridPattern} interface,
* section "Coordinate restrictions".
*/
UniformGridPattern shiftGridIndexes(IPoint shift);
/*Repeat()
min(?!(us|g)) ==> max;;
less ==> greater;;
lower ==> upper;;
lowerSurface ==> upperSurface;;
backward ==> forward;;
leftward ==> rightward;;
decreasing ==> increasing;;
−d ==> +d;;
minBound ==> maxBound;;
\*[ \t]+(\*) ==> $1 */
/**
* Returns the lower boundary of this pattern along the given axis:
* a pattern consisting of all such points A of this pattern,
* that the neighbour point B,
* generated by the backward shift of point A along the coordinate #j=coordIndex
* by the corresponding grid step dj={@link #stepOfGrid(int)
* stepOfGrid(coordIndex)}, does not belong to this pattern.
* The number of dimensions in the resulting pattern ({@link #dimCount() dimCount()}) is the same as in this one.
*
*
In other words, the point
* A = (x0, x1, ...,
* xj, ..., xn−1)
* belongs to the returned pattern if and only if it belongs to this pattern and the point
* B = (x0, x1, ...,
* xj−dj, ..., xn−1)
* (corresponding to decreasing the grid index ij by 1)
* does not belong to this pattern.
*
*
Please compare with {@link #minBound(int)} method. This method can return a pattern
* containing more points than {@link #minBound(int)}, in particular, if this pattern contains some "holes".
*
* The returned pattern always implements {@link DirectPointSetPattern}
* if this pattern implements {@link DirectPointSetPattern}
*
*
The returned pattern always implements {@link RectangularPattern}
* if this pattern implements {@link RectangularPattern}.
*
*
Note: if this object is not {@link DirectPointSetPattern}
* and is not {@link RectangularPattern}, this method can work slowly for some large patterns:
* the required time can be O(N), where N is the number of points.
* In these cases, this method can also throw {@link TooManyPointsInPatternError}
* or OutOfMemoryError
. The situation is like in {@link #points()} and {@link #roundedPoints()} method.
* However, this situation is possible only in custom implementation of this interface —
* all implementations, provided by this package, implement either {@link DirectPointSetPattern}
* or {@link RectangularPattern} interface.
*
*
There is a guarantee, that if this object implements {@link DirectPointSetPattern} interface,
* then this method requires not greater than O(N) memory
* (N={@link #pointCount() pointCount()})
* and never throws {@link TooManyPointsInPatternError}.
*
*
There is a guarantee, that if this object implements {@link RectangularPattern} interface,
* then this method works quickly (O(1) operations) and without exceptions.
*
* @param coordIndex the index of the coordinate (0 for x, 1 for y, 2 for z, etc.)
* @return the "lower boundary" of this pattern: new pattern consisting of all points of this pattern,
* which have no leftward neighbour along the given coordinate.
* @throws IndexOutOfBoundsException if coordIndex<0
or
* coordIndex>={@link #dimCount() dimCount()}
.
* @throws TooManyPointsInPatternError (impossible for implementations, provided by this package)
* if this pattern is not {@link DirectPointSetPattern} and
* not {@link RectangularPattern} and if, at the same time, the number
* of points is greater than Integer.MAX_VALUE
or,
* in some rare situations, is near this limit
* (OutOfMemoryError
can be also thrown instead of this exception).
*/
UniformGridPattern lowerSurface(int coordIndex);
/*Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! */
/**
* Returns the upper boundary of this pattern along the given axis:
* a pattern consisting of all such points A of this pattern,
* that the neighbour point B,
* generated by the forward shift of point A along the coordinate #j=coordIndex
* by the corresponding grid step dj={@link #stepOfGrid(int)
* stepOfGrid(coordIndex)}, does not belong to this pattern.
* The number of dimensions in the resulting pattern ({@link #dimCount() dimCount()}) is the same as in this one.
*
*
In other words, the point
* A = (x0, x1, ...,
* xj, ..., xn−1)
* belongs to the returned pattern if and only if it belongs to this pattern and the point
* B = (x0, x1, ...,
* xj+dj, ..., xn−1)
* (corresponding to increasing the grid index ij by 1)
* does not belong to this pattern.
*
*
Please compare with {@link #maxBound(int)} method. This method can return a pattern
* containing more points than {@link #maxBound(int)}, in particular, if this pattern contains some "holes".
*
* The returned pattern always implements {@link DirectPointSetPattern}
* if this pattern implements {@link DirectPointSetPattern}
*
*
The returned pattern always implements {@link RectangularPattern}
* if this pattern implements {@link RectangularPattern}.
*
*
Note: if this object is not {@link DirectPointSetPattern}
* and is not {@link RectangularPattern}, this method can work slowly for some large patterns:
* the required time can be O(N), where N is the number of points.
* In these cases, this method can also throw {@link TooManyPointsInPatternError}
* or OutOfMemoryError
. The situation is like in {@link #points()} and {@link #roundedPoints()} method.
* However, this situation is possible only in custom implementation of this interface —
* all implementations, provided by this package, implement either {@link DirectPointSetPattern}
* or {@link RectangularPattern} interface.
*
*
There is a guarantee, that if this object implements {@link DirectPointSetPattern} interface,
* then this method requires not greater than O(N) memory
* (N={@link #pointCount() pointCount()})
* and never throws {@link TooManyPointsInPatternError}.
*
*
There is a guarantee, that if this object implements {@link RectangularPattern} interface,
* then this method works quickly (O(1) operations) and without exceptions.
*
* @param coordIndex the index of the coordinate (0 for x, 1 for y, 2 for z, etc.)
* @return the "upper boundary" of this pattern: new pattern consisting of all points of this pattern,
* which have no rightward neighbour along the given coordinate.
* @throws IndexOutOfBoundsException if coordIndex<0
or
* coordIndex>={@link #dimCount() dimCount()}
.
* @throws TooManyPointsInPatternError (impossible for implementations, provided by this package)
* if this pattern is not {@link DirectPointSetPattern} and
* not {@link RectangularPattern} and if, at the same time, the number
* of points is greater than Integer.MAX_VALUE
or,
* in some rare situations, is near this limit
* (OutOfMemoryError
can be also thrown instead of this exception).
*/
UniformGridPattern upperSurface(int coordIndex);
/*Repeat.AutoGeneratedEnd*/
/**
* Returns the set-theoretical union of all patterns, returned by {@link #lowerSurface(int)}
* {@link #upperSurface(int)} methods for all coordinates.
* In other words, the returned pattern contains full "boundary" of this pattern.
* The number of dimensions in the resulting pattern ({@link #dimCount() dimCount()}) is the same as in this one.
*
*
Note: if this object is not {@link DirectPointSetPattern}
* and is not {@link RectangularPattern}, this method can work slowly for some large patterns:
* the required time can be O(N), where N is the number of points.
* In these cases, this method can also throw {@link TooManyPointsInPatternError}
* or OutOfMemoryError
. The situation is like in {@link #points()} and {@link #roundedPoints()} method.
* However, this situation is possible only in custom implementation of this interface —
* all implementations, provided by this package, implement either {@link DirectPointSetPattern}
* or {@link RectangularPattern} interface.
*
* @return the "boundary" of this pattern: new pattern consisting of all points of this pattern,
* which have no leftward or rightward neighbour along at least one coordinate.
* @throws TooManyPointsInPatternError (impossible for implementations, provided by this package)
* if this pattern is not {@link DirectPointSetPattern} and
* not {@link RectangularPattern} and if, at the same time, the number
* of points is greater than Integer.MAX_VALUE
or,
* in some rare situations, is near this limit
* (OutOfMemoryError
* can be also thrown instead of this exception).
*/
Pattern surface();
UniformGridPattern shift(Point shift);
UniformGridPattern symmetric();
UniformGridPattern multiply(double multiplier);
UniformGridPattern scale(double... multipliers);
UniformGridPattern projectionAlongAxis(int coordIndex);
UniformGridPattern minBound(int coordIndex);
UniformGridPattern maxBound(int coordIndex);
UniformGridPattern carcass();
}