/* Get_sep: Calculates the separation between two satellites along the satellite beam, in the normal- and parallel- to look direction. Inputs are: a state vector from scene 1, in GEI coordinates; the name of the ceos for image 2; the slant range and doppler of the center of the beam; and pointers to the output normal and parallel baselines. */ void get_sep(stateVector stVec1, meta_parameters *meta2, double range, double dop,double *Bn,double *Bp) { double lat,phi,earthRadius; vector target,up,relPos; vector upBeam,alongBeam,beamNormal; double t,timeDelta; stateVector stVec2; GEOLOCATE_REC *g; /*Target is the patch of ground at beam center.*/ /*Initialize the transformation.*/ g=init_geolocate_meta(&stVec1,meta2); getLoc(g,range,dop, &lat,&phi,&earthRadius); free_geolocate(g); sph2cart(earthRadius,lat,phi,&target); /*Create beam plane unit vectors.*/ vecSub(stVec1.pos,target,&alongBeam); vecNormalize(&alongBeam); up=stVec1.pos; vecNormalize(&up); vecCross(up,alongBeam,&beamNormal); vecNormalize(&beamNormal); vecCross(alongBeam,beamNormal,&upBeam); vecNormalize(&upBeam); /*Find the time when the second satellite crosses the first's beam.*/ t=0.0; stVec2=meta_get_stVec(meta2,t); timeDelta=1.0; while (fabs(timeDelta)>0.00001) { vecSub(stVec1.pos,stVec2.pos,&relPos); timeDelta=vecDot(beamNormal,relPos)/vecDot(beamNormal,stVec2.vel); t+=timeDelta; if (!quietflag) { printf(" Time=%f sec, delta=%f sec\n",t,timeDelta); printf(" Distance from beam plane=%f m\n",vecDot(beamNormal,relPos)); } stVec2=meta_get_stVec(meta2,t); } /*Now we have the second satellite sitting in the plane of the first's beam, so we just separate that position into components along-beam and across-beam, and return.*/ vecSub(stVec2.pos,stVec1.pos,&relPos); *Bp=vecDot(alongBeam,relPos); *Bn=vecDot(upBeam,relPos); }
void scan_to_latlon(meta_parameters *meta, double x, double y, double z, double *lat_d, double *lon, double *height) { double qlat, qlon; double lat,radius; vector pos; meta_projection *proj = meta->projection; if (z != 0.0) { // height correction applies directly to y (range direction) double line, samp; line = (y-proj->startY)/proj->perY - meta->general->start_line; samp = (x-proj->startX)/proj->perX - meta->general->start_sample; double sr = meta_get_slant(meta,line,samp); double er = proj->param.atct.rlocal; double ht = meta_get_sat_height(meta,line,samp); double cos_ang = (sr*sr + er*er - ht*ht)/(2.0*sr*er); if (cos_ang > 1) cos_ang = 1; if (cos_ang < -1) cos_ang = -1; double incid = PI-acos(cos_ang); x += z*tan(PI/2-incid); } if (meta->sar->look_direction=='R') qlat = -x/proj->param.atct.rlocal; /* Right looking sar */ else qlat = x/proj->param.atct.rlocal; /* Left looking sar */ qlon = y/(proj->param.atct.rlocal*cos(qlat)); sph2cart(proj->param.atct.rlocal, qlat, qlon, &pos); rotate_z(&pos,-proj->param.atct.alpha3); rotate_y(&pos,-proj->param.atct.alpha2); rotate_z(&pos,-proj->param.atct.alpha1); cart2sph(pos,&radius,&lat,lon); *lon *= R2D; lat *= R2D; *lat_d = atand(tand(lat) / (1-ecc2(proj->re_minor,proj->re_major))); *height = z; // FIXME: Do we need to correct the height at all? }
static void ll_ac(meta_projection *proj, char look_dir, double lat_r, double lon, double *c1, double *c2) { double qlat, qlon; double lat,radius; vector pos; lat = atan(tan(lat_r)*(1 - ecc2(proj->re_minor,proj->re_major))); sph2cart(proj->param.atct.rlocal,lat,lon,&pos); rotate_z(&pos,proj->param.atct.alpha1); rotate_y(&pos,proj->param.atct.alpha2); rotate_z(&pos,proj->param.atct.alpha3); cart2sph(pos,&radius,&qlat,&qlon); *c1 = qlon*proj->param.atct.rlocal*cos(qlat); if (look_dir=='R') *c2 = -1.0*qlat*proj->param.atct.rlocal; /* right looking */ else *c2 = qlat * proj->param.atct.rlocal; /* left looking */ }
/** Kernel L2P operation * r += Op(L, t) where L is the local expansion and r is the result * * @param[in] L The local expansion * @param[in] center The center of the box with the local expansion * @param[in] target The target of this L2P operation * @param[in] result The result to accumulate into * @pre L includes the influence of all sources outside its box */ void L2P(const local_type& L, const point_type& center, const target_type& target, result_type& result) const { complex Ynm[4*P*P], YnmTheta[4*P*P]; point_type dist = target - center; point_type gradient[4]; // = {0.,0.,0.,0.}; gradient[0] = point_type(0.); gradient[1] = point_type(0.); gradient[2] = point_type(0.); gradient[3] = point_type(0.); point_type cartesian(0); real r, theta, phi; cart2sph(r,theta,phi,dist); evalMultipole(r,theta,phi,Ynm,YnmTheta); #ifdef STRESSLET double scale = 1./6; #else double scale = 1.; #endif for( int n=0; n!=P; ++n ) { int nm = n * n + n; int nms = n * (n + 1) / 2; result[0] += scale*std::real(L[0][nms] * Ynm[nm]); result[1] += scale*std::real(L[1][nms] * Ynm[nm]); result[2] += scale*std::real(L[2][nms] * Ynm[nm]); real factor = 1. / r * n; gradient[0][0] += std::real(L[0][nms] * Ynm[nm]) * factor; gradient[0][1] += std::real(L[0][nms] * YnmTheta[nm]); gradient[1][0] += std::real(L[1][nms] * Ynm[nm]) * factor; gradient[1][1] += std::real(L[1][nms] * YnmTheta[nm]); gradient[2][0] += std::real(L[2][nms] * Ynm[nm]) * factor; gradient[2][1] += std::real(L[2][nms] * YnmTheta[nm]); gradient[3][0] += std::real(L[3][nms] * Ynm[nm]) * factor; gradient[3][1] += std::real(L[3][nms] * YnmTheta[nm]); for( int m=1; m<=n; ++m ) { nm = n * n + n + m; nms = n * (n + 1) / 2 + m; result[0] += scale * 2 * std::real(L[0][nms] * Ynm[nm]); result[1] += scale * 2 * std::real(L[1][nms] * Ynm[nm]); result[2] += scale * 2 * std::real(L[2][nms] * Ynm[nm]); gradient[0][0] += 2 * std::real(L[0][nms] * Ynm[nm]) * factor; gradient[0][1] += 2 * std::real(L[0][nms] * YnmTheta[nm]); gradient[0][2] += 2 * std::real(L[0][nms] * Ynm[nm] * CI) * m; gradient[1][0] += 2 * std::real(L[1][nms] * Ynm[nm]) * factor; gradient[1][1] += 2 * std::real(L[1][nms] * YnmTheta[nm]); gradient[1][2] += 2 * std::real(L[1][nms] * Ynm[nm] * CI) * m; gradient[2][0] += 2 * std::real(L[2][nms] * Ynm[nm]) * factor; gradient[2][1] += 2 * std::real(L[2][nms] * YnmTheta[nm]); gradient[2][2] += 2 * std::real(L[2][nms] * Ynm[nm] * CI) * m; gradient[3][0] += 2 * std::real(L[3][nms] * Ynm[nm]) * factor; gradient[3][1] += 2 * std::real(L[3][nms] * YnmTheta[nm]); gradient[3][2] += 2 * std::real(L[3][nms] * Ynm[nm] * CI) * m; } } sph2cart(r,theta,phi,gradient[0],cartesian); cartesian *= -target[0]; gradient[0] = cartesian; sph2cart(r,theta,phi,gradient[1],cartesian); cartesian *= -target[1]; gradient[1] = cartesian; sph2cart(r,theta,phi,gradient[2],cartesian); cartesian *= -target[2]; gradient[2] = cartesian; sph2cart(r,theta,phi,gradient[3],cartesian); gradient[3] = cartesian; result[0] += scale*(gradient[0][0]+gradient[1][0]+gradient[2][0]+gradient[3][0]); result[1] += scale*(gradient[0][1]+gradient[1][1]+gradient[2][1]+gradient[3][1]); result[2] += scale*(gradient[0][2]+gradient[1][2]+gradient[2][2]+gradient[3][2]); }