Created
October 6, 2012 16:31
-
-
Save bdezonia/3845389 to your computer and use it in GitHub Desktop.
Toy example for Roi discussions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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