X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;f=include%2Finterpolator.h;h=1b1fc484b2fc24b63f382dff5cd522e10ecce587;hb=5a6caa64e880f613b82e516031028d02fd127257;hp=def913ec377161f40e86e7765fb24f1faf605cbe;hpb=befd71a7157339b52a0c40359518d5276b25d127;p=ctsim.git diff --git a/include/interpolator.h b/include/interpolator.h index def913e..1b1fc48 100644 --- a/include/interpolator.h +++ b/include/interpolator.h @@ -2,7 +2,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: interpolator.h,v 1.1 2001/02/11 21:57:08 kevin Exp $ +** $Id: interpolator.h,v 1.4 2001/03/24 05:28:28 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -34,6 +34,7 @@ public: double interpolate (double x); }; + class CubicPolyInterpolator { private: const double* const m_pdY; @@ -47,3 +48,155 @@ public: double interpolate (double x); }; + +template +class BilinearInterpolator { +private: + T** const m_ppMatrix; + const unsigned int m_nx; + const unsigned int m_ny; + +public: + BilinearInterpolator (T** ppMatrix, unsigned int nx, unsigned int ny) + : m_ppMatrix(ppMatrix), m_nx(nx), m_ny(ny) + {} + + T interpolate (double dXPos, double dYPos) + { + int iFloorX = floor (dXPos); + int iFloorY = floor (dYPos); + double dXFrac = dXPos - iFloorX; + double dYFrac = dYPos - iFloorY; + + T result = 0; + + if (iFloorX < 0 || iFloorY < 0 || iFloorX > m_nx-1 || iFloorY > m_ny-1) + result = 0; + else if (iFloorX == m_nx - 1 && iFloorY == m_ny - 1) + result = m_ppMatrix[m_nx-1][m_ny-1]; + else if (iFloorX == m_nx - 1) + result = m_ppMatrix[iFloorX][iFloorY] + dYFrac * (m_ppMatrix[iFloorX][iFloorY+1] - m_ppMatrix[iFloorX][iFloorY]); + else if (iFloorY == m_ny - 1) + result = m_ppMatrix[iFloorX][iFloorY] + dXFrac * (m_ppMatrix[iFloorX+1][iFloorY] - m_ppMatrix[iFloorX][iFloorY]); + else + result = (1 - dXFrac) * (1 - dYFrac) * m_ppMatrix[iFloorX][iFloorY] + + dXFrac * (1 - dYFrac) * m_ppMatrix[iFloorX+1][iFloorY] + + dYFrac * (1 - dXFrac) * m_ppMatrix[iFloorX][iFloorY+1] + + dXFrac * dYFrac * m_ppMatrix[iFloorX+1][iFloorY+1]; + + return result; + } +}; + + +template +class BicubicPolyInterpolator { +private: + T** const m_ppMatrix; + const unsigned int m_nx; + const unsigned int m_ny; + +public: + BicubicPolyInterpolator (T** ppMatrix, unsigned int nx, unsigned int ny) + : m_ppMatrix(ppMatrix), m_nx(nx), m_ny(ny) + {} + + T interpolate (double dXPos, double dYPos) + { + int iFloorX = floor (dXPos); + int iFloorY = floor (dYPos); + double dXFrac = dXPos - iFloorX; + double dYFrac = dYPos - iFloorY; + + T result = 0; + + // Need to add code + + return result; + } +}; + + +template +class LinearInterpolator { +private: + T* const m_pX; + T* const m_pY; + const unsigned int m_n; + const bool m_bZeroOutsideRange; + +public: + LinearInterpolator (T* pY, unsigned int n, bool bZeroOutside = true) + : m_pX(0), m_pY(pY), m_n(n), m_bZeroOutsideRange(bZeroOutside) + {} + + LinearInterpolator (T* pX, T* pY, unsigned int n, bool bZeroOutside = true) + : m_pX(pX), m_pY(pY), m_n(n), m_bZeroOutsideRange(bZeroOutside) + {} + + double interpolate (double dX, int* piLastFloor = NULL) + { + double result = 0; + + if (! m_pX) { + if (dX == 0) + result = m_pY[0]; + else if (dX < 0) { + if (m_bZeroOutsideRange) + result = 0; + else + result = m_pY[0]; + } else if (dX == m_n - 1) + result = m_pY[m_n-1]; + else if (dX > m_n - 1) { + if (m_bZeroOutsideRange) + result = 0; + else + result = m_pY[m_n - 1]; + } else { + int iFloor = floor(dX); + result = m_pY[iFloor] + (m_pY[iFloor+1] - m_pY[iFloor]) * (dX - iFloor); + } + } else { + int iLower = -1; + int iUpper = m_n; + if (piLastFloor && *piLastFloor >= 0 && m_pX[*piLastFloor] < dX) + iLower = *piLastFloor; + + while (iUpper - iLower > 1) { + int iMiddle = (iUpper + iLower) >> 1; + if (dX >= m_pX[iMiddle]) + iLower = iMiddle; + else + iUpper = iMiddle; + } + if (dX == m_pX[0]) + result = m_pY[0]; + else if (dX < m_pX[0]) { + if (m_bZeroOutsideRange) + result = 0; + else + result = m_pY[0]; + } else if (dX == m_pX[m_n-1]) + result = m_pY[m_n-1]; + else if (dX > m_pX[m_n - 1]) { + if (m_bZeroOutsideRange) + result = 0; + else + result = m_pY[m_n - 1]; + } else { + if (iLower < 0 || iLower >= m_n) { + sys_error (ERR_SEVERE, "Coordinate out of range [linearInterpolate]"); + return 0; + } + + if (piLastFloor) + *piLastFloor = iLower; + result = m_pY[iLower] + (m_pY[iUpper] - m_pY[iLower]) * ((dX - m_pX[iLower]) / (m_pX[iUpper] - m_pX[iLower])); + } + } + + return result; + } +}; +