gcs5.c
0000#include <stdio.h>
0001#include <math.h>
0002#include <orbit.h>
0003
0004
0005/*************************************************************/
0006/* vector external multiplication */
0007/*************************************************************/
0008void vecXmul(double *a,double *b,double *c)
0009{
0010 c[0]=a[1]*b[2]-a[2]*b[1];
0011 c[1]=a[2]*b[0]-a[0]*b[2];
0012 c[2]=a[0]*b[1]-a[1]*b[0];
0013}
0014
0015/************************************************************/
0016/* vector internal multiplication */
0017/************************************************************/
0018double vecImul(double *a,double *b)
0019{
0020 return((double)(a[0]*b[0]+a[1]*b[1]+a[2]*b[2]));
0021}
0022
0023/************************************************************/
0024/* angle between two vectors */
0025/************************************************************/
0026double vecAngSimp(double *a,double *b)
0027{
0028 double aa,bb;
0029 aa=vecNorm(a);
0030 bb=vecNorm(b);
0031 bb=vecImul(a,b)/(aa*bb);
0032// aa=sqrt(1.-bb*bb);
0033// return( (double)(atan2(aa,bb)));
0034 return( (double)acos(bb));
0035}
0036
0037/************************************************************/
0038/* angle between two vectors */
0039/************************************************************/
0040double vecAngDire(double *a,double *b,double *c)
0041{
0042 double ang;
0043 double cc[3];
0044 ang=vecAngSimp(a,b);
0045 vecXmul(a,b,cc);
0046 if(vecImul(cc,c)>0.) return(ang);
0047 else return((double)(6.283185306-ang));
0048}
0049
0050/************************************************************/
0051/* vector conversion */
0052/************************************************************/
0053void vecCnv(double a[][3],double *b,double *c)
0054{
0055 short i,j;
0056 for(i=0;i<3;i++){
0057 c[i]=0.;
0058 for(j=0;j<3;j++) c[i]+=a[i][j]*b[j];
0059 }
0060}
0061
0062void ele2vec(double x,double y,double z,double *a)
0063{
0064 a[0]=x;
0065 a[1]=y;
0066 a[2]=z;
0067}
0068
0069void vec2ele(double *a,double *x,double *y,double *z)
0070{
0071 *x=a[0];
0072 *y=a[1];
0073 *z=a[2];
0074}
0075
0076/********************************************************/
0077/* absolute value of a vector */
0078/********************************************************/
0079double vecNorm(double *c)
0080{
0081 return((double)sqrt(c[0]*c[0]+c[1]*c[1]+c[2]*c[2]));
0082}
0083
0084/************************************************************/
0085/* mm.ddyyyy(day1) & hh.mmss(hr) vs. ref. day(day2) */
0086/* mode=0 : day1 to day2 mode=1 : day2 to day1 */
0087/************************************************************/
0088void date(DateTimePtr day1,double *day2,Boolean left2right)
0089{
0090 double dy1,h,dy2;
0091 double dmo,day3,ddy,dyr,dhr,dhr1,dmn;
0092
0093 if(left2right){
0094 dmo=day1->mo;
0095 ddy=day1->dd;
0096 dyr=day1->yyyy;
0097 dhr=day1->hh;
0098 dmn=day1->mi;
0099 dhr1=day1->ss;
0100 dhr=dhr+dmn/60.+dhr1/3600.;
0101 if(dmo<2.1){
0102 dyr=dyr-1.;
0103 dmo=dmo+13.;
0104 }
0105 else dmo=dmo+1.;
0106 *day2=floor(365.25*dyr)+floor(30.6001*dmo)+ddy+1720982.
0107 +dhr/24.-2433283.;
0108 }
0109 else{
0110 dy2=*day2;
0111 day3=floor(dy2);
0112 h=dy2-day3;
0113 day3=day3+2433283.-1720982;
0114 dyr=floor((day3-122.1)/365.25);
0115 dmo=floor((day3-floor(365.25*dyr))/30.6001);
0116 ddy=day3-floor(365.25*dyr)-floor(30.6001*dmo);
0117 dmo=dmo-1.;
0118 if(dmo>12.5) dmo=dmo-12.;
0119 if(dmo<2.5) dyr=dyr+1.;
0120 day1->yyyy=dyr;
0121 day1->mo=dmo;
0122 day1->dd=ddy;
0123 day3=h*24.;
0124 h=floor(day3);
0125 day3=(day3-h)*60.;
0126 dmn=floor(day3);
0127 day3=(day3-dmn)*60.;
0128 h=h+0.0001*day3;
0129 day1->hh=h;
0130 day1->mi=dmn;
0131 day1->ss=day3;
0132 }
0133}
0134
0135/************************************************************/
0136/* time of the day */
0137/************************************************************/
0138double tod(double day)
0139{
0140 double thet;
0141
0142 thet=fmod(day*360.985,360.);
0143 thet=fmod(0.29015e-12*day*day+6.47346e-4*day+thet
0144 +100.0755425L,360.);
0145 thet*=0.017453293;
0146 return(thet);
0147}
0148
0149/************************************************************/
0150/* true anomaly to mean anomaly */
0151/************************************************************/
0152double f2m(double f,double e)
0153{
0154 double E,M;
0155
0156 E=f2e(f,e);
0157 M=e2m(E,e);
0158 return(M);
0159}
0160
0161/************************************************************/
0162/* true anomaly to eccentric anomaly */
0163/************************************************************/
0164double f2e(double f,double e)
0165{
0166 double E;
0167 E=2.*atan(sqrt((1.-e)/(1.+e))*tan(0.5*f));
0168 return(E);
0169}
0170
0171/************************************************************/
0172/* eccentric anomaly to mean anomaly */
0173/************************************************************/
0174double e2m(double E,double e)
0175{
0176 double M;
0177 M=E-e*sin(E);
0178 return(M);
0179}
0180
0181/************************************************************/
0182/* eccentric anomaly to true anomaly */
0183/************************************************************/
0184double e2f(double E,double e)
0185{
0186 double f;
0187 f=2.*atan(sqrt( (1.+e)/(1.-e) )*tan(0.5*E));
0188 return(f);
0189}
0190
0191/************************************************************/
0192/* mean anomaly to eccentric anomaly */
0193/************************************************************/
0194double m2e(double M,double e)
0195{
0196 double E;
0197 short i;
0198
0199 E=M;
0200 for(i=0;i<14;i++) E=M+e*sin(E);
0201 return(E);
0202}
0203
0204/************************************************************/
0205/* mean anomaly to true anomaly */
0206/************************************************************/
0207double m2f(double M,double e)
0208{
0209 double f,E;
0210 E=m2e(M,e);
0211 f=e2f(E,e);
0212 return(f);
0213}
0214
0215/************************************************/
0216/* LV and Six conversion */
0217/************************************************/
0218void LVSix(LVElemPtr a,SixElemPtr b,Boolean left2right)
0219{
0220 double c[3][3],vdash[3],v0[3],ha[3],hb[3];
0221 double at,on,h,v,az,el,cf1,hh,di,omegal,dr;
0222 double mu,dx,dy,de,df0,da,omegas,day1,dthet;
0223 double hb1,M;
0224
0225 double aa[3],bb[3],cc[3];
0226
0227
0228 if(left2right){
0229 at=a->lat;
0230 on=a->lon;
0231 h=a->h;
0232 v=a->v;
0233 az=a->az;
0234 el=a->el;
0235
0236 cf1=0.01745329251;
0237 at*=cf1;
0238 on*=cf1;
0239 az*=cf1;
0240 el*=cf1;
0241 c[0][0]=-sin(on); // local coordinate pointing east
0242 c[1][0]=cos(on);
0243 c[2][0]=0.;
0244 c[0][2]=cos(at)*cos(on); // local coordinate pointing up
0245 c[1][2]=cos(at)*sin(on);
0246 c[2][2]=sin(at);
0247 ele2vec(c[0][2],c[1][2],c[2][2],aa); // radial vector
0248 ele2vec(c[0][0],c[1][0],c[2][0],bb); // east vector
0249 vecXmul(aa,bb,cc); // north vector
0250 vec2ele(cc,&c[0][1],&c[1][1],&c[2][1]); // local coordinate at separation point
0251 vdash[0]=v*cos(el)*sin(az); // east
0252 vdash[1]=v*cos(el)*cos(az); // north
0253 vdash[2]=v*sin(el); // up
0254 vecCnv(c,vdash,v0); // v0 in geocentric coordinate
0255 vecXmul(aa,v0,ha); // moment of velocity vector
0256 hh=vecNorm(ha);
0257 ha[0]/=hh;
0258 ha[1]/=hh;
0259 ha[2]/=hh;
0260 di=sqrt(ha[0]*ha[0]+ha[1]*ha[1]);
0261 di=atan2(di,ha[2]); // inclination in radian
0262 omegal=atan2(ha[1],ha[0])+1.5707963267; // large omega
0263 dr=6378142.+h;
0264 hh=dr*hh; // moment of velocity
0265 hb1=vecImul(aa,v0); // aa=radial vector
0266 mu=3.986009e14;
0267 dy=hh*hb1;
0268 dx=hh*hh/dr-mu;
0269 de=sqrt(dx*dx+dy*dy)/mu; // eccentricity
0270 df0=atan2(dy,dx); // true anomaly
0271 da=hh*hh/(mu*(1.-de*de));
0272
0273 ele2vec(0.,0.,1.,aa);
0274 vecXmul(aa,ha,hb);
0275 ele2vec(c[0][2],c[1][2],c[2][2],aa); // radial vector
0276 omegas=vecAngDire(hb,aa,ha);
0277 omegas=omegas-df0;
0278 date((DateTimePtr) a,(double *)b,TRUE);
0279 b->epoc+=a->elapsed/86400.;
0280 dthet=tod(b->epoc); // epoc (day from 1950.1.1)
0281 omegal=omegal+dthet; // large omega
0282 M=f2m(df0,de);
0283 b->e=de; // eccentricity
0284 b->M=M; // mean anomaly (rad)
0285 b->om=omegas; // small omega (rad)
0286 b->i=di; // inclination (rad)
0287 b->Om=omegal; // large omega (rad)
0288 b->a=da; // semi-major axis (m)
0289 }
0290 else{
0291 date((DateTimePtr)a,(double *)b,FALSE);
0292 // to be added later
0293 }
0294}
0295
0296/************************************************************/
0297/* 6 elements vs. cartesian */
0298/* */
0299/************************************************************/
0300void SixCart(SixElemPtr a,CartElemPtr b,Boolean left2right)
0301{
0302 double E,x,y,sinlm,coslm,sinsm,cossm,sini,cosi;
0303 double r,mu,vx,vy,ha,r1,f;
0304 double h[3],d[3];
0305
0306 if(left2right){
0307 E=m2e(a->M,a->e);
0308 x=(a->a)*(cos(E)-(a->e));
0309 y=(a->a)*sqrt(1.-(a->e)*(a->e))*sin(E);
0310
0311 sinlm=sin(a->Om);
0312 coslm=cos(a->Om);
0313 sinsm=sin(a->om);
0314 cossm=cos(a->om);
0315 sini=sin(a->i);
0316 cosi=cos(a->i);
0317
0318 b->p[0]=(coslm*cossm-sinlm*sinsm*cosi)*x
0319 +(-coslm*sinsm-sinlm*cossm*cosi)*y;
0320 b->p[1]=(sinlm*cossm+coslm*sinsm*cosi)*x
0321 +(-sinlm*sinsm+coslm*cossm*cosi)*y;
0322 b->p[2]=sinsm*sini*x+cossm*sini*y;
0323
0324 r=vecNorm((double *)(b->p));
0325 mu=3.986009e14;
0326
0327 vx=-(sqrt(mu*(a->a))/r)*sin(E);
0328 vy=(sqrt(mu*(a->a)*(1.-(a->e)*(a->e)))/r)*cos(E);
0329
0330 b->v[0]=(coslm*cossm-sinlm*sinsm*cosi)*vx
0331 +(-coslm*sinsm-sinlm*cossm*cosi)*vy;
0332 b->v[1]=(sinlm*cossm+coslm*sinsm*cosi)*vx
0333 +(-sinlm*sinsm+coslm*cossm*cosi)*vy;
0334 b->v[2]=sinsm*sini*vx+cossm*sini*vy;
0335
0336 }
0337 else{
0338 if(b->p[2]==0.&&b->v[2]==0.){
0339 h[2]=(b->p[0])*(b->v[1])-(b->p[1])*(b->v[0]);
0340 ha=h[2];
0341 a->Om=0.;
0342 if(h[2]>0.)
0343 (a->i)=0.;
0344 else
0345 (a->i)=3.14159265;
0346 }
0347 else{
0348 h[0]=(b->p[1])*(b->v[2])-(b->p[2])*(b->v[1]);
0349 h[1]=(b->p[2])*(b->v[0])-(b->p[0])*(b->v[2]);
0350 h[2]=(b->p[0])*(b->v[1])-(b->p[1])*(b->v[0]);
0351
0352 ha=vecNorm(h);
0353 a->i=acos(h[2]/ha);
0354 x=-h[1];
0355 y=h[0];
0356 a->Om=atan2(y,x);
0357 }
0358
0359 r=vecNorm(b->p);
0360 mu=3.986009e14;
0361 x=ha*ha/r-mu;
0362 y=ha*vecImul(b->p,b->v)/r;
0363 r1=sqrt(x*x+y*y);
0364 if(r1==0.){
0365 a->e=0.0;
0366 a->om=0.0;
0367 d[0]=cos(a->Om);
0368 d[1]=sin(a->Om);
0369 d[2]=0.;
0370 a->M=vecAngDire(d,b->p,h);
0371 }
0372 else {
0373 f=atan2(y,x);
0374 a->e=sqrt(x*x+y*y)/mu;
0375 a->M=f2m(f,a->e);
0376 a->a=ha*ha/(mu*(1.-(a->e)*(a->e)));
0377 d[0]=-h[1];
0378 d[1]=h[0];
0379 d[2]=0.;
0380 a->om=vecAngDire(d,b->p,h)-f;
0381 if(a->om<0.) a->om+=6.283185306;
0382 }
0383 }
0384}