FACT++  1.0
void palPv2el ( const double  pv[6],
double  date,
double  pmass,
int  jformr,
int *  jform,
double *  epoch,
double *  orbinc,
double *  anode,
double *  perih,
double *  aorq,
double *  e,
double *  aorl,
double *  dm,
int *  jstat 
)

Definition at line 201 of file palPv2el.c.

References C, DMAX, eraAnp(), PAL__GCON, and PAL__SPD.

Referenced by palUe2el(), and t_planet().

204  {
205 
206  /* Sin and cos of J2000 mean obliquity (IAU 1976) */
207  const double SE = 0.3977771559319137;
208  const double CE = 0.9174820620691818;
209 
210  /* Minimum allowed distance (AU) and speed (AU/day) */
211  const double RMIN = 1e-3;
212  const double VMIN = 1e-8;
213 
214  /* How close to unity the eccentricity has to be to call it a parabola */
215  const double PARAB = 1.0e-8;
216 
217  double X,Y,Z,XD,YD,ZD,R,V2,V,RDV,GMU,HX,HY,HZ,
218  HX2PY2,H2,H,OI,BIGOM,AR,ECC,S,C,AT,U,OM,
219  GAR3,EM1,EP1,HAT,SHAT,CHAT,AE,AM,DN,PL,
220  EL,Q,TP,THAT,THHF,F;
221 
222  int JF;
223 
224  /* Validate arguments PMASS and JFORMR.*/
225  if (pmass < 0.0) {
226  *jstat = -1;
227  return;
228  }
229  if (jformr < 1 || jformr > 3) {
230  *jstat = -2;
231  return;
232  }
233 
234  /* Provisionally assume the elements will be in the chosen form. */
235  JF = jformr;
236 
237  /* Rotate the position from equatorial to ecliptic coordinates. */
238  X = pv[0];
239  Y = pv[1]*CE+pv[2]*SE;
240  Z = -pv[1]*SE+pv[2]*CE;
241 
242  /* Rotate the velocity similarly, scaling to AU/day. */
243  XD = PAL__SPD*pv[3];
244  YD = PAL__SPD*(pv[4]*CE+pv[5]*SE);
245  ZD = PAL__SPD*(-pv[4]*SE+pv[5]*CE);
246 
247  /* Distance and speed. */
248  R = sqrt(X*X+Y*Y+Z*Z);
249  V2 = XD*XD+YD*YD+ZD*ZD;
250  V = sqrt(V2);
251 
252  /* Reject unreasonably small values. */
253  if (R < RMIN || V < VMIN) {
254  *jstat = -3;
255  return;
256  }
257 
258  /* R dot V. */
259  RDV = X*XD+Y*YD+Z*ZD;
260 
261  /* Mu. */
262  GMU = (1.0+pmass)*PAL__GCON*PAL__GCON;
263 
264  /* Vector angular momentum per unit reduced mass. */
265  HX = Y*ZD-Z*YD;
266  HY = Z*XD-X*ZD;
267  HZ = X*YD-Y*XD;
268 
269  /* Areal constant. */
270  HX2PY2 = HX*HX+HY*HY;
271  H2 = HX2PY2+HZ*HZ;
272  H = sqrt(H2);
273 
274  /* Inclination. */
275  OI = atan2(sqrt(HX2PY2),HZ);
276 
277  /* Longitude of ascending node. */
278  if (HX != 0.0 || HY != 0.0) {
279  BIGOM = atan2(HX,-HY);
280  } else {
281  BIGOM=0.0;
282  }
283 
284  /* Reciprocal of mean distance etc. */
285  AR = 2.0/R-V2/GMU;
286 
287  /* Eccentricity. */
288  ECC = sqrt(DMAX(1.0-AR*H2/GMU,0.0));
289 
290  /* True anomaly. */
291  S = H*RDV;
292  C = H2-R*GMU;
293  if (S != 0.0 || C != 0.0) {
294  AT = atan2(S,C);
295  } else {
296  AT = 0.0;
297  }
298 
299  /* Argument of the latitude. */
300  S = sin(BIGOM);
301  C = cos(BIGOM);
302  U = atan2((-X*S+Y*C)*cos(OI)+Z*sin(OI),X*C+Y*S);
303 
304  /* Argument of perihelion. */
305  OM = U-AT;
306 
307  /* Capture near-parabolic cases. */
308  if (fabs(ECC-1.0) < PARAB) ECC=1.0;
309 
310  /* Comply with JFORMR = 1 or 2 only if orbit is elliptical. */
311  if (ECC > 1.0) JF=3;
312 
313  /* Functions. */
314  GAR3 = GMU*AR*AR*AR;
315  EM1 = ECC-1.0;
316  EP1 = ECC+1.0;
317  HAT = AT/2.0;
318  SHAT = sin(HAT);
319  CHAT = cos(HAT);
320 
321  /* Variable initializations to avoid compiler warnings. */
322  AM = 0.0;
323  DN = 0.0;
324  PL = 0.0;
325  EL = 0.0;
326  Q = 0.0;
327  TP = 0.0;
328 
329  /* Ellipse? */
330  if (ECC < 1.0 ) {
331 
332  /* Eccentric anomaly. */
333  AE = 2.0*atan2(sqrt(-EM1)*SHAT,sqrt(EP1)*CHAT);
334 
335  /* Mean anomaly. */
336  AM = AE-ECC*sin(AE);
337 
338  /* Daily motion. */
339  DN = sqrt(GAR3);
340  }
341 
342  /* "Major planet" element set? */
343  if (JF == 1) {
344 
345  /* Longitude of perihelion. */
346  PL = BIGOM+OM;
347 
348  /* Longitude at epoch. */
349  EL = PL+AM;
350  }
351 
352  /* "Comet" element set? */
353  if (JF == 3) {
354 
355  /* Perihelion distance. */
356  Q = H2/(GMU*EP1);
357 
358  /* Ellipse, parabola, hyperbola? */
359  if (ECC < 1.0) {
360 
361  /* Ellipse: epoch of perihelion. */
362  TP = date-AM/DN;
363 
364  } else {
365 
366  /* Parabola or hyperbola: evaluate tan ( ( true anomaly ) / 2 ) */
367  THAT = SHAT/CHAT;
368  if (ECC == 1.0) {
369 
370  /* Parabola: epoch of perihelion. */
371  TP = date-THAT*(1.0+THAT*THAT/3.0)*H*H2/(2.0*GMU*GMU);
372 
373  } else {
374 
375  /* Hyperbola: epoch of perihelion. */
376  THHF = sqrt(EM1/EP1)*THAT;
377  F = log(1.0+THHF)-log(1.0-THHF);
378  TP = date-(ECC*sinh(F)-F)/sqrt(-GAR3);
379  }
380  }
381  }
382 
383  /* Return the appropriate set of elements. */
384  *jform = JF;
385  *orbinc = OI;
386  *anode = eraAnp(BIGOM);
387  *e = ECC;
388  if (JF == 1) {
389  *perih = eraAnp(PL);
390  *aorl = eraAnp(EL);
391  *dm = DN;
392  } else {
393  *perih = eraAnp(OM);
394  if (JF == 2) *aorl = eraAnp(AM);
395  }
396  if (JF != 3) {
397  *epoch = date;
398  *aorq = 1.0/AR;
399  } else {
400  *epoch = TP;
401  *aorq = Q;
402  }
403  *jstat = 0;
404 
405 }
static const double PAL__GCON
Definition: palmac.h:117
in C
Definition: README_v19.txt:379
#define DMAX(A, B)
Definition: palmac.h:126
double eraAnp(double a)
Definition: anp.c:3
static const double PAL__SPD
Definition: palmac.h:102

+ Here is the call graph for this function:

+ Here is the caller graph for this function: