Skip to content

Instantly share code, notes, and snippets.

@bdezonia
Created October 6, 2012 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bdezonia/3845389 to your computer and use it in GitHub Desktop.
Save bdezonia/3845389 to your computer and use it in GitHub Desktop.
Toy example for Roi discussions
//import java.lang.reflect.Array;
/*
* Toy example
*
* Want to be able to have
* regions (regions of interest)
* iterable regions
* coordinates of type int[], double[], long[], etc.
* we should be able to treat any iterable region as a region of interest
*
* In real implementation would like to eliminate Number and all the object
* overhead. And use Imglib types to advantage with primitive access when possible.
*/
public class Misc {
/*
* The following 4 interfaces support the bulk of what PointSets currently do.
* It breaks RegionOfInterest's reliance on double[]
* it breaks PointSet's reliance on long[]
*/
private interface Coordinate<T extends Number> {
int numDimensions();
void get(Coordinate<T> target);
void set(Coordinate<T> source);
T get(int i);
void set(int i, T v);
void inc(int i);
void dec(int i);
void incBy(int i, T delta);
void decBy(int i, T delta);
Coordinate<T> copy();
Coordinate<T> createNew();
}
private interface Region<T extends Number> {
int numDimensions();
void min(Coordinate<T> targetCoord);
void max(Coordinate<T> targetCoord);
T min(int i);
T max(int i);
Coordinate<T> createCoord();
/** Useful for parallelizing problems */
Region<T> copy();
/** Membership testing */
boolean includes(Coordinate<T> coord);
/** Ability to move them in space along its axes with correct granularity */
void translate(Coordinate<T> deltas);
}
private interface IterableRegion<T extends Number> extends Region<T> {
/** key functionality */
Iterator<Coordinate<T>> createIterator();
/** Useful info for things like undo. Can be faster than counting. */
long calcNumElements();
}
private interface Iterator<T> {
boolean hasNext();
T next();
void reset();
}
/* The code after this provides some flesh as examples */
/**
* A real coordinate implementation of a Region of space. Not iterable.
*
* T should be a floating type (Number not specific enough here)
*/
private class HyperVolume<T extends Number> implements Region<T> {
// TODO - won't flesh out right now. Similar to Grid below but without iterators
// and works in floating point
}
/**
* A integer coordinate implementation of an IterableRegion.
*
* T should be an integral type (Number not specific enough here)
*
* This class based upon Imglib2 OPS' poorly named HyperVolumePointSet
*/
private class Grid<T extends Number> implements IterableRegion<T> {
private Coordinate<T> minCoord, maxCoord;
public Grid(Coordinate<T> coord1, Coordinate<T> coord2) {
if (coord1.numDimensions() != coord2.numDimensions())
throw new IllegalArgumentException();
minCoord = coord1.createNew();
maxCoord = coord1.createNew();
for (int i = 0; i < coord1.numDimensions(); i++) {
T a = coord1.get(i);
T b = coord2.get(i);
minCoord.set(i, calcMin(a,b));
maxCoord.set(i, calcMax(a,b));
}
}
@Override
public int numDimensions() {
return minCoord.numDimensions();
}
@Override
public boolean includes(Coordinate<T> coord) {
if (coord.numDimensions() != numDimensions()) return false;
for (int i = 0; i < coord.numDimensions(); i++) {
T min = min(i);
T max = max(i);
T val = coord.get(i);
if (less(val, min)) return false;
if (greater(val, max)) return false;
}
return true;
}
@Override
public Iterator<Coordinate<T>> createIterator() {
return new GridIterator<T>(this);
}
@Override
public void min(Coordinate<T> targetCoord) {
targetCoord.set(minCoord);
}
@Override
public void max(Coordinate<T> targetCoord) {
targetCoord.set(maxCoord);
}
@Override
public T min(int i) {
return minCoord.get(i);
}
@Override
public T max(int i) {
return maxCoord.get(i);
}
@Override
public void translate(Coordinate<T> deltas) {
for (int i = 0; i < numDimensions(); i++) {
minCoord.incBy(i, deltas.get(i));
maxCoord.incBy(i, deltas.get(i));
}
}
@Override
public Coordinate<T> createCoord() {
return minCoord.createNew();
}
@Override
public long calcNumElements() {
// TODO calc from minCoord and maxCoord values
return 0;
}
@Override
public Grid<T> copy() {
return new Grid<T>(minCoord, maxCoord);
}
}
private class GridIterator<T extends Number> implements Iterator<Coordinate<T>> {
private final Grid<T> grid;
private final Coordinate<T> minPos;
private final Coordinate<T> maxPos;
private final Coordinate<T> currPos;
private boolean outOfBounds;
public GridIterator(Grid<T> grid) {
this.grid = grid;
this.minPos = grid.createCoord();
this.maxPos = grid.createCoord();
this.currPos = grid.createCoord();
firstPos();
}
@Override
public boolean hasNext() {
if (outOfBounds) return true;
for (int i = 0; i < currPos.numDimensions(); i++) {
currPos.inc(i);
if (lessOrEqual(currPos.get(i), maxPos.get(i))) {
return true;
}
currPos.set(i, minPos.get(i));
}
return false;
}
@Override
public Coordinate<T> next() {
if (outOfBounds) outOfBounds = false;
return currPos;
}
@Override
public void reset() {
firstPos();
}
private void firstPos() {
// the grid may have been translated so regrab min/max
grid.min(minPos);
grid.max(maxPos);
outOfBounds = true;
currPos.set(minPos);
}
}
// TODO - we should make some composite Regions/IterableRegion classes
// There are such examples in Imglib2 OPS pointset subpackage
// These are useful and powerful
// TODO - eliminate these using Imglib types. For this mini example only
private <T extends Number> T calcMin(T a, T b) {
if (a.doubleValue() < b.doubleValue()) return a;
return b;
}
private <T extends Number> T calcMax(T a, T b) {
if (a.doubleValue() > b.doubleValue()) return a;
return b;
}
private <T extends Number> boolean less(T a, T b) {
if (a.doubleValue() < b.doubleValue()) return true;
return false;
}
private <T extends Number> boolean greater(T a, T b) {
if (a.doubleValue() > b.doubleValue()) return true;
return false;
}
private <T extends Number> boolean lessOrEqual(T a, T b) {
if (a.doubleValue() <= b.doubleValue()) return true;
return false;
}
private <T extends Number> boolean greaterOrEqual(T a, T b) {
if (a.doubleValue() >= b.doubleValue()) return true;
return false;
}
private <T extends Number> boolean equal(T a, T b) {
if (a.doubleValue() == b.doubleValue()) return true;
return false;
}
private <T extends Number> boolean notEqual(T a, T b) {
if (a.doubleValue() != b.doubleValue()) return true;
return false;
}
private <T extends Number> T add(T a, T b) {
throw new UnsupportedOperationException("this provided by Imglib types");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment