diff --git a/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolator.java b/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolator.java new file mode 100644 index 000000000..d17631528 --- /dev/null +++ b/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolator.java @@ -0,0 +1,80 @@ +package net.imglib2.interpolation.neighborsearch; + +import java.util.function.DoubleUnaryOperator; + +import net.imglib2.KDTree; +import net.imglib2.RealPoint; +import net.imglib2.RealRandomAccess; +import net.imglib2.interpolation.InterpolatorFactory; +import net.imglib2.neighborsearch.RadiusNeighborSearch; +import net.imglib2.neighborsearch.RadiusNeighborSearchOnKDTree; +import net.imglib2.type.numeric.NumericType; + +/** + * A {@link RealRandomAccess} for {@link KDTree}s using a radial function used by + * {@link RadialKDTreeInterpolatorFactory}. + */ +public class RadialKDTreeInterpolator> extends RealPoint implements RealRandomAccess { + + protected static final double minThreshold = Double.MIN_VALUE * 1000; + + protected final RadiusNeighborSearch search; + protected final double maxRadius; + protected final double maxSquaredRadius; + protected final KDTree tree; + protected final T value; + protected final T tmp; + protected final DoubleUnaryOperator squaredRadiusFunction; + + public RadialKDTreeInterpolator( + final KDTree tree, + final DoubleUnaryOperator squaredRadiusFunction, + final double maxRadius, + T t) { + + super(tree.numDimensions()); + + this.squaredRadiusFunction = squaredRadiusFunction; + this.tree = tree; + this.search = new RadiusNeighborSearchOnKDTree(tree); + this.maxRadius = maxRadius; + this.maxSquaredRadius = maxRadius * maxRadius; + this.value = t.copy(); + this.tmp = t.copy(); + } + + public double getMaxRadius() { + + return maxRadius; + } + + @Override + public T get() { + + value.setZero(); + search.search(this, maxRadius, false); + if (search.numNeighbors() == 0) + return value; + + for (int i = 0; i < search.numNeighbors(); ++i) { + // can't multiply the value returned + tmp.set(search.getSampler(i).get()); + tmp.mul(squaredRadiusFunction.applyAsDouble(search.getSquareDistance(i))); + value.add(tmp); + } + return value; + } + + @Override + public RadialKDTreeInterpolator copy() { + + return new RadialKDTreeInterpolator(tree, squaredRadiusFunction, maxRadius, value); + } + + @Override + public RadialKDTreeInterpolator copyRealRandomAccess() { + + return copy(); + } + +} diff --git a/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolatorFactory.java b/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolatorFactory.java new file mode 100644 index 000000000..41e9242cb --- /dev/null +++ b/src/main/java/net/imglib2/interpolation/neighborsearch/RadialKDTreeInterpolatorFactory.java @@ -0,0 +1,45 @@ +package net.imglib2.interpolation.neighborsearch; + +import java.util.function.DoubleUnaryOperator; + +import net.imglib2.KDTree; +import net.imglib2.RealInterval; +import net.imglib2.RealRandomAccess; +import net.imglib2.interpolation.InterpolatorFactory; +import net.imglib2.type.numeric.NumericType; + +/** + * An {@link InterpolatorFactory} for {@link KDTree}s using a radial function. + *

+ * The resulting {@link RealRandomAccess} produced by this InterpolatorFactory + * returns values as a linear combination of all points within a certain radius. + * The contribution of each point is weighted according to a function of its + * squared radius. + */ +public class RadialKDTreeInterpolatorFactory> implements InterpolatorFactory> { + + protected final double maxRadius; + protected final DoubleUnaryOperator squaredRadiusFunction; + protected final T val; + + public RadialKDTreeInterpolatorFactory( + final DoubleUnaryOperator squaredRadiusFunction, final double maxRadius, T t) { + + this.maxRadius = maxRadius; + this.squaredRadiusFunction = squaredRadiusFunction; + this.val = t; + } + + @Override + public RadialKDTreeInterpolator create(final KDTree tree) { + + return new RadialKDTreeInterpolator(tree, squaredRadiusFunction, maxRadius, val); + } + + @Override + public RealRandomAccess create(final KDTree tree, final RealInterval interval) { + + return create(tree); + } + +}