+void
+Projections::calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double** ppdView, double** ppdDet)
+{
+ double xMin = -m_phmLen / 2;
+ double xMax = xMin + m_phmLen;
+ double yMin = -m_phmLen / 2;
+ double yMax = yMin + m_phmLen;
+
+ double xInc = (xMax - xMin) / nx; // size of cells
+ double yInc = (yMax - yMin) / ny;
+
+ int iDetCenter = (m_nDet - 1) / 2; // index refering to L=0 projection
+
+ if (m_geometry != Scanner::GEOMETRY_PARALLEL) {
+ sys_error (ERR_WARNING, "convertPolar supports Parallel only");
+ return;
+ }
+
+ // Calculates polar coordinates (view#, det#) for each point on phantom grid
+ double x = xMin + xInc / 2; // Rectang coords of center of pixel
+ for (unsigned int ix = 0; ix < nx; x += xInc, ix++) {
+ double y = yMin + yInc / 2;
+ for (unsigned int iy = 0; iy < ny; y += yInc, iy++) {
+ double r = ::sqrt (x * x + y * y);
+ double phi = atan2 (y, x);
+
+ if (phi >= PI) {
+ phi -= PI;
+ } else if (phi < 0) {
+ phi += PI;
+ } else
+ r = -r;
+
+ ppdView[ix][iy] = (phi - m_rotStart) / m_rotInc;
+ ppdDet[ix][iy] = (r / m_detInc) + iDetCenter;
+ }
+ }
+}
+
+void
+Projections::interpolatePolar (ImageFileArray& v, ImageFileArray& vImag,
+ unsigned int nx, unsigned int ny, std::complex<double>** ppcDetValue,
+ double** ppdView, double** ppdDet, unsigned int nView, unsigned int nDet, int iInterpolationID)
+{
+ for (unsigned int ix = 0; ix < ny; ix++) {
+ for (unsigned int iy = 0; iy < ny; iy++) {
+ if (iInterpolationID == POLAR_INTERP_NEAREST) {
+ int iView = nearest<int> (ppdView[ix][iy]);
+ int iDet = nearest<int> (ppdDet[ix][iy]);
+ if (iView == nView) {
+ iView = 0;
+ // iDet = m_nDet - iDet;
+ }
+ if (iDet >= 0 && iDet < nDet && iView >= 0 && iView < nView) {
+ v[ix][iy] = ppcDetValue[iView][iDet].real();
+ if (vImag)
+ vImag[ix][iy] = ppcDetValue[iView][iDet].imag();
+ } else {
+ sys_error (ERR_SEVERE, "Can't find projection data for ix=%d,iy=%d with radView=%f and radDet=%f",
+ ix, iy, ppdView[ix][iy], ppdDet[ix][iy]);
+ v[ix][iy] = 0;
+ }
+ } else if (iInterpolationID == POLAR_INTERP_BILINEAR) {
+ int iFloorView = static_cast<int>(ppdView[ix][iy]);
+ double dFracView = ppdView[ix][iy] - iFloorView;
+ int iFloorDet = static_cast<int>(ppdDet[ix][iy]);
+ double dFracDet = ppdDet[ix][iy] - iFloorDet;
+
+ if (iFloorDet >= 0 && iFloorView >= 0) {
+ std::complex<double> v1 = ppcDetValue[iFloorView][iFloorDet];
+ std::complex<double> v2, v3, v4;
+ if (iFloorView < nView - 1)
+ v2 = ppcDetValue[iFloorView + 1][iFloorDet];
+ else
+ v2 = ppcDetValue[0][iFloorDet];
+ if (iFloorDet < nDet - 1)
+ v4 = ppcDetValue[iFloorView][iFloorDet+1];
+ else
+ v4 = v1;
+ if (iFloorView < nView - 1 && iFloorDet < nDet - 1)
+ v3 = ppcDetValue [iFloorView+1][iFloorDet+1];
+ else if (iFloorView < nView - 1)
+ v3 = v2;
+ else
+ v3 = ppcDetValue[0][iFloorDet+1];
+ std::complex<double> vInterp = (1 - dFracView) * (1 - dFracDet) * v1 +
+ dFracView * (1 - dFracDet) * v2 + dFracView * dFracDet * v3 +
+ dFracDet * (1 - dFracView) * v4;
+ v[ix][iy] = vInterp.real();
+ if (vImag)
+ vImag[ix][iy] = vInterp.imag();
+ } else {
+ sys_error (ERR_SEVERE, "Can't find projection data for ix=%d,iy=%d with radView=%f and radDet=%f",
+ ix, iy, ppdView[ix][iy], ppdDet[ix][iy]);
+ v[ix][iy] = 0;
+ if (vImag)
+ vImag[ix][iy] = 0;
+ }
+ } else if (iInterpolationID == POLAR_INTERP_BICUBIC) {
+ v[ix][iy] =0;
+ if (vImag)
+ vImag[ix][iy] = 0;
+ }
+ }
+ }
+}
+