private boolean isInvalid() { for (int i = 0; i < position.length; i++) if (position[i] < parentSpace.min(i) || position[i] > parentSpace.max(i)) { return true; } return false; }
/** * Moves a given dimension of the {@link Position} by a given delta. Throws an exception if delta * would move {@link Position} outside its parent {@link Extents}. */ @Override public void move(final long delta, final int dim) { if (this.isInvalid) { throw new IllegalArgumentException("Cannot move position : it is uninitialized"); } final long newValue = position[dim] + delta; if (newValue < parentSpace.min(dim) || newValue > parentSpace.max(dim)) { throw new IllegalArgumentException( "specified move would take position outside defined extents"); } position[dim] = newValue; }
/** * Moves the {@link Position} backward by one step. Decrements the dimension positions from left * to right. * * @throws IllegalStateException if called from first position. */ public void bck() { if (this.isInvalid) { last(); return; } for (int i = 0; i < position.length; i++) { position[i]--; if (position[i] >= parentSpace.min(i)) return; position[i] = parentSpace.max(i); } first(); // reset position to where it was throw new IllegalStateException("cannot move first position backward"); }
/** * Moves the {@link Position} forward by one step. Increments the dimension positions from left to * right. * * @throws IllegalStateException if called from last position. */ @Override public void fwd() { if (this.isInvalid) { first(); return; } for (int i = 0; i < position.length; i++) { position[i]++; if (position[i] <= parentSpace.max(i)) return; position[i] = parentSpace.min(i); } last(); // reset position to where it was throw new IllegalStateException("cannot move last position forward"); }
/** * Sets the {@link Position} from a given long index. The index ranges from 0 to * extents.numElements()-1. Throws an exception if index out of range. */ public void setIndex(final long index) { if (index < 0 || index >= parentSpace.numElements()) { throw new IllegalArgumentException("specified index value is outside bounds of extents"); } long offset = 1; long r = index; for (int i = 0; i < position.length; i++) { final long offset1 = offset * dimension(i); final long q = i < position.length - 1 ? r % offset1 : r; position[i] = (q / offset) + parentSpace.min(i); r -= q; offset = offset1; } this.isInvalid = false; }
/** * Sets the value of the {@link Position} for a given dimension. Throws an exception if the given * value is outside the bounds of the parent {@link Extents}. */ @Override public void setPosition(final long value, final int dim) { final long min = parentSpace.min(dim); if (value < min) { throw new IllegalArgumentException( "invalid position for dimension #" + dim + ": " + value + " < " + min); } final long max = parentSpace.max(dim); if (value > max) { throw new IllegalArgumentException( "invalid position for dimension #" + dim + ": " + value + " > " + max); } position[dim] = value; if (this.isInvalid) this.isInvalid = isInvalid(); }
/** * Gets the long index from the current {@link Position}. The index ranges from 0 to * extents.numElements()-1. */ public long getIndex() { if (this.isInvalid && position.length > 0) { throw new IllegalArgumentException("Cannot get index value : position is uninitialized"); } long offset = 1; long index1D = 0; for (int i = 0; i < position.length; i++) { index1D += offset * (position[i] - parentSpace.min(i)); offset *= dimension(i); } return index1D; }
/** * Moves the {@link Position} backward one step in specified dimension. Throws an exception if * specified move would take position outside parent {@link Extents}. */ @Override public void bck(final int d) { if (this.isInvalid) { throw new IllegalArgumentException("Cannot move position : it is uninitialized"); } final long newValue = position[d] - 1; if (newValue < parentSpace.min(d)) { throw new IllegalArgumentException( "cannot move specified dimension backward -" + " it would take position outside defined extents"); } position[d]--; }
/** * Returns true if position can be moved backward (i.e. position is not in the first position). */ public boolean hasPrev() { if (this.isInvalid && position.length > 0) return true; for (int i = 0; i < position.length; i++) if (position[i] > parentSpace.min(i)) return true; return false; }
/** Returns true if position can be moved forward (i.e. position is not in the last position). */ @Override public boolean hasNext() { if (this.isInvalid && position.length > 0) return true; for (int i = 0; i < position.length; i++) if (position[i] < parentSpace.max(i)) return true; return false; }
/** Returns the dimension of the {@link Position}'s parent {@link Extents} at a given i. */ public long dimension(final int i) { return parentSpace.dimension(i); }
/** Returns the number of dimensions within the {@link Position}. */ @Override public int numDimensions() { return parentSpace.numDimensions(); }
/** * Constructor - takes an {@link Extents} object that represents the parent space to iterate * within. */ public Position(final Extents parentSpace) { this.parentSpace = parentSpace; this.position = new long[parentSpace.numDimensions()]; // ImgLib convention - start out of bounds reset(); }
/** Sets the {@link Position} to its last state (all dimension positions to max-1) */ public void last() { for (int i = 0; i < position.length; i++) position[i] = parentSpace.max(i); this.isInvalid = false; }