Bool_t TZigZag::NearestPoints(Double_t x, TArrayI &I, TArrayD &W) const { // One-dimensional case. Gives the 2 nearest points from point x in zigzag numbering. //W are weights for the points, calculated according to the inverse of their distances //from x const Double_t un = 1.0; const Double_t eps = 1.0e-12; Int_t k; Double_t xl,xr,x1,x2,dx,dxs2,w0,w1,wt; I.Set(2); W.Set(2); dx = (fXmax-fXmin)/fNx; dxs2 = dx/2; xl = dxs2; xr = dxs2 + (fNx-1)*dx; if (x<xl) { I[0] = 0; I[1] = 1; x1 = dxs2; x2 = dxs2 + dx; } else { if (x>xr) { I[0] = fNx - 1; I[1] = fNx - 2; x1 = dxs2 + (fNx-1)*dx; x2 = x1 - dx; } else { k = Int_t((x-dxs2)/dx); I[0] = k; I[1] = k+1; x1 = dxs2 + k*dx; x2 = x1 + dx; } } w0 = TMath::Abs(x1-x); if (w0<eps) w0 = eps; w0 = un/w0; w1 = TMath::Abs(x2-x); if (w1<eps) w1 = eps; w1 = un/w1; wt = w0 + w1; W[0] = w0/wt; W[1] = w1/wt; return kTRUE; }
Bool_t TZigZag::PointsNear(Double_t x, Double_t y, Double_t &yi, TArrayD &Tn, TArrayD &Yn) const { // Two-dimensional case. Finds in I,T,X,Y the 4 points of the grid around point (x,y). //Then finds the 2 closest points along the zigzag in In,Tn,Xn,Yn. // If point (x,y) not inside [fXmin,fXmax] and [fYmin,fYmax], make a projection //towards center and stops at point just after entry and gives the 4 points for it. const Double_t un = 1.0; const Double_t aeps = 1.0e-6; TArrayI Ii(4); TArrayD Ti(4); TArrayD Xi(4); TArrayD Yi(4); Bool_t ok; Int_t i; Int_t kx=0; Int_t ky=0; Double_t mx,my,eps; Double_t xc,xl,xr,dx,dxs2; Double_t yc,yl,yr,dy,dys2; Double_t xi,xp,yp; Double_t xle,xre,yle,yre; Tn.Set(2); Yn.Set(2); dx = (fXmax-fXmin)/fNx; dxs2 = dx/2; dy = (fYmax-fYmin)/fNy; dys2 = dy/2; xl = dxs2; xr = dxs2 + (fNx-1)*dx; yl = dys2; yr = dys2 + (fNy-1)*dy; if ((yr-yl) > (xr-xl)) eps = aeps*(yr-yl); else eps = aeps*(xr-xl); xle = xl + eps; xre = xr - eps; yle = yl + eps; yre = yr - eps; if ((x>=xle) && (x<=xre) && (y>=yle) && (y<=yre)) { xi = x; yi = y; kx = Int_t((xi-dxs2)/dx) + 1; ky = Int_t((yi-dys2)/dy) + 1; ok = kTRUE; }//end if ((x>xl) && (x<xr) && (y>yl) && (y<yr)) else { xc = (fXmax-fXmin)/2; yc = (fYmax-fYmin)/2; mx = (y-yc)/(x-xc); my = un/mx; xi = xle; yi = yc + mx*(xi-xc); ok = IsInside(xi,yi,x,y,xc,yc,xl,xr,yl,yr); if (!ok) { xi = xre; yi = yc + mx*(xi-xc); ok = IsInside(xi,yi,x,y,xc,yc,xl,xr,yl,yr); if (!ok) { yi = yle; xi = xc + my*(yi-yc); ok = IsInside(xi,yi,x,y,xc,yc,xl,xr,yl,yr); if (!ok) { yi = yre; xi = xc + my*(yi-yc); ok = IsInside(xi,yi,x,y,xc,yc,xl,xr,yl,yr); }//end if (!ok) }//end if (!ok) }//end if (!ok) if (ok) { kx = Int_t((xi-dxs2)/dx) + 1; ky = Int_t((yi-dys2)/dy) + 1; } else { cout << "TZigZag::PointsNear : ERROR point inside not found" << endl; } }//end else if ((x>xl) && (x<xr) && (y>yl) && (y<yr)) if (ok) { //Point kx,ky xp = dxs2 + (kx-1)*dx; yp = dys2 + (ky-1)*dy; i = NToZZ(kx,ky); Ii[0] = i; Ti[0] = T(i); Xi[0] = xp; Yi[0] = yp; //Point kx+1,ky xp = dxs2 + kx*dx; yp = dys2 + (ky-1)*dy; i = NToZZ(kx+1,ky); Ii[1] = i; Ti[1] = T(i); Xi[1] = xp; Yi[1] = yp; //Point kx,ky+1 xp = dxs2 + (kx-1)*dx; yp = dys2 + ky*dy; i = NToZZ(kx,ky+1); Ii[2] = i; Ti[2] = T(i); Xi[2] = xp; Yi[2] = yp; //Point kx+1,ky+1 xp = dxs2 + kx*dx; yp = dys2 + ky*dy; i = NToZZ(kx+1,ky+1); Ii[3] = i; Ti[3] = T(i); Xi[3] = xp; Yi[3] = yp; //Finding the 2 points along the zigzag Order(4,Ii,Ti,Xi,Yi); Yn[0] = Yi[0]; Tn[0] = Ti[0] + ((Ti[1] - Ti[0])/(Xi[1] -Xi[0]))*(xi - Xi[0]); Yn[1] = Yi[2]; Tn[1] = Ti[2] + ((Ti[3] - Ti[2])/(Xi[3] -Xi[2]))*(xi - Xi[2]); } return ok; }
Bool_t TZigZag::NearestPoints(Double_t x, Double_t y, Double_t z, TArrayI &I, TArrayD &W) const { // 3-dimensional case. Gives the 8 nearest points from point x in zigzag numbering. //W are weights for the points, calculated according to the inverse of their distances //from x. If point (x,y) not inside [fXmin,fXmax],[fYmin,fYmax],[fZmin,fZmax], make a //projection towards center and stops at point just after entry and gives the 8 points //for it. const Double_t un = 1.0; const Double_t aeps = 1.0e-6; Bool_t ok; Int_t i; Int_t kx=0; Int_t ky=0; Int_t kz=0; Double_t mx,my,mz,eps; Double_t xc,xl,xr,dx,dxs2; Double_t yc,yl,yr,dy,dys2; Double_t zc,zl,zr,dz,dzs2; Double_t xi,yi,zi,ti,xp,yp,zp; Double_t xle,xre,yle,yre,zle,zre; Double_t w0,w1,w2,w3,w4,w5,w6,w7,wt; I.Set(8); W.Set(8); for (i=0;i<8;i++) { I[i] = -1; W[i] = -un; } dx = (fXmax-fXmin)/fNx; dxs2 = dx/2; dy = (fYmax-fYmin)/fNy; dys2 = dy/2; dz = (fZmax-fZmin)/fNy; dzs2 = dz/2; xl = dxs2; xr = dxs2 + (fNx-1)*dx; yl = dys2; yr = dys2 + (fNy-1)*dy; zl = dzs2; zr = dzs2 + (fNz-1)*dz; w0 = xr - xl; w1 = yr - yl; w2 = zr - zl; w0 = TMath::Max(w0,w1); w0 = TMath::Max(w0,w2); eps = aeps*w0; if ((x>=xl) && (x<=xr) && (y>=yl) && (y<=yr) && (z>=zl) && (z<=zr)) { xi = x; yi = y; zi = z; kx = Int_t((xi-dxs2)/dx) + 1; ky = Int_t((yi-dys2)/dy) + 1; kz = Int_t((zi-dzs2)/dz) + 1; ok = kTRUE; }//end if ((x>xl) && (x<xr) && (y>yl) && (y<yr) && (z>zl) && (z<zr)) else { xc = (fXmax-fXmin)/2; yc = (fYmax-fYmin)/2; zc = (fZmax-fZmin)/2; xle = xl + eps; xre = xr - eps; yle = yl + eps; yre = yr - eps; zle = zl + eps; zre = zr - eps; mx = x - xc; my = y - yc; mz = z - zc; //intercept with xle xi = xle; ti = (xi-xc)/mx; yi = yc + my*ti; zi = zc + mz*ti; ok = IsInside(xi,yi,zi,x,y,z,xc,yc,zc,xl,xr,yl,yr,zl,zr); if (!ok) { //intercept with xre xi = xre; ti = (xi-xc)/mx; yi = yc + my*ti; zi = zc + mz*ti; ok = IsInside(xi,yi,zi,x,y,z,xc,yc,zc,xl,xr,yl,yr,zl,zr); if (!ok) { //intercept with yle yi = yle; ti = (yi-yc)/my; xi = xc + mx*ti; zi = zc + mz*ti; ok = IsInside(xi,yi,zi,x,y,z,xc,yc,zc,xl,xr,yl,yr,zl,zr); if (!ok) { //intercept with yre yi = yre; ti = (yi-yc)/my; xi = xc + mx*ti; zi = zc + mz*ti; ok = IsInside(xi,yi,zi,x,y,z,xc,yc,zc,xl,xr,yl,yr,zl,zr); if (!ok) { //intercept with zle zi = zle; ti = (zi-zc)/mz; xi = xc + mx*ti; yi = yc + my*ti; ok = IsInside(xi,yi,zi,x,y,z,xc,yc,zc,xl,xr,yl,yr,zl,zr); if (!ok) { //intercept with zre zi = zre; ti = (zi-zc)/mz; xi = xc + mx*ti; yi = yc + my*ti; ok = IsInside(xi,yi,zi,x,y,z,xc,yc,zc,xl,xr,yl,yr,zl,zr); }//end if (!ok) intercept with zre }//end if (!ok) intercept with zle }//end if (!ok) intercept with yre }//end if (!ok) intercept with yle }//end if (!ok) intercept with xre if (ok) { kx = Int_t((xi-dxs2)/dx) + 1; ky = Int_t((yi-dys2)/dy) + 1; kz = Int_t((zi-dzs2)/dz) + 1; } else { cout << "TZigZag::NearestPoints : ERROR point inside not found" << endl; } }//end else if ((x>xl) && (x<xr) && (y>yl) && (y<yr) && (z>zl) && (z<zr)) if (ok) { Double_t fx,fy,fz; //Point kx,ky,kz xp = dxs2 + (kx-1)*dx; yp = dys2 + (ky-1)*dy; zp = dzs2 + (kz-1)*dz; fx = x - xp; fy = y - yp; fz = z - zp; i = NToZZ(kx,ky,kz); I[0] = i; w0 = TMath::Sqrt(fx*fx + fy*fy + fz*fz) + eps; w0 = un/w0; //Point kx+1,ky,kz xp = dxs2 + kx*dx; yp = dys2 + (ky-1)*dy; zp = dzs2 + (kz-1)*dz; fx = x - xp; fy = y - yp; fz = z - zp; i = NToZZ(kx+1,ky,kz); I[1] = i; w1 = TMath::Sqrt(fx*fx + fy*fy + fz*fz) + eps; w1 = un/w1; //Point kx,ky+1,kz xp = dxs2 + (kx-1)*dx; yp = dys2 + ky*dy; zp = dzs2 + (kz-1)*dz; fx = x - xp; fy = y - yp; fz = z - zp; i = NToZZ(kx,ky+1,kz); I[2] = i; w2 = TMath::Sqrt(fx*fx + fy*fy + fz*fz) + eps; w2 = un/w2; //Point kx+1,ky+1,kz xp = dxs2 + kx*dx; yp = dys2 + ky*dy; zp = dzs2 + (kz-1)*dz; fx = x - xp; fy = y - yp; fz = z - zp; i = NToZZ(kx+1,ky+1,kz); I[3] = i; w3 = TMath::Sqrt(fx*fx + fy*fy + fz*fz) + eps; w3 = un/w3; //Point kx,ky,kz+1 xp = dxs2 + (kx-1)*dx; yp = dys2 + (ky-1)*dy; zp = dzs2 + kz*dz; fx = x - xp; fy = y - yp; fz = z - zp; i = NToZZ(kx,ky,kz+1); I[4] = i; w4 = TMath::Sqrt(fx*fx + fy*fy + fz*fz) + eps; w4 = un/w4; //Point kx+1,ky,kz+1 xp = dxs2 + kx*dx; yp = dys2 + (ky-1)*dy; zp = dzs2 + kz*dz; fx = x - xp; fy = y - yp; fz = z - zp; i = NToZZ(kx+1,ky,kz+1); I[5] = i; w5 = TMath::Sqrt(fx*fx + fy*fy + fz*fz) + eps; w5 = un/w5; //Point kx,ky+1,kz+1 xp = dxs2 + (kx-1)*dx; yp = dys2 + ky*dy; zp = dzs2 + kz*dz; fx = x - xp; fy = y - yp; fz = z - zp; i = NToZZ(kx,ky+1,kz+1); I[6] = i; w6 = TMath::Sqrt(fx*fx + fy*fy + fz*fz) + eps; w6 = un/w6; //Point kx+1,ky+1,kz+1 xp = dxs2 + kx*dx; yp = dys2 + ky*dy; zp = dzs2 + kz*dz; fx = x - xp; fy = y - yp; fz = z - zp; i = NToZZ(kx+1,ky+1,kz+1); I[7] = i; w7 = TMath::Sqrt(fx*fx + fy*fy + fz*fz) + eps; w7 = un/w7; // wt = w0 + w1 + w2 + w3 + w4 + w5 + w6 + w7; W[0] = w0/wt; W[1] = w1/wt; W[2] = w2/wt; W[3] = w3/wt; W[4] = w4/wt; W[5] = w5/wt; W[6] = w6/wt; W[7] = w7/wt; } return ok; }