/** * This is a couple of functions to do rebinning. This is neeeded when * you have a number of data points with random coordinates and you wish to * get this back onto a regular grid for better handling. * * copyright: see file COPYRIGHT * * Mark Koennecke, May 2007 */ #include #include "rebin.h" /*---------------------------------------------------------------------------*/ static int checkPoint(pNXDS target, double x, double y) { int maxx, maxy; maxx = getNXDatasetDim(target, 0); maxy = getNXDatasetDim(target, 1); if (x < .0 || y < .0 || x > maxx - 1 || y > maxy - 1) { return 0; } return 1; } /*--------------------------------------------------------------------------*/ static void addNXDatasetValue(pNXDS target, int64_t iPos[], double value) { double val; val = value + getNXDatasetValue(target, iPos); putNXDatasetValue(target, iPos, val); } /*---------------------------------------------------------------------------*/ static void roundPoint(pNXDS target, double x, double y, double value) { int64_t iDim[2]; iDim[0] = (int) floor(x + .5); iDim[1] = (int) floor(y + 0.5); addNXDatasetValue(target, iDim, value); } /*---------------------------------------------------------------------------- * I am using the squares here, no need to do the sqrt which would give the * actual distance. * ---------------------------------------------------------------------------*/ static double dist(double x1, double y1, double x2, double y2) { double dx, dy; dx = x1 - x2; dy = y1 - y2; return dx * dx + dy * dy; } /*----------------------------------------------------------------------------- * This tries to distribute value over all of the four neighbouring points * weighted with the distance to them. -------------------------------------------------------------------------------*/ static void distribute(pNXDS target, double x, double y, double value) { double lldist, lrdist, uldist, urdist, totalDist, ix, iy, frac; int64_t iPos[2]; ix = floor(x); iy = floor(y); lldist = dist(x, y, ix, iy); if (lldist < .01) { iPos[0] = ix; iPos[1] = iy; addNXDatasetValue(target, iPos, value); return; } ix += 1; lrdist = dist(x, y, ix, iy); if (lrdist < .01) { iPos[0] = ix; iPos[1] = iy; addNXDatasetValue(target, iPos, value); return; } iy += 1; urdist = dist(x, y, ix, iy); if (urdist < .01) { iPos[0] = ix; iPos[1] = iy; addNXDatasetValue(target, iPos, value); return; } ix = floor(x); uldist = dist(x, y, ix, iy); if (uldist < .01) { iPos[0] = ix; iPos[1] = iy; addNXDatasetValue(target, iPos, value); return; } lldist = 1. / lldist; lrdist = 1. / lrdist; urdist = 1. / urdist; uldist = 1. / uldist; totalDist = lldist + lrdist + urdist + uldist; if (totalDist < .01) { iPos[0] = (int) floor(x); iPos[1] = (int) floor(y); addNXDatasetValue(target, iPos, value); return; } iPos[0] = (int) floor(x); iPos[1] = (int) floor(y); frac = (lldist / totalDist) * value; addNXDatasetValue(target, iPos, frac); iPos[0] += 1; frac = (lrdist / totalDist) * value; addNXDatasetValue(target, iPos, frac); iPos[1] += 1; frac = (urdist / totalDist) * value; addNXDatasetValue(target, iPos, frac); iPos[0] = (int) floor(x); frac = (uldist / totalDist) * value; addNXDatasetValue(target, iPos, frac); } /*---------------------------------------------------------------------------*/ int rebinPoint2D(pNXDS target, double x, double y, double value, int method) { if (!checkPoint(target, x, y)) { return 0; } switch (method) { case TRILINEAR: distribute(target, x, y, value); break; case ROUND: roundPoint(target, x, y, value); break; default: return 0; } return 1; }