/*
* Copyright (C) 2010-2014 - Andreas Maier
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/
package edu.stanford.rsl.conrad.data.numeric.iterators;
import edu.stanford.rsl.conrad.data.numeric.Grid2D;
import edu.stanford.rsl.conrad.data.numeric.NumericGrid;
public class NumericFloatIterator{
protected NumericGrid m_grid;
/**
* The condition for out of bound values
* 0 = clamp to zero
* 1 = clamp to constant
* 2 = clamp to edge value
* 3 = symmetrically extend value
* 4 = extend periodically
*/
protected int boundaryCondition;
/**
* The boundary size for each dimension.
* Half of the boundary size is extended in each direction.
* If N is the given size and N is odd, the boundary on the right side is extended by N/2 + 1,
* whereas the boundary on the left side is extended by N/2.
*/
protected int[] boundarySize;
/**
* The value to set the boundary if using a clamp to constant boundary condition
*/
protected float clampValue;
/**
* The iterators direction
*/
protected int[] direction;
/**
* The current iterator position
*/
protected int[] position;
protected int dim;
public NumericFloatIterator(NumericGrid g){
this(g, 0, new int[g.getSize().length], 0.f, new int[g.getSize().length]);
}
public NumericFloatIterator(NumericGrid g, int boundCond, int[] boundSize, float clampValue, int[] pos, int []dir) {
// set the grid
this.m_grid = g;
// initialize the boundaries
boundaryCondition = boundCond;
boundarySize = boundSize;
this.clampValue = clampValue;
// set initial direction
direction = dir;
// set initial position
position = pos;
// the dimension
dim = g.getSize().length;
}
public NumericFloatIterator(NumericGrid g, int boundCond, int[] boundSize, float clampValue, int[] pos) {
// set the grid
this.m_grid = g;
// initialize the boundaries
boundaryCondition = boundCond;
boundarySize = boundSize;
this.clampValue = clampValue;
// set initial direction
direction = new int[g.getSpacing().length];
direction[0]=1;
// set initial position
position = pos;
// the dimension
dim = g.getSize().length;
}
public boolean hasNext(){
boolean val = true;
for (int i=0; i < dim; ++i){
int tmp = position[i];
if (tmp < 0 - boundarySize[i]/2 || tmp >= m_grid.getSize()[i] + boundarySize[i]/2 + boundarySize[i]%2)
val = false;
}
return val;
}
private void move(){
for (int i=0; i < dim; ++i)
position[i]+=direction[i];
}
public float getNext(){
int[] currentPosition = null;
Float val = null;
for (int i=0; i < dim; ++i){
boolean bleft=position[i] < 0;
boolean bright=position[i] >= m_grid.getSize()[i];
// check if we have a boundary case
if (bleft || bright) {
switch (boundaryCondition) {
case 0:
val = new Float(0.f);
break;
case 1:
val = new Float(clampValue);
break;
case 2:
currentPosition = (currentPosition==null) ? position.clone() : currentPosition;
currentPosition[i] = (bleft) ? 0 : m_grid.getSize()[i]-1;
break;
case 3:
currentPosition = (currentPosition==null) ? position.clone() : currentPosition;
// TODO not save if grid dimension is smaller than the boundary
currentPosition[i] = (bleft) ? Math.abs(position[i]) -1 : m_grid.getSize()[i] - (position[i] % m_grid.getSize()[i]) -1;
break;
case 4:
currentPosition = (currentPosition==null) ? position.clone() : currentPosition;
currentPosition[i] = (bleft) ? m_grid.getSize()[i] + ((position[i]+1) % m_grid.getSize()[i]) -1 : (position[i] % m_grid.getSize()[i]);
break;
default:
break;
}
}
}
float out = (val != null) ? val.floatValue() : ((currentPosition!=null) ? m_grid.getValue(currentPosition) : m_grid.getValue(position));
this.move();
return out;
}
public int[] getPosition(){
return position;
}
public void setPosition(int... pos){
position = pos;
}
public void setDirection(int... dir){
direction = dir;
}
public int[] getDirection(){
return direction.clone();
}
public static void main(String[] args) {
NumericGrid g = new Grid2D(8,8);
for (int i=0; i < 8; i++){
for (int j=0; j<8; j++)
((Grid2D)g).setAtIndex(i, j, i);
}
NumericFloatIterator it = new NumericFloatIterator(g,4,new int[]{16,16},10.f,new int[]{-8,-8},new int[]{1,0});
while (it.hasNext())
{
System.out.print(it.getPosition()[0]+ "/" + it.getPosition()[1] + ": " + it.getNext() + "\n");
}
}
}