Class Boundary2DWrapper
- Direct Known Subclasses:
Boundary2DProjectionMeasurer
,Boundary2DSimpleMeasurer
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 resetCounters()
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.
- Author:
- Daniel Alievsky
-
Nested Class Summary
Nested classes/interfaces inherited from class net.algart.matrices.scanning.Boundary2DScanner
Boundary2DScanner.Side, Boundary2DScanner.Step
-
Field Summary
Modifier and TypeFieldDescriptionprotected final Boundary2DScanner
The parent scanner: the methods of this object call the corresponding methods of the parent one. -
Constructor Summary
ModifierConstructorDescriptionprotected
Boundary2DWrapper
(Boundary2DScanner parent) Creates new instance of this class. -
Method Summary
Modifier and TypeMethodDescriptionboolean
Returns true if and only if thecurrent pixel side
lies at the boundary of thescanned matrix
.boolean
Returns true if and only if the current position (Boundary2DScanner.x()
,Boundary2DScanner.y()
,Boundary2DScanner.side()
) is identical to the position, set by last call ofBoundary2DScanner.nextBoundary()
orBoundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
method.Returns the connectivity kind, used by this object.boolean
Returns true if the last call ofBoundary2DScanner.next()
method has changedBoundary2DScanner.x()
orBoundary2DScanner.y()
coordinate.long
Returns the index of the current pixel in theunderlying array
of the currently scanned matrix.long
Returns the number of calls ofBoundary2DScanner.next()
method since the last call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
method, corresponding todiagonal steps
.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
Returns true if and only if this scanner is an all boundaries scanner.boolean
Returns true if and only if this instance was positioned to some coordinates in the matrix.boolean
Returns true if and only if this scanner is a main boundaries scanner.boolean
Returns true if and only if this scanner is already positioned (Boundary2DScanner.isInitialized()
returns true) and, in addition,Boundary2DScanner.next()
orBoundary2DScanner.scanBoundary(ArrayContext)
methods were called at least once.boolean
Returns true if and only if this scanner is a single boundary scanner.lastStep()
Returns information about the movement of the current position, performed by the last call ofBoundary2DScanner.next()
method.long
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 byBoundary2DScanner.x()
,Boundary2DScanner.y()
,Boundary2DScanner.side()
— is located.void
next()
Move the current position to the next segment of the currently scanned object boundary.boolean
Finds the next vertical segment, belonging to some object boundary, after the current position, and sets the current position to the found one.long
Returns the oriented area inside the boundary, traversed byBoundary2DScanner.next()
method since the last call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
method.final Boundary2DScanner
parent()
Returns theparent
scanner.void
Resets the counters, returned byBoundary2DScanner.stepCount()
andBoundary2DScanner.orientedArea()
method, and all other counters, that are possibly increased by inheritors of this class.long
Returns the number of calls ofBoundary2DScanner.next()
method since the last call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
method, corresponding torotation steps
.side()
Returns the current pixel side (or throws IllegalStateException if this scanner was notpositioned yet
).long
Returns the total number of calls ofBoundary2DScanner.next()
method since the last call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
method.long
x()
Returns the current x-coordinate (or throws IllegalStateException if the scanner was notpositioned yet
).long
y()
Returns the current y-coordinate (or throws IllegalStateException if this scanner was notpositioned yet
).Methods inherited from class net.algart.matrices.scanning.Boundary2DScanner
area, checkInterruption, dimX, dimY, fillHoles, fillHoles, getAllBoundariesScanner, getMainBoundariesScanner, getSingleBoundaryScanner, goToSamePosition, isInternalBoundary, matrix, perimeter, scanBoundary, scanBoundary, straightStepCount, toString, updateProgress
-
Field Details
-
parent
The parent scanner: the methods of this object call the corresponding methods of the parent one.- See Also:
-
-
Constructor Details
-
Boundary2DWrapper
Creates new instance of this class.- Parameters:
parent
- the parent scanner, that will be stored inparent
field.- Throws:
NullPointerException
- if parent argument is null.
-
-
Method Details
-
parent
Returns theparent
scanner.- Returns:
- the parent scanner.
-
isSingleBoundaryScanner
public boolean isSingleBoundaryScanner()Description copied from class:Boundary2DScanner
Returns true if and only if this scanner is a single boundary scanner. More precisely, it is true if and only if:- this instance was created by
Boundary2DScanner.getSingleBoundaryScanner(net.algart.arrays.Matrix<? extends net.algart.arrays.BitArray>, net.algart.matrices.scanning.ConnectivityType)
method - or it is
Boundary2DWrapper
and this method of itsparent scanner
returns true.
- Specified by:
isSingleBoundaryScanner
in classBoundary2DScanner
- Returns:
- whether this scanner is a a single boundary scanner.
- this instance was created by
-
isAllBoundariesScanner
public boolean isAllBoundariesScanner()Description copied from class:Boundary2DScanner
Returns true if and only if this scanner is an all boundaries scanner. More precisely, it is true if and only if:- this instance was created by
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)
method - or it is
Boundary2DWrapper
and this method of itsparent scanner
returns true.
- Specified by:
isAllBoundariesScanner
in classBoundary2DScanner
- Returns:
- whether this scanner is a an all boundaries scanner.
- this instance was created by
-
isMainBoundariesScanner
public boolean isMainBoundariesScanner()Description copied from class:Boundary2DScanner
Returns true if and only if this scanner is a main boundaries scanner. More precisely, it is true if and only if:- this instance was created by
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)
method - or it is
Boundary2DWrapper
and this method of itsparent scanner
returns true.
- Specified by:
isMainBoundariesScanner
in classBoundary2DScanner
- Returns:
- whether this scanner is a a main boundaries scanner.
- this instance was created by
-
connectivityType
Description copied from class:Boundary2DScanner
Returns the connectivity kind, used by this object. It is specified while creating this instance.- Specified by:
connectivityType
in classBoundary2DScanner
- Returns:
- the connectivity kind, used by this object.
-
isInitialized
public boolean isInitialized()Description copied from class:Boundary2DScanner
Returns true if and only if this instance was positioned to some coordinates in the matrix. More precisely, returns false if this instance was newly created and none fromBoundary2DScanner.nextBoundary()
,goTo
,goToSamePosition
methods were called yet, or true in all other cases. If this instance isBoundary2DWrapper
, 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.- Specified by:
isInitialized
in classBoundary2DScanner
- Returns:
- true if and only if this instance was already positioned by
nextBoundary
orgoTo
method.
-
isMovedAlongBoundary
public boolean isMovedAlongBoundary()Description copied from class:Boundary2DScanner
Returns true if and only if this scanner is already positioned (Boundary2DScanner.isInitialized()
returns true) and, in addition,Boundary2DScanner.next()
orBoundary2DScanner.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.- Specified by:
isMovedAlongBoundary
in classBoundary2DScanner
- Returns:
- true if and only
Boundary2DScanner.next()
orBoundary2DScanner.scanBoundary(ArrayContext)
methods were successfully called after creating this instance.
-
x
public long x()Description copied from class:Boundary2DScanner
Returns the current x-coordinate (or throws IllegalStateException if the scanner was notpositioned yet
).- Specified by:
x
in classBoundary2DScanner
- Returns:
- the current x-coordinate.
-
y
public long y()Description copied from class:Boundary2DScanner
Returns the current y-coordinate (or throws IllegalStateException if this scanner was notpositioned yet
).- Specified by:
y
in classBoundary2DScanner
- Returns:
- the current y-coordinate.
-
side
Description copied from class:Boundary2DScanner
Returns the current pixel side (or throws IllegalStateException if this scanner was notpositioned yet
).- Specified by:
side
in classBoundary2DScanner
- Returns:
- the current pixel side.
-
atMatrixBoundary
public boolean atMatrixBoundary()Description copied from class:Boundary2DScanner
Returns true if and only if thecurrent pixel side
lies at the boundary of thescanned matrix
. In other words, returns true if:side()
==Side.X_MINUS
andx()
==0,- or
side()
==Side.Y_MINUS
andy()
==0, - or
side()
==Side.X_PLUS
andx()
==dimX()
-1, - or
side()
==Side.Y_PLUS
andy()
==dimY()
-1.
Note: if this scanner was not
positioned yet
, this method does not throw an exception and simply returns false.- Specified by:
atMatrixBoundary
in classBoundary2DScanner
- Returns:
- whether the current segment of the boundary is a part of the boundary of the whole scanned matrix.
-
nestingLevel
public long nestingLevel()Description copied from class:Boundary2DScanner
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 byBoundary2DScanner.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) byBoundary2DScanner.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
- if this scanner was created via
Boundary2DScanner.getAllBoundariesScanner(Matrix, Matrix, Matrix, ConnectivityType)
method; - if the buffer1 and buffer2 argument of that method are different, independently allocated matrices;
- and if
Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
method was never called; - note: if this instance is
Boundary2DWrapper
, the result of this method for the parent scanner is returned.
If this scanner was created via
Boundary2DScanner.getSingleBoundaryScanner(Matrix, ConnectivityType)
orBoundary2DScanner.getMainBoundariesScanner(Matrix, Matrix, ConnectivityType)
, the returned nesting level is always 0. In all other cases, the result of this method is not specified.- Specified by:
nestingLevel
in classBoundary2DScanner
- Returns:
- the current nesting level of object boundaries.
- if this scanner was created via
-
currentIndexInArray
public long currentIndexInArray()Description copied from class:Boundary2DScanner
Returns the index of the current pixel in theunderlying array
of the currently scanned matrix. This method is almost equivalent to , with the only difference that it works even if this scanner was notBoundary2DScanner.y()
*Boundary2DScanner.matrix()
.dimX()
+Boundary2DScanner.x()
positioned yet
: in the last case it returns 0.- Specified by:
currentIndexInArray
in classBoundary2DScanner
- Returns:
- the index of the current pixel in the underlying array of the scanned matrix.
-
goTo
Description copied from class:Boundary2DScanner
Sets the current position in the matrix to the specified coordinates and pixel side.Usually this method is not necessary for scanners, created by
getAllBoundariesScanner
andgetMainBoundariesScanner
methods: it is enough to useBoundary2DScanner.nextBoundary()
andBoundary2DScanner.next()
(orBoundary2DScanner.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).- Specified by:
goTo
in classBoundary2DScanner
- Parameters:
x
- new current x-coordinate.y
- new current y-coordinate.side
- new current pixel side.
-
get
public boolean get()Description copied from class:Boundary2DScanner
Returns the value of the current element of the currently scanned matrix. This method is equivalent to , but works little faster. This method works even if this scanner was notBoundary2DScanner.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)
- Specified by:
get
in classBoundary2DScanner
- Returns:
- the value of the current element of the currently scanned matrix.
-
nextBoundary
public boolean nextBoundary()Description copied from class:Boundary2DScanner
Finds the next vertical segment, belonging to some object boundary, after the current position, and sets the current position to the found one.More precisely, it finds some "next" position after the current position, in the natural order, where the side is
X_MINUS
orX_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 notpositioned yet
, this method finds the first such position.The precise sense of the "next" term above depends on the kind of the boundary scanner.
- If this scanner is created by
Boundary2DScanner.getSingleBoundaryScanner(Matrix, ConnectivityType)
method, it is just the nearest possible position (in the natural order). - If this scanner is created by
Boundary2DScanner.getAllBoundariesScanner(Matrix, Matrix, Matrix, ConnectivityType)
method, it is the nearest boundary segment that was not visited yet byBoundary2DScanner.next()
method. - If this scanner is created by
Boundary2DScanner.getMainBoundariesScanner(Matrix, Matrix, ConnectivityType)
method, it is the nearest boundary segment that was not visited yet byBoundary2DScanner.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.- Specified by:
nextBoundary
in classBoundary2DScanner
- Returns:
- true if this method has successfully found new boundary.
- If this scanner is created by
-
next
public void next()Description copied from class:Boundary2DScanner
Move the current position to the next segment of the currently scanned object boundary. External boundaries are scanned in clockwise order, internal boundaries in anticlockwise order (if we suppose that the x axis is directed rightwards and the y axis is directed downwards).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 classesBoundary2DSimpleMeasurer
,Boundary2DProjectionMeasurer
.- Specified by:
next
in classBoundary2DScanner
-
lastStep
Description copied from class:Boundary2DScanner
Returns information about the movement of the current position, performed by the last call ofBoundary2DScanner.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 ofBoundary2DScanner.isMovedAlongBoundary()
method.- Specified by:
lastStep
in classBoundary2DScanner
- Returns:
- the step of scanning boundary, performed by the call of
Boundary2DScanner.next()
method. - See Also:
-
coordinatesChanged
public boolean coordinatesChanged()Description copied from class:Boundary2DScanner
Returns true if the last call ofBoundary2DScanner.next()
method has changedBoundary2DScanner.x()
orBoundary2DScanner.y()
coordinate. Returns false if the last call ofBoundary2DScanner.next()
method has changed only thecurrent pixel side
.Equivalent to !
Boundary2DScanner.lastStep()
.isSamePixel()
, but works little faster.- Specified by:
coordinatesChanged
in classBoundary2DScanner
- Returns:
- whether the last call of
Boundary2DScanner.next()
method has changed current pixel coordinates.
-
boundaryFinished
public boolean boundaryFinished()Description copied from class:Boundary2DScanner
Returns true if and only if the current position (Boundary2DScanner.x()
,Boundary2DScanner.y()
,Boundary2DScanner.side()
) is identical to the position, set by last call ofBoundary2DScanner.nextBoundary()
orBoundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
method. Usually it means that the current boundary has been successfully scanned.- Specified by:
boundaryFinished
in classBoundary2DScanner
- Returns:
- true if the current boundary scanning is finished.
-
stepCount
public long stepCount()Description copied from class:Boundary2DScanner
Returns the total number of calls ofBoundary2DScanner.next()
method since the last call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
method.The result of this method is based on internal counters, incremented by 1 in
Boundary2DScanner.next()
method and cleared to 0 while object creation and while every call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
methods.Note that we always have:
Boundary2DScanner.stepCount()
=Boundary2DScanner.straightStepCount()
+Boundary2DScanner.diagonalStepCount()
+Boundary2DScanner.rotationStepCount()
.- Specified by:
stepCount
in classBoundary2DScanner
- Returns:
- number of calls of
Boundary2DScanner.next()
method since the last call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
.
-
diagonalStepCount
public long diagonalStepCount()Description copied from class:Boundary2DScanner
Returns the number of calls ofBoundary2DScanner.next()
method since the last call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
method, corresponding todiagonal steps
.The result of this method is based on internal counters, incremented by 1 in
Boundary2DScanner.next()
method and cleared to 0 while object creation and while every call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
methods.- Specified by:
diagonalStepCount
in classBoundary2DScanner
- Returns:
- number of straight steps since the last call of
Boundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
.
-
rotationStepCount
public long rotationStepCount()Description copied from class:Boundary2DScanner
Returns the number of calls ofBoundary2DScanner.next()
method since the last call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
method, corresponding torotation steps
.The result of this method is based on internal counters, incremented by 1 in
Boundary2DScanner.next()
method and cleared to 0 while object creation and while every call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
methods.- Specified by:
rotationStepCount
in classBoundary2DScanner
- Returns:
- number of straight steps since the last call of
Boundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
.
-
orientedArea
public long orientedArea()Description copied from class:Boundary2DScanner
Returns the oriented area inside the boundary, traversed byBoundary2DScanner.next()
method since the last call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
method.The oriented area is the current value of an internal counter, which is reset to 0 while object creation and while every call of
Boundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
methods, and which is incremented while eachBoundary2DScanner.next()
method in the following manner:switch (
side()
{ case X_MINUS: orientedArea -=x()
- 1; break; case X_PLUS: orientedArea +=x()
; break; }In other words, the absolute value of oriented area is the number of pixels inside the traversed boundary, and its sign is positive when it is an object (external boundary) or negative when it is a pore inside an object (internal boundary). It is the total number of pixels of the completion of the current measured object (with minus sign if it is an internal boundary, i.e. when it is the number of pixels in the "hole").
- Specified by:
orientedArea
in classBoundary2DScanner
- Returns:
- the oriented area inside the boundary, traversed by
Boundary2DScanner.next()
method since the last call ofBoundary2DScanner.nextBoundary()
,Boundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
orBoundary2DScanner.resetCounters()
method
-
resetCounters
public void resetCounters()Description copied from class:Boundary2DScanner
Resets the counters, returned byBoundary2DScanner.stepCount()
andBoundary2DScanner.orientedArea()
method, and all other counters, that are possibly increased by inheritors of this class. This method is automatically called at the end ofBoundary2DScanner.nextBoundary()
andBoundary2DScanner.goTo(long, long, net.algart.matrices.scanning.Boundary2DScanner.Side)
methods.- Specified by:
resetCounters
in classBoundary2DScanner
-