Beispiel #1
0
int dihf(float x, float y, float z, float *d, float *i, 
          float *h, float *f) {
   
    float h2;
    float sn, hpx;

    sn = (float)1e-4;

    h2 = x * x + y * y;
    *h = sqrt(h2);
    *f = sqrt(h2 + z * z);
    if (*f < sn) {
	*d = (float)999.;
	*i = (float)999.;
    } else {
	*i = atan2d(z,*h);

	if (*h < sn) {
	    *d = (float)999.;
	} else {
	    hpx = *h + x;
	    if (hpx < sn) {
		*d = (float) 180.;
	    } else {
		*d = atan2d(y,hpx) * (float)2.;
	    }
	}
    }
    return 0;
} 
Beispiel #2
0
static void astro_sunpos(double d, double *lon, double *r)
{
	double M,         /* Mean anomaly of the Sun */
	       w,         /* Mean longitude of perihelion */
	                  /* Note: Sun's mean longitude = M + w */
	       e,         /* Eccentricity of Earth's orbit */
	       E,         /* Eccentric anomaly */
	       x, y,      /* x, y coordinates in orbit */
	       v;         /* True anomaly */

	/* Compute mean elements */
	M = astro_revolution(356.0470 + 0.9856002585 * d);
	w = 282.9404 + 4.70935E-5 * d;
	e = 0.016709 - 1.151E-9 * d;

	/* Compute true longitude and radius vector */
	E = M + e * RADEG * sind(M) * (1.0 + e * cosd(M));
	x = cosd(E) - e;
	y = sqrt(1.0 - e*e) * sind(E);
	*r = sqrt(x*x + y*y);              /* Solar distance */
	v = atan2d(y, x);                  /* True anomaly */
	*lon = v + w;                        /* True solar longitude */
	if (*lon >= 360.0) {
		*lon -= 360.0;                   /* Make it 0..360 degrees */
	}
}
Beispiel #3
0
void sunpos( double d, double *lon, double *r )
/******************************************************/
/* Computes the Sun's ecliptic longitude and distance */
/* at an instant given in d, number of days since     */
/* 2000 Jan 0.0.  The Sun's ecliptic latitude is not  */
/* computed, since it's always very near 0.           */
/******************************************************/
{
    double M,         /* Mean anomaly of the Sun */
    w,         /* Mean longitude of perihelion */
    /* Note: Sun's mean longitude = M + w */
    e,         /* Eccentricity of Earth's orbit */
    E,         /* Eccentric anomaly */
    x, y,      /* x, y coordinates in orbit */
    v;         /* True anomaly */
    
    /* Compute mean elements */
    M = revolution( 356.0470 + 0.9856002585 * d );
    w = 282.9404 + 4.70935E-5 * d;
    e = 0.016709 - 1.151E-9 * d;
    
    /* Compute true longitude and radius vector */
    E = M + e * RADEG * sind(M) * ( 1.0 + e * cosd(M) );
    x = cosd(E) - e;
    y = sqrt( 1.0 - e*e ) * sind(E);
    *r = sqrt( x*x + y*y );              /* Solar distance */
    v = atan2d( y, x );                  /* True anomaly */
    *lon = v + w;                        /* True solar longitude */
    if ( *lon >= 360.0 )
        *lon -= 360.0;                   /* Make it 0..360 degrees */
}
Beispiel #4
0
void fldpnt(double rrho,double rlat,double rlon,double ral,
			double rel,double r,double *frho,double *flat,
                        double *flon) {

   double rx,ry,rz,sx,sy,sz,tx,ty,tz;
   double sinteta;
  
   /* convert from global spherical to global cartesian*/

   sinteta=sind(90.0-rlat);
   rx=rrho*sinteta*cosd(rlon);
   ry=rrho*sinteta*sind(rlon);
   rz=rrho*cosd(90.0-rlat);

   sx=-r*cosd(rel)*cosd(ral);
   sy=r*cosd(rel)*sind(ral);
   sz=r*sind(rel);

   tx  =  cosd(90.0-rlat)*sx + sind(90.0-rlat)*sz;
   ty  =  sy;
   tz  = -sind(90.0-rlat)*sx + cosd(90.0-rlat)*sz;
   sx  =  cosd(rlon)*tx - sind(rlon)*ty;
   sy  =  sind(rlon)*tx + cosd(rlon)*ty;
   sz  =  tz;

   tx=rx+sx;
   ty=ry+sy;
   tz=rz+sz;

   /* convert from cartesian back to global spherical*/
   *frho=sqrt((tx*tx)+(ty*ty)+(tz*tz));
   *flat=90.0-acosd(tz/(*frho));
   if ((tx==0) && (ty==0)) *flon=0;
   else *flon=atan2d(ty,tx);
}
Beispiel #5
0
int RPosRngBmAzmElv(int bm,int rn,int year,
                     struct RadarSite *hdw,double frang,
                     double rsep,double rx,double height,
                     double *azm,double *elv) {

  double flat,flon,frho;
  double fx,fy,fz;

  double gx,gy,gz;
  double glat,glon;
  double gdlat,gdlon,gdrho;
  double gbx,gby,gbz; 
  double ghx,ghy,ghz;
  double bx,by,bz,b;
  double dummy;
  int s;
 
  gdlat=hdw->geolat;
  gdlon=hdw->geolon;

  if (rx==0) rx=hdw->recrise;

  RPosGeo(1,bm,rn,hdw,frang,rsep,rx,
             height,&frho,&flat,&flon);

  sphtocar(frho,flat,flon,&fx,&fy,&fz);       
  geodtgc(1,&gdlat,&gdlon,&gdrho,&glat,&glon,&dummy);
  sphtocar(gdrho,glat,glon,&gbx,&gby,&gbz);       
  gx=fx-gbx;
  gy=fy-gby;
  gz=fz-gbz;     
  norm_vec(&gx,&gy,&gz);
  glbthor(1,flat,flon,&gx,&gy,&gz,&ghx,&ghy,&ghz);
  norm_vec(&ghx,&ghy,&ghz);
            
  s=IGRFMagCmp(year,frho,flat,flon,&bx,&by,&bz,&b);
  if (s==-1) return -1;
  
  norm_vec(&bx,&by,&bz);
  ghz=-(bx*ghx+by*ghy)/bz;
  norm_vec(&ghx,&ghy,&ghz);
  *elv=atan2d(ghz,sqrt(ghx*ghx+ghy*ghy));
  *azm=atan2d(ghy,-ghx);
  return 0;
}
Beispiel #6
0
/***********************************************************************//**
 * @brief Cartesian-to-spherical deprojection
 *
 * @param[in] nx X vector length.
 * @param[in] ny Y vector length (0=no replication).
 * @param[in] sxy Input vector step.
 * @param[in] spt Output vector step.
 * @param[in] x Vector of projected x coordinates.
 * @param[in] y Vector of projected y coordinates.
 * @param[out] phi Longitude of the projected point in native spherical
 *                 coordinates [deg].
 * @param[out] theta Latitude of the projected point in native spherical
 *                   coordinates [deg].
 * @param[out] stat Status return value for each vector element (always 0)
 *
 * Deproject Cartesian (x,y) coordinates in the plane of projection to native
 * spherical coordinates (phi,theta).
 *
 * This method has been adapted from the wcslib function prj.c::carx2s().
 * The interface follows very closely that of wcslib. In contrast to the
 * wcslib routine, however, the method assumes that the projection has been
 * setup previsouly (as this will be done by the constructor).
 ***************************************************************************/
void GWcsSTG::prj_x2s(int nx, int ny, int sxy, int spt, 
                      const double* x, const double* y,
                      double* phi, double* theta, int* stat) const
{
    // Initialize projection if required
    if (!m_prjset)
        prj_set();

    // Set value replication length mx,my
    int mx;
    int my;
    if (ny > 0) {
        mx = nx;
        my = ny;
    } 
    else {
        mx = 1;
        my = 1;
        ny = nx;
    }
    
    // Do x dependence
    const double* xp     = x;
    int           rowoff = 0;
    int           rowlen = nx * spt;
    for (int ix = 0; ix < nx; ++ix, rowoff += spt, xp += sxy) {
        double  xj   = *xp + m_x0;
        double* phip = phi + rowoff;
        for (int iy = 0; iy < my; ++iy, phip += rowlen)
            *phip = xj;
    }

    // Do y dependence
    const double* yp     = y;
    double*       phip   = phi;
    double*       thetap = theta;
    int*          statp  = stat;
    for (int iy = 0; iy < ny; ++iy, yp += sxy) {
        double yj  = *yp + m_y0;
        double yj2 = yj*yj;
        for (int ix = 0; ix < mx; ++ix, phip += spt, thetap += spt) {
            double xj = *phip;
            double r  = sqrt(xj*xj + yj2);
            if (r == 0.0)
                *phip = 0.0;
            else
                *phip = atan2d(xj, -yj);
            *thetap    = 90.0 - 2.0*atand(r*m_w[1]);
            *(statp++) = 0;
        }
    }

    // Return
    return;
}
/*
** The GSM to SM transformation is given by the matrix
**	T4 = <- mu,Y>
**
** where the rotation angle mu is the dipole tilt. This transformation 
** is a rotation in the GSM XZ plane from the GSM Z axis to the 
** geomagnetic dipole axis. 
*/
void
mat_T4(const double et, Mat mat)
{
  Vec Qe;
  double mu;

  vec_Qe(et, Qe);

  mu = atan2d(Qe[0], sqrt(Qe[1]*Qe[1] + Qe[2]*Qe[2]));

  hapgood_matrix(-mu, Y, mat);
}
/*
** The GSE to GSM transformation is given by the matrix
**
**	T3 = <-psi,X>
**
** where the rotation angle psi is the the GSE-GSM angle. This
** transformation is a rotation in the GSE YZ plane from the GSE Z axis
** to the GSM Z axis. 
*/
void
mat_T3(const double et, Mat mat)
{
  Vec Qe;
  double psi;

  vec_Qe(et, Qe);

  psi = atan2d(Qe[1], Qe[2]);

  hapgood_matrix(-psi, X, mat);
}
Beispiel #9
0
static void astro_sun_RA_dec(double d, double *RA, double *dec, double *r)
{
	double lon, obl_ecl, x, y, z;

	/* Compute Sun's ecliptical coordinates */
	astro_sunpos(d, &lon, r);

	/* Compute ecliptic rectangular coordinates (z=0) */
	x = *r * cosd(lon);
	y = *r * sind(lon);

	/* Compute obliquity of ecliptic (inclination of Earth's axis) */
	obl_ecl = 23.4393 - 3.563E-7 * d;

	/* Convert to equatorial rectangular coordinates - x is unchanged */
	z = y * sind(obl_ecl);
	y = y * cosd(obl_ecl);

	/* Convert to spherical coordinates */
	*RA = atan2d(y, x);
	*dec = atan2d(z, sqrt(x*x + y*y));
}
Beispiel #10
0
void geocnvrt(double gdlat,double gdlon,
			  double xal,double xel,double *ral,double *rel) {

  double kxg,kyg,kzg,kxr,kyr,kzr;
  double rrad,rlat,rlon,del;

  kxg=cosd(xel)*sind(xal);
  kyg=cosd(xel)*cosd(xal);
  kzg=sind(xel);
  geodtgc(1,&gdlat,&gdlon,&rrad,&rlat,&rlon,&del);
  kxr=kxg;
  kyr=kyg*cosd(del)+kzg*sind(del);
  kzr=-kyg*sind(del)+kzg*cosd(del);

  *ral=atan2d(kxr,kyr);
  *rel=atand(kzr/sqrt((kxr*kxr)+(kyr*kyr)));
}
Beispiel #11
0
int RPosInvMag(int bm,int rn,int year,struct RadarSite *hdw,double frang,
             double rsep,double rx,double height,
             double *mlat,double *mlon,double *azm) {

  double flat,flon,frho;
  double fx,fy,fz;

  double gx,gy,gz;
  double glat,glon;
  double gdlat,gdlon,gdrho;
  double gbx,gby,gbz; 
  double ghx,ghy,ghz;
  double bx,by,bz,b;
  double dummy,elv,azc;

  double tmp_ht;
  double xlat,xlon,nlat,nlon;
  int s;

  gdlat=hdw->geolat;
  gdlon=hdw->geolon;

  if (rx==0) rx=hdw->recrise;

  RPosGeo(1,bm,rn,hdw,frang,rsep,rx,
             height,&frho,&flat,&flon);

  sphtocar(frho,flat,flon,&fx,&fy,&fz);       
  geodtgc(1,&gdlat,&gdlon,&gdrho,&glat,&glon,&dummy);
  sphtocar(gdrho,glat,glon,&gbx,&gby,&gbz);       
  gx=fx-gbx;
  gy=fy-gby;
  gz=fz-gbz;     
  norm_vec(&gx,&gy,&gz);
  glbthor(1,flat,flon,&gx,&gy,&gz,&ghx,&ghy,&ghz);
  norm_vec(&ghx,&ghy,&ghz);

  s=IGRFMagCmp(year,frho,flat,flon,&bx,&by,&bz,&b);
  if (s==-1) return -1;
  
  norm_vec(&bx,&by,&bz);
  ghz=-(bx*ghx+by*ghy)/bz;
  norm_vec(&ghx,&ghy,&ghz);
  elv=atan2d(ghz,sqrt(ghx*ghx+ghy*ghy));
  azc=atan2d(ghy,-ghx);
      
  geodtgc(-1,&gdlat,&gdlon,&gdrho,&flat,&flon,&dummy);
  tmp_ht=frho-gdrho;
   
  AACGMConvert(flat,flon,tmp_ht,mlat,mlon,&dummy,0);
        
  fldpnt_sph(frho,flat,flon,azc,rsep,&xlat,&xlon);
      
  s=AACGMConvert(xlat,xlon,tmp_ht,&nlat,&nlon,&dummy,0);
  if (s==-1) return -1;
       
  if ((nlon-*mlon) > 180)  nlon=nlon-360;
  if ((nlon-*mlon) < -180) nlon=nlon+360;

  fldpnt_azm(*mlat,*mlon,nlat,nlon,azm);      
  return 0;
}
Beispiel #12
0
int sphx2s(
  const double eul[5],
  int nphi,
  int ntheta,
  int spt,
  int sll,
  const double phi[],
  const double theta[],
  double lng[],
  double lat[])

{
  int mphi, mtheta, rowlen, rowoff;
  double cosphi, costhe, costhe3, costhe4, dlng, dphi, sinphi, sinthe,
         sinthe3, sinthe4, x, y, z;
  register int iphi, itheta;
  register const double *phip, *thetap;
  register double *latp, *lngp;

  if (ntheta > 0) {
    mphi   = nphi;
    mtheta = ntheta;
  } else {
    mphi   = 1;
    mtheta = 1;
    ntheta = nphi;
  }


  /* Check for a simple change in origin of longitude. */
  if (eul[4] == 0.0) {
    if (eul[1] == 0.0) {
      dlng = fmod(eul[0] + 180.0 - eul[2], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (itheta = 0; itheta < ntheta; itheta++) {
        for (iphi = 0; iphi < mphi; iphi++) {
          *lngp = *phip + dlng;
          *latp = *thetap;

          /* Normalize the celestial longitude. */
          if (eul[0] >= 0.0) {
            if (*lngp < 0.0) *lngp += 360.0;
          } else {
            if (*lngp > 0.0) *lngp -= 360.0;
          }

          if (*lngp > 360.0) {
            *lngp -= 360.0;
          } else if (*lngp < -360.0) {
            *lngp += 360.0;
          }

          lngp   += sll;
          latp   += sll;
          phip   += spt;
          thetap += spt;
        }
      }

    } else {
      dlng = fmod(eul[0] + eul[2], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (itheta = 0; itheta < ntheta; itheta++) {
        for (iphi = 0; iphi < mphi; iphi++) {
          *lngp = dlng - *phip;
          *latp = -(*thetap);

          /* Normalize the celestial longitude. */
          if (eul[0] >= 0.0) {
            if (*lngp < 0.0) *lngp += 360.0;
          } else {
            if (*lngp > 0.0) *lngp -= 360.0;
          }

          if (*lngp > 360.0) {
            *lngp -= 360.0;
          } else if (*lngp < -360.0) {
            *lngp += 360.0;
          }

          lngp   += sll;
          latp   += sll;
          phip   += spt;
          thetap += spt;
        }
      }
    }

    return 0;
  }


  /* Do phi dependency. */
  phip = phi;
  rowoff = 0;
  rowlen = nphi*sll;
  for (iphi = 0; iphi < nphi; iphi++, rowoff += sll, phip += spt) {
    dphi = *phip - eul[2];

    lngp = lng + rowoff;
    for (itheta = 0; itheta < mtheta; itheta++) {
      *lngp = dphi;
      lngp += rowlen;
    }
  }


  /* Do theta dependency. */
  thetap = theta;
  lngp = lng;
  latp = lat;
  for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) {
    sincosd(*thetap, &sinthe, &costhe);
    costhe3 = costhe*eul[3];
    costhe4 = costhe*eul[4];
    sinthe3 = sinthe*eul[3];
    sinthe4 = sinthe*eul[4];

    for (iphi = 0; iphi < mphi; iphi++, lngp += sll, latp += sll) {
      dphi = *lngp;
      sincosd(dphi, &sinphi, &cosphi);

      /* Compute the celestial longitude. */
      x = sinthe4 - costhe3*cosphi;
      if (fabs(x) < tol) {
        /* Rearrange formula to reduce roundoff errors. */
        x = -cosd(*thetap + eul[1]) + costhe3*(1.0 - cosphi);
      }

      y = -costhe*sinphi;
      if (x != 0.0 || y != 0.0) {
        dlng = atan2d(y, x);
      } else {
        /* Change of origin of longitude. */
        if (eul[1] < 90.0) {
          dlng =  dphi + 180.0;
        } else {
          dlng = -dphi;
        }
      }
      *lngp = eul[0] + dlng;

      /* Normalize the celestial longitude. */
      if (eul[0] >= 0.0) {
        if (*lngp < 0.0) *lngp += 360.0;
      } else {
        if (*lngp > 0.0) *lngp -= 360.0;
      }

      if (*lngp > 360.0) {
        *lngp -= 360.0;
      } else if (*lngp < -360.0) {
        *lngp += 360.0;
      }

      /* Compute the celestial latitude. */
      if (fmod(dphi,180.0) == 0.0) {
        *latp = *thetap + cosphi*eul[1];
        if (*latp >  90.0) *latp =  180.0 - *latp;
        if (*latp < -90.0) *latp = -180.0 - *latp;
      } else {
        z = sinthe3 + costhe4*cosphi;
        if (fabs(z) > 0.99) {
          /* Use an alternative formula for greater accuracy. */
          *latp = copysign(acosd(sqrt(x*x+y*y)), z);
        } else {
          *latp = asind(z);
        }
      }
    }
  }

  return 0;
}
Beispiel #13
0
int sphs2x(
  const double eul[5],
  int nlng,
  int nlat,
  int sll,
  int spt,
  const double lng[],
  const double lat[],
  double phi[],
  double theta[])

{
  int mlat, mlng, rowlen, rowoff;
  double coslat, coslat3, coslat4, coslng, dlng, dphi, sinlat, sinlat3,
         sinlat4, sinlng, x, y, z;
  register int ilat, ilng;
  register const double *latp, *lngp;
  register double *phip, *thetap;

  if (nlat > 0) {
    mlng = nlng;
    mlat = nlat;
  } else {
    mlng = 1;
    mlat = 1;
    nlat = nlng;
  }


  /* Check for a simple change in origin of longitude. */
  if (eul[4] == 0.0) {
    if (eul[1] == 0.0) {
      dphi = fmod(eul[2] - 180.0 - eul[0], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (ilat = 0; ilat < nlat; ilat++) {
        for (ilng = 0; ilng < mlng; ilng++) {
          *phip = fmod(*lngp + dphi, 360.0);
          *thetap = *latp;

          /* Normalize the native longitude. */
          if (*phip > 180.0) {
            *phip -= 360.0;
          } else if (*phip < -180.0) {
            *phip += 360.0;
          }

          phip   += spt;
          thetap += spt;
          lngp   += sll;
          latp   += sll;
        }
      }

    } else {
      dphi = fmod(eul[2] + eul[0], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (ilat = 0; ilat < nlat; ilat++) {
        for (ilng = 0; ilng < mlng; ilng++) {
          *phip = fmod(dphi - *lngp, 360.0);
          *thetap = -(*latp);

          /* Normalize the native longitude. */
          if (*phip > 180.0) {
            *phip -= 360.0;
          } else if (*phip < -180.0) {
            *phip += 360.0;
          }

          phip   += spt;
          thetap += spt;
          lngp   += sll;
          latp   += sll;
        }
      }
    }

    return 0;
  }


  /* Do lng dependency. */
  lngp = lng;
  rowoff = 0;
  rowlen = nlng*spt;
  for (ilng = 0; ilng < nlng; ilng++, rowoff += spt, lngp += sll) {
    dlng = *lngp - eul[0];

    phip = phi + rowoff;
    thetap = theta;
    for (ilat = 0; ilat < mlat; ilat++) {
      *phip = dlng;
      phip += rowlen;
    }
  }


  /* Do lat dependency. */
  latp = lat;
  phip   = phi;
  thetap = theta;
  for (ilat = 0; ilat < nlat; ilat++, latp += sll) {
    sincosd(*latp, &sinlat, &coslat);
    coslat3 = coslat*eul[3];
    coslat4 = coslat*eul[4];
    sinlat3 = sinlat*eul[3];
    sinlat4 = sinlat*eul[4];

    for (ilng = 0; ilng < mlng; ilng++, phip += spt, thetap += spt) {
      dlng = *phip;
      sincosd(dlng, &sinlng, &coslng);

      /* Compute the native longitude. */
      x = sinlat4 - coslat3*coslng;
      if (fabs(x) < tol) {
        /* Rearrange formula to reduce roundoff errors. */
        x = -cosd(*latp+eul[1]) + coslat3*(1.0 - coslng);
      }

      y = -coslat*sinlng;
      if (x != 0.0 || y != 0.0) {
        dphi = atan2d(y, x);
      } else {
        /* Change of origin of longitude. */
        if (eul[1] < 90.0) {
          dphi =  dlng - 180.0;
        } else {
          dphi = -dlng;
        }
      }
      *phip = fmod(eul[2] + dphi, 360.0);

      /* Normalize the native longitude. */
      if (*phip > 180.0) {
        *phip -= 360.0;
      } else if (*phip < -180.0) {
        *phip += 360.0;
      }

      /* Compute the native latitude. */
      if (fmod(dlng,180.0) == 0.0) {
        *thetap = *latp + coslng*eul[1];
        if (*thetap >  90.0) *thetap =  180.0 - *thetap;
        if (*thetap < -90.0) *thetap = -180.0 - *thetap;
      } else {
        z = sinlat3 + coslat4*coslng;
        if (fabs(z) > 0.99) {
          /* Use an alternative formula for greater accuracy. */
          *thetap = copysign(acosd(sqrt(x*x+y*y)), z);
        } else {
          *thetap = asind(z);
        }
      }
    }
  }

  return 0;
}