package icy.math;
import icy.type.geom.Line3D;
import icy.type.point.Point3D;
import java.util.Iterator;
/**
* Line3D iterator (iterate over Line3D points given a wanted step).
*
* @author Stephane Dallongeville
*/
public class Line3DIterator implements Iterator<Point3D>
{
final static protected double DEFAULT_STEP = 1d;
protected boolean done;
protected int count;
final protected Point3D pos;
final protected Point3D last;
protected double sx, sy, sz;
/**
* Create the Line3D Iterator.
*
* @param line
* the lien we want to iterate points
* @param step
* step between each point (default = 1d)
*/
public Line3DIterator(Line3D line, double step)
{
super();
pos = line.getP1();
last = line.getP2();
done = false;
final double dx = last.getX() - pos.getX();
final double dy = last.getY() - pos.getY();
final double dz = last.getZ() - pos.getZ();
final double adx = Math.abs(dx);
final double ady = Math.abs(dy);
final double adz = Math.abs(dz);
final double adjStep = (step <= 0d) ? 1d : step;
// step on X axis
if ((adx >= ady) && (adx >= adz))
{
if (adx == 0d)
{
count = 0;
sy = 0;
sz = 0;
}
else
{
count = (int) (adx / adjStep);
sy = (ady / adx) * adjStep;
sz = (adz / adx) * adjStep;
}
sx = adjStep;
}
// adjStep on Y axis
else if ((ady >= adx) && (ady >= adz))
{
count = (int) (ady / adjStep);
sx = (adx / ady) * adjStep;
sy = adjStep;
sz = (adz / ady) * adjStep;
}
// adjStep on Z axis
else
{
count = (int) (adz / adjStep);
sx = (adx / adz) * adjStep;
sy = (ady / adz) * adjStep;
sz = adjStep;
}
// for initial position
count++;
// reverse step if needed
if (dx < 0)
sx = -sx;
if (dy < 0)
sy = -sy;
if (dz < 0)
sz = -sz;
}
/**
* Create the Line3D Iterator.
*
* @param line
* the lien we want to iterate points
*/
public Line3DIterator(Line3D line)
{
this(line, DEFAULT_STEP);
}
@Override
public boolean hasNext()
{
return !done;
}
@Override
public Point3D next()
{
final Point3D result = (Point3D) pos.clone();
// done ?
if (--count <= 0)
{
// consider done only if pos is equal to last
done = pos.equals(last);
// force equality with last position
pos.setLocation(last);
}
else
pos.setLocation(pos.getX() + sx, pos.getY() + sy, pos.getZ() + sz);
return result;
}
@Override
public void remove()
{
throw new UnsupportedOperationException();
}
}