102 lines
3.2 KiB
Java
102 lines
3.2 KiB
Java
package sparseviewer.interp;
|
|
|
|
public class IdwInterpolator {
|
|
|
|
public static InterpolationResult interpolate(double[] x,
|
|
double[] y,
|
|
double[] z,
|
|
int width,
|
|
int height,
|
|
double power) {
|
|
Grid2D grid = createGrid(x, y, width, height);
|
|
float[] out = new float[width * height];
|
|
|
|
double exponent = power * 0.5;
|
|
|
|
for (int iy = 0; iy < height; iy++) {
|
|
double gy = grid.yAt(iy);
|
|
|
|
for (int ix = 0; ix < width; ix++) {
|
|
double gx = grid.xAt(ix);
|
|
|
|
double numerator = 0.0;
|
|
double denominator = 0.0;
|
|
boolean exact = false;
|
|
double exactValue = 0.0;
|
|
|
|
for (int i = 0; i < x.length; i++) {
|
|
if (!isFinite(x[i]) || !isFinite(y[i]) || !isFinite(z[i])) {
|
|
continue;
|
|
}
|
|
|
|
double dx = x[i] - gx;
|
|
double dy = y[i] - gy;
|
|
double d2 = dx * dx + dy * dy;
|
|
|
|
if (d2 < 1e-24) {
|
|
exact = true;
|
|
exactValue = z[i];
|
|
break;
|
|
}
|
|
|
|
double w = 1.0 / Math.pow(d2, exponent);
|
|
|
|
numerator += w * z[i];
|
|
denominator += w;
|
|
}
|
|
|
|
if (exact) {
|
|
out[iy * width + ix] = (float) exactValue;
|
|
} else if (denominator > 0.0) {
|
|
out[iy * width + ix] = (float) (numerator / denominator);
|
|
} else {
|
|
out[iy * width + ix] = Float.NaN;
|
|
}
|
|
}
|
|
}
|
|
|
|
return new InterpolationResult(grid, out);
|
|
}
|
|
|
|
private static Grid2D createGrid(double[] x, double[] y, int width, int height) {
|
|
double xmin = Double.POSITIVE_INFINITY;
|
|
double xmax = Double.NEGATIVE_INFINITY;
|
|
double ymin = Double.POSITIVE_INFINITY;
|
|
double ymax = Double.NEGATIVE_INFINITY;
|
|
|
|
for (int i = 0; i < x.length; i++) {
|
|
if (isFinite(x[i])) {
|
|
if (x[i] < xmin) xmin = x[i];
|
|
if (x[i] > xmax) xmax = x[i];
|
|
}
|
|
|
|
if (isFinite(y[i])) {
|
|
if (y[i] < ymin) ymin = y[i];
|
|
if (y[i] > ymax) ymax = y[i];
|
|
}
|
|
}
|
|
|
|
if (xmin == xmax) {
|
|
xmin -= 1.0;
|
|
xmax += 1.0;
|
|
}
|
|
|
|
if (ymin == ymax) {
|
|
ymin -= 1.0;
|
|
ymax += 1.0;
|
|
}
|
|
|
|
double xpad = 0.03 * (xmax - xmin);
|
|
double ypad = 0.03 * (ymax - ymin);
|
|
|
|
return new Grid2D(width, height,
|
|
xmin - xpad,
|
|
xmax + xpad,
|
|
ymin - ypad,
|
|
ymax + ypad);
|
|
}
|
|
|
|
private static boolean isFinite(double v) {
|
|
return !Double.isNaN(v) && !Double.isInfinite(v);
|
|
}
|
|
} |