public abstract class Boundary2DWrapper extends Boundary2DScanner
Abstract wrapper of a boundary scanner:
special variant of Boundary2DScanner
class, that redirects all methods to some
parent scanner and, maybe, performs some additional actions.
All methods of this object and its inheritors call the same methods of the parent scanner
and return their results. In addition, the nextBoundary()
and goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
methods of this class
call reset()
method after calling the method of the parent scanner.
An inheritor may add some other actions into any methods (usually into next()
method).
Extending this class is a convenient way to process scanned boundaries without complication
of the basic scanning loop
(usually based on nextBoundary()
and Boundary2DScanner.scanBoundary(net.algart.arrays.ArrayContext)
calls).
The simplest example is Boundary2DSimpleMeasurer
class, that adds measuring operation
to calling the parent next()
method.
Boundary2DScanner.Side, Boundary2DScanner.Step
Modifier and Type  Field and Description 

protected Boundary2DScanner 
parent
The parent scanner: the methods of this object call the corresponding methods of the parent one.

Modifier  Constructor and Description 

protected 
Boundary2DWrapper(Boundary2DScanner parent)
Creates new instance of this class.

Modifier and Type  Method and Description 

boolean 
boundaryFinished()
Returns true if and only if the current position (
Boundary2DScanner.x() , Boundary2DScanner.y() , Boundary2DScanner.side() )
is identical to the position, set by last call of Boundary2DScanner.nextBoundary() or
Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side) method. 
ConnectivityType 
connectivityType()
Returns the connectivity kind, used by this object.

boolean 
coordinatesChanged()
Returns true if the last call of
Boundary2DScanner.next() method has changed Boundary2DScanner.x() or Boundary2DScanner.y()
coordinate. 
long 
currentIndexInArray()
Returns the index of the current pixel in the
underlying array of the currently
scanned matrix. 
boolean 
get()
Returns the value of the current element of the currently scanned matrix.

void 
goTo(long x,
long y,
Boundary2DScanner.Side side)
Sets the current position in the matrix to the specified coordinates and pixel side.

boolean 
isAllBoundariesScanner()
Returns true if and only if this scanner is an all boundaries scanner.

boolean 
isInitialized()
Returns true if and only if this instance was positioned to some coordinates in the matrix.

boolean 
isMainBoundariesScanner()
Returns true if and only if this scanner is a main boundaries scanner.

boolean 
isMovedAlongBoundary()
Returns true if and only if this scanner is already positioned
(
Boundary2DScanner.isInitialized() returns true) and, in addition, Boundary2DScanner.next() or
Boundary2DScanner.scanBoundary(ArrayContext) methods were called at least once. 
boolean 
isSingleBoundaryScanner()
Returns true if and only if this scanner is a single boundary scanner.

Boundary2DScanner.Step 
lastStep()
Returns information about the movement of the current position, performed by the last call of
Boundary2DScanner.next() method. 
long 
nestingLevel()
Returns the current nesting level of object boundaries:
the number of boundaries (external or internal), inside which the current pixel side
— the segment with the length 1.0, described by
Boundary2DScanner.x() , Boundary2DScanner.y() , Boundary2DScanner.side()
— is located. 
void 
next()
Move the current position to the next segment of the currently scanned object boundary.

boolean 
nextBoundary()
Finds the next vertical segment, belonging to some object boundary,
after the current position, and sets the current position to the found one.

Boundary2DScanner 
parent()
Returns the
parent scanner. 
void 
reset()
This method is automatically called by
nextBoundary() and
goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side) methods
after calling the same methods of the parent scanner. 
Boundary2DScanner.Side 
side()
Returns the current pixel side (or throws IllegalStateException if this scanner
was not
positioned yet ). 
long 
stepCount()
Returns the total number of calls of
Boundary2DScanner.next() method since the last call Boundary2DScanner.nextBoundary() or
Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side) method. 
long 
x()
Returns the current xcoordinate (or throws IllegalStateException if the scanner
was not
positioned yet ). 
long 
y()
Returns the current ycoordinate (or throws IllegalStateException if this scanner
was not
positioned yet ). 
checkInterruption, getAllBoundariesScanner, getMainBoundariesScanner, getSingleBoundaryScanner, goToSamePosition, isInternalBoundary, matrix, scanBoundary, scanBoundary, toString, updateProgress
protected final Boundary2DScanner parent
parent()
protected Boundary2DWrapper(Boundary2DScanner parent)
parent
 the parent scanner, that will be stored in parent
field.java.lang.NullPointerException
 if parent argument is null.public final Boundary2DScanner parent()
parent
scanner.public boolean isSingleBoundaryScanner()
Boundary2DScanner
Boundary2DScanner.getSingleBoundaryScanner(net.algart.arrays.Matrix<? extends net.algart.arrays.BitArray>, net.algart.matrices.scanning.ConnectivityType)
methodBoundary2DWrapper
and this method of its parent scanner
returns true.isSingleBoundaryScanner
in class Boundary2DScanner
public boolean isAllBoundariesScanner()
Boundary2DScanner
Boundary2DScanner.getAllBoundariesScanner(net.algart.arrays.Matrix<? extends net.algart.arrays.BitArray>, net.algart.arrays.Matrix<? extends net.algart.arrays.UpdatablePFixedArray>, net.algart.arrays.Matrix<? extends net.algart.arrays.UpdatablePFixedArray>, net.algart.matrices.scanning.ConnectivityType)
methodBoundary2DWrapper
and this method of its parent scanner
returns true.isAllBoundariesScanner
in class Boundary2DScanner
public boolean isMainBoundariesScanner()
Boundary2DScanner
Boundary2DScanner.getMainBoundariesScanner(net.algart.arrays.Matrix<? extends net.algart.arrays.BitArray>, net.algart.arrays.Matrix<? extends net.algart.arrays.UpdatablePFixedArray>, net.algart.matrices.scanning.ConnectivityType)
methodBoundary2DWrapper
and this method of its parent scanner
returns true.isMainBoundariesScanner
in class Boundary2DScanner
public ConnectivityType connectivityType()
Boundary2DScanner
connectivityType
in class Boundary2DScanner
public boolean isInitialized()
Boundary2DScanner
Boundary2DScanner.nextBoundary()
, goTo
, goToSamePosition
methods were called yet, or true in all other cases.
If this instance is Boundary2DWrapper
, the result of this method for the parent scanner is returned.
If this object is not positioned, most of methods, processing pixels in the current position,
throw IllegalStateException.isInitialized
in class Boundary2DScanner
nextBoundary
or
goTo
method.public boolean isMovedAlongBoundary()
Boundary2DScanner
Boundary2DScanner.isInitialized()
returns true) and, in addition, Boundary2DScanner.next()
or
Boundary2DScanner.scanBoundary(ArrayContext)
methods were called at least once.
This information can be useful before calling Boundary2DScanner.lastStep()
method
(for example, for debugging goals): that method throws IllegalStateException
if and only if this method returns false.
isMovedAlongBoundary
in class Boundary2DScanner
Boundary2DScanner.next()
or Boundary2DScanner.scanBoundary(ArrayContext)
methods
were successfully called after creating this instance.public long x()
Boundary2DScanner
positioned yet
).x
in class Boundary2DScanner
public long y()
Boundary2DScanner
positioned yet
).y
in class Boundary2DScanner
public Boundary2DScanner.Side side()
Boundary2DScanner
positioned yet
).side
in class Boundary2DScanner
public long nestingLevel()
Boundary2DScanner
Boundary2DScanner.x()
, Boundary2DScanner.y()
, Boundary2DScanner.side()
— is located.
(Here we suppose, that if the current pixel side lies at some boundary,
then it lies inside this boundary.)
Just after creating an instance of this class the nesting level is 0.
After the first call of Boundary2DScanner.nextBoundary()
it becomes 1.
After finding the first internal boundary (if it exists) by Boundary2DScanner.nextBoundary()
the nesting level becomes 2.
After each intersection of a boundary while searching for the next boundary
the nesting level is increased by 1 or decreased by 1.
So, odd values of the nesting level correspond to external boundaries
and even values correspond to internal boundaries, excepting the case of a newly created instance
(the only case when it is 0).
Please note: the nesting level is supported only
Boundary2DScanner.getAllBoundariesScanner(Matrix, Matrix, Matrix, ConnectivityType)
method;Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
method was never called;Boundary2DWrapper
, the result of this method for the parent scanner
is returned.If this scanner was created via
Boundary2DScanner.getSingleBoundaryScanner(Matrix, ConnectivityType)
or
Boundary2DScanner.getMainBoundariesScanner(Matrix, Matrix, ConnectivityType)
,
the returned nesting level is always 0.
In all other cases, the result of this method is not specified.
nestingLevel
in class Boundary2DScanner
public long currentIndexInArray()
Boundary2DScanner
underlying array
of the currently
scanned matrix. This method is almost equivalent to
Boundary2DScanner.y()
* Boundary2DScanner.matrix()
.dimX()
+ Boundary2DScanner.x()
positioned yet
:
in the last case it returns 0.currentIndexInArray
in class Boundary2DScanner
public void goTo(long x, long y, Boundary2DScanner.Side side)
Boundary2DScanner
Usually this method is not necessary for scanners, created by
getAllBoundariesScanner
and
getMainBoundariesScanner
methods:
it is enough to use Boundary2DScanner.nextBoundary()
and Boundary2DScanner.next()
(or Boundary2DScanner.scanBoundary(ArrayContext)
)
methods to visit all object boundaries at the matrix.
But this method may be helpful if you need to scan a single boundary (for example,
that was found by another scanner).
goTo
in class Boundary2DScanner
x
 new current xcoordinate.y
 new current ycoordinate.side
 new current pixel side.public boolean get()
Boundary2DScanner
Boundary2DScanner.matrix()
.array()
.getBit
(Boundary2DScanner.currentIndexInArray()
)positioned yet
;
in this case, it returns the value of (0,0) matrix element
(i.e. Boundary2DScanner.matrix()
.array()
.getBit(0)
get
in class Boundary2DScanner
public boolean nextBoundary()
Boundary2DScanner
More precisely, it finds some "next" position after the current position,
in the natural order,
where the side is X_MINUS
or X_PLUS
and one from two matrix elements on the left and on the right from the specified segment (pixel side) is 1,
but another from these two elements is 0 or lies outside the matrix.
If this scanner was not positioned yet
, this method finds the first
such position.
The precise sense of the "next" term above depends on the kind of the boundary scanner.
Boundary2DScanner.getSingleBoundaryScanner(Matrix, ConnectivityType)
method, it is just the nearest possible position
(in the natural order).Boundary2DScanner.getAllBoundariesScanner(Matrix, Matrix, Matrix, ConnectivityType)
method, it is the nearest boundary segment that was not visited yet by Boundary2DScanner.next()
method.Boundary2DScanner.getMainBoundariesScanner(Matrix, Matrix, ConnectivityType)
method, it is the nearest boundary segment that was not visited yet by Boundary2DScanner.next()
method
and that does not lie inside some already scanned boundary.In addition to searching for the next position, this method may do something else:
see comments to methods getSingleBoundaryScanner
,
getAllBoundariesScanner
,
getMainBoundariesScanner
.
This method returns true if it can find the necessary "next" position, or false if there is no required position, i.e. if the matrix scanning is finished. In the second case, the current position is not changed.
Note that if this scanner was not positioned yet
, it becomes positioned
if this method returns true, but stays not positioned if it returns false.
nextBoundary
in class Boundary2DScanner
public void next()
Boundary2DScanner
If the current position does not correspond to an object boundary, the position will be changed to some unknown position near the current one (precise behavior is not specified).
In addition to switching to the next position, this method can do something else:
see comments to methods
getSingleBoundaryScanner
,
getAllBoundariesScanner
,
getMainBoundariesScanner
,
and comments to classes Boundary2DSimpleMeasurer
, Boundary2DProjectionMeasurer
.
next
in class Boundary2DScanner
public Boundary2DScanner.Step lastStep()
Boundary2DScanner
Boundary2DScanner.next()
method.
If that method was never called (in particular, as a part of Boundary2DScanner.scanBoundary(ArrayContext)
),
this method throws IllegalStateException. You can check this situation with help of
Boundary2DScanner.isMovedAlongBoundary()
method.
lastStep
in class Boundary2DScanner
Boundary2DScanner.next()
method.Boundary2DScanner.isMovedAlongBoundary()
public boolean coordinatesChanged()
Boundary2DScanner
Boundary2DScanner.next()
method has changed Boundary2DScanner.x()
or Boundary2DScanner.y()
coordinate. Returns false if the last call of Boundary2DScanner.next()
method has changed only the
current pixel side
.
Equivalent to
!Boundary2DScanner.lastStep()
.isSamePixel()
,
but works little faster.
coordinatesChanged
in class Boundary2DScanner
Boundary2DScanner.next()
method has changed current pixel coordinates.public boolean boundaryFinished()
Boundary2DScanner
Boundary2DScanner.x()
, Boundary2DScanner.y()
, Boundary2DScanner.side()
)
is identical to the position, set by last call of Boundary2DScanner.nextBoundary()
or
Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
method.
Usually it means that the current boundary has been successfully scanned.boundaryFinished
in class Boundary2DScanner
public long stepCount()
Boundary2DScanner
Boundary2DScanner.next()
method since the last call Boundary2DScanner.nextBoundary()
or
Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
method.stepCount
in class Boundary2DScanner
Boundary2DScanner.next()
method and reset to zero while object creation
and while every call of Boundary2DScanner.nextBoundary()
or Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
method.public void reset()
nextBoundary()
and
goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
methods
after calling the same methods of the parent scanner.
The default implementation does nothing.
This method can be overridden, for example, to initialize analysis of the next boundary
in the inheritor.