Exemplo n.º 1
0
/*
  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);
}
Exemplo n.º 2
0
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?
}
Exemplo n.º 3
0
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]);
  }