home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume16 / xephem / part06 < prev    next >
Encoding:
Text File  |  1992-03-05  |  50.2 KB  |  1,824 lines

  1. Newsgroups: comp.sources.x
  2. Path: uunet!think.com!mips!msi!dcmartin
  3. From: e_downey@hwking.cca.cr.rockwell.com (Elwood Downey)
  4. Subject: v16i117: xephem - astronomical ephemeris program., Part06/24
  5. Message-ID: <1992Mar6.135318.2170@msi.com>
  6. Originator: dcmartin@fascet
  7. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  8. Organization: Molecular Simulations, Inc.
  9. References: <csx-16i112-xephem@uunet.UU.NET>
  10. Date: Fri, 6 Mar 1992 13:53:18 GMT
  11. Approved: dcmartin@msi.com
  12.  
  13. Submitted-by: e_downey@hwking.cca.cr.rockwell.com (Elwood Downey)
  14. Posting-number: Volume 16, Issue 117
  15. Archive-name: xephem/part06
  16.  
  17. # this is part.06 (part 6 of a multipart archive)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file obj.c continued
  20. #
  21. if test ! -r _shar_seq_.tmp; then
  22.     echo 'Please unpack part 1 first!'
  23.     exit 1
  24. fi
  25. (read Scheck
  26.  if test "$Scheck" != 6; then
  27.     echo Please unpack part "$Scheck" next!
  28.     exit 1
  29.  else
  30.     exit 0
  31.  fi
  32. ) < _shar_seq_.tmp || exit 1
  33. if test ! -f _shar_wnt_.tmp; then
  34.     echo 'x - still skipping obj.c'
  35. else
  36. echo 'x - continuing file obj.c'
  37. sed 's/^X//' << 'SHAR_EOF' >> 'obj.c' &&
  38. #define    E_M2        18
  39. #define    E_SIZE        19
  40. X
  41. #define    H_NAME        20
  42. #define    H_EP        21
  43. #define    H_INC        22
  44. #define    H_LAN        23
  45. #define    H_AOP        24
  46. #define    H_E        25
  47. #define    H_QP        26
  48. #define    H_EPOCH        27
  49. #define    H_G        28
  50. #define    H_K        29
  51. #define    H_SIZE        30
  52. X
  53. #define    P_NAME        31
  54. #define    P_EP        32
  55. #define    P_INC        33
  56. #define    P_AOP        34
  57. #define    P_QP        35
  58. #define    P_LAN        36
  59. #define    P_EPOCH        37
  60. #define    P_G        38
  61. #define    P_K        39
  62. #define    P_SIZE        40
  63. X
  64. static Widget objform_w;
  65. static Widget objsl_w;
  66. static Widget objf_w, obje_w, objh_w, objp_w;
  67. X
  68. static char *dbfile;                    /* !0 if set by -d option */
  69. static char dbfdef[] = "ephem.db";      /* default database file name */
  70. X
  71. /* client codes for the bottom control buttons */
  72. #define    APPLY    1
  73. #define    LOOKUP    2
  74. #define    CLOSE    3
  75. X
  76. /* structures to describe objects of various types.
  77. X */
  78. #define    MAXNM        16    /* longest allowed object name, inc \0 */
  79. typedef struct {
  80. X    double m_m1, m_m2;    /* either g/k or H/G, depending on... */
  81. X    int m_whichm;    /* one of MAG_gk or MAG_HG */
  82. } Mag;
  83. typedef struct {
  84. X    double f_ra;    /* ra, rads, at given epoch */
  85. X    double f_dec;    /* dec, rads, at given epoch */
  86. X    double f_mag;    /* visual magnitude */
  87. X    double f_siz;    /* angular size, in arc seconds */
  88. X    double f_epoch;    /* the given epoch, as an mjd */
  89. X    char   f_name[MAXNM]; /* name */
  90. } ObjF;            /* fixed object */
  91. typedef struct {
  92. X    double e_inc;    /* inclination, degrees */
  93. X    double e_Om;    /* longitude of ascending node, degrees */
  94. X    double e_om;    /* argument of perihelion, degress */
  95. X    double e_a;        /* mean distance, aka, semi-maj axis, in AU */
  96. X    double e_n;        /* daily motion, degrees/day */
  97. X    double e_e;        /* eccentricity */
  98. X    double e_M;        /* mean anomaly, ie, degrees from perihelion at... */
  99. X    double e_cepoch;    /* epoch date (M reference), as an mjd */
  100. X    double e_epoch;    /* equinox year (inc/Om/om reference), as an mjd */
  101. X    Mag    e_mag;    /* magnitude */
  102. X    double e_siz;    /* angular size, in arc seconds at 1 AU */
  103. X    char   e_name[MAXNM]; /* name */
  104. } ObjE;            /* object in heliocentric elliptical orbit */
  105. typedef struct {
  106. X    double h_ep;    /* epoch of perihelion, as an mjd */
  107. X    double h_inc;    /* inclination, degs */
  108. X    double h_Om;    /* longitude of ascending node, degs */
  109. X    double h_om;    /* argument of perihelion, degs. */
  110. X    double h_e;        /* eccentricity */
  111. X    double h_qp;    /* perihelion distance, AU */
  112. X    double h_epoch;    /* equinox year (inc/Om/om reference), as an mjd */
  113. X    double h_g, h_k;    /* magnitude model coefficients */
  114. X    double h_siz;    /* angular size, in arc seconds at 1 AU */
  115. X    char   h_name[MAXNM]; /* name */
  116. } ObjH;            /* object in heliocentric parabolic trajectory */
  117. typedef struct {
  118. X    double p_ep;    /* epoch of perihelion, as an mjd */
  119. X    double p_inc;    /* inclination, degs */
  120. X    double p_qp;    /* perihelion distance, AU */
  121. X    double p_om;    /* argument of perihelion, degs. */
  122. X    double p_Om;    /* longitude of ascending node, degs */
  123. X    double p_epoch;    /* reference epoch, as an mjd */
  124. X    double p_g, p_k;    /* magnitude model coefficients */
  125. X    double p_siz;    /* angular size, in arc seconds at 1 AU */
  126. X    char   p_name[MAXNM]; /* name */
  127. } ObjP;            /* object in heliocentric parabolic trajectory */
  128. X
  129. typedef struct {
  130. X    int  o_type;        /* current object type; see flags, below */
  131. X    int  o_on;          /* !=0 once object is defined */
  132. X    ObjF o_f;           /* the fixed object */
  133. X    ObjE o_e;           /* the elliptical orbit object */
  134. X    ObjH o_h;           /* the hyperbolic orbit object */
  135. X    ObjP o_p;           /* the parabolic orbit object */
  136. } Obj;
  137. X
  138. /* o_type */
  139. #define    FIXED        1
  140. #define    ELLIPTICAL    2
  141. #define    HYPERBOLIC    3
  142. #define    PARABOLIC    4
  143. X
  144. /* m_whichm */
  145. #define MAG_HG          0       /* using 0 makes HG the initial default */
  146. #define MAG_gk          1
  147. X
  148. /* table of fields for the object definitions.
  149. X * the id field is NOT a row/col loc; that is fixed sequentially.
  150. X * instead, the id holds a code for each structure member.
  151. X * N.B. these must be in pairs: label then button (CHG). see create_buttons().
  152. X */
  153. #define    type    width
  154. static FieldMap obj_field_map[] = {
  155. X    {F_NAME, 0, FIXED, "Name:"},
  156. X    {F_NAME, CHG, FIXED, "Object name:"},
  157. X    {F_RA, 0, FIXED, "RA:"},
  158. X    {F_RA, CHG, FIXED, "RA (h:m:s):"},
  159. X    {F_DEC, 0, FIXED, "Dec:"},
  160. X    {F_DEC, CHG, FIXED, "Dec (d:m:s):"},
  161. X    {F_MAG, 0, FIXED, "Mag:"},
  162. X    {F_MAG, CHG, FIXED, "Magnitude:"},
  163. X    {F_EPOCH, 0, FIXED, "Epoch:"},
  164. X    {F_EPOCH, CHG, FIXED, "Reference epoch (UT Date, m/d.d/y or year.d):"},
  165. X    {F_SIZE, 0, FIXED, "Size:"},
  166. X    {F_SIZE, CHG, FIXED, "Angular Size (arc secs):"},
  167. X
  168. X    {E_NAME, 0, ELLIPTICAL, "Name:"},
  169. X    {E_NAME, CHG, ELLIPTICAL, "Object name:"},
  170. X    {E_INC, 0, ELLIPTICAL, "Inclination:"},
  171. X    {E_INC, CHG, ELLIPTICAL, "Inclination (degs):"},
  172. X    {E_LAN, 0, ELLIPTICAL, "Long of Asc Nod:"},
  173. X    {E_LAN, CHG, ELLIPTICAL, "Longitude of ascending node (degs):"},
  174. X    {E_AOP, 0, ELLIPTICAL, "Arg of Peri:"},
  175. X    {E_AOP, CHG, ELLIPTICAL, "Argument of Perihelion (degs):"},
  176. X    {E_A, 0, ELLIPTICAL, "Mean Dist:"},
  177. X    {E_A, CHG, ELLIPTICAL, "Mean distance (AU):"},
  178. X    {E_N, 0, ELLIPTICAL, "Daily Motion:"},
  179. X    {E_N, CHG, ELLIPTICAL, "Daily motion (degs/day):"},
  180. X    {E_E, 0, ELLIPTICAL, "Eccentricity:"},
  181. X    {E_E, CHG, ELLIPTICAL, "Eccentricty (<1):"},
  182. X    {E_M, 0, ELLIPTICAL, "Mean Anomaly:"},
  183. X    {E_M, CHG, ELLIPTICAL, "Mean Anomaly (degs):"},
  184. X    {E_CEPOCH, 0, ELLIPTICAL, "C Epoch:"},
  185. X    {E_CEPOCH, CHG, ELLIPTICAL, "Epoch date (UT Date, m/d.d/y or year.d):"},
  186. X    {E_EPOCH, 0, ELLIPTICAL, "Epoch:"},
  187. X    {E_EPOCH, CHG, ELLIPTICAL, "Equinox year (UT Date, m/d.d/y or year.d):"},
  188. X    {E_M1, 0, ELLIPTICAL, "Mag coeff 1:"},
  189. X    {E_M1, CHG, ELLIPTICAL, "Magnitude coefficient 1 (g#, H# or just #):"},
  190. X    {E_M2, 0, ELLIPTICAL, "Mag coeff 2:"},
  191. X    {E_M2, CHG, ELLIPTICAL, "Magnitude coefficient 2 (k#, G# or just #):"},
  192. X    {E_SIZE, 0, ELLIPTICAL, "Size:"},
  193. X    {E_SIZE, CHG, ELLIPTICAL, "Angular Size @ 1 AU (arc secs):"},
  194. X
  195. X    {H_NAME, 0, HYPERBOLIC, "Name:"},
  196. X    {H_NAME, CHG, HYPERBOLIC, "Object name:"},
  197. X    {H_EP, 0, HYPERBOLIC, "Ep of Peri:"},
  198. X    {H_EP,CHG, HYPERBOLIC, "Epoch of perihelion (UT Date, m/d.d/y or year.d):"},
  199. X    {H_INC, 0, HYPERBOLIC, "Inclination:"},
  200. X    {H_INC, CHG, HYPERBOLIC, "Inclination (degs):"},
  201. X    {H_LAN, 0, HYPERBOLIC, "Long of Asc Nod:"},
  202. X    {H_LAN, CHG, HYPERBOLIC, "Longitude of ascending node (degs):"},
  203. X    {H_AOP, 0, HYPERBOLIC, "Arg of Peri:"},
  204. X    {H_AOP, CHG, HYPERBOLIC, "Argument of perihelion (degs):"},
  205. X    {H_E, 0, HYPERBOLIC, "Eccentricity:"},
  206. X    {H_E, CHG, HYPERBOLIC, "Eccentricity (>1):"},
  207. X    {H_QP, 0, HYPERBOLIC, "Peri Dist:"},
  208. X    {H_QP, CHG, HYPERBOLIC, "Perihelion distance (AU):"},
  209. X    {H_EPOCH, 0, HYPERBOLIC, "Epoch:"},
  210. X    {H_EPOCH, CHG, HYPERBOLIC, "Reference epoch (UT Date, m/d.d/y or year.d):"},
  211. X    {H_G, 0, HYPERBOLIC, "g:"},
  212. X    {H_G, CHG, HYPERBOLIC, "g, as in m = g + 5*log(delta) + 2.5*k*log(r):"},
  213. X    {H_K, 0, HYPERBOLIC, "k:"},
  214. X    {H_K, CHG, HYPERBOLIC, "k, as in m = g + 5*log(delta) + 2.5*k*log(r):"},
  215. X    {H_SIZE, 0, HYPERBOLIC, "Size:"},
  216. X    {H_SIZE, CHG, HYPERBOLIC, "Angular Size @ 1 AU (arc secs):"},
  217. X
  218. X    {P_NAME, 0, PARABOLIC, "Name:"},
  219. X    {P_NAME, CHG, PARABOLIC, "Object name:"},
  220. X    {P_EP, 0, PARABOLIC, "Ep of Peri:"},
  221. X    {P_EP, CHG, PARABOLIC, "Epoch of perihelion (UT Date, m/d.d/y or year.d):"},
  222. X    {P_INC, 0, PARABOLIC, "Inclination:"},
  223. X    {P_INC, CHG, PARABOLIC, "Inclination (degs):"},
  224. X    {P_AOP, 0, PARABOLIC, "Arg of Peri:"},
  225. X    {P_AOP, CHG, PARABOLIC, "Argument of perihelion (degs):"},
  226. X    {P_QP, 0, PARABOLIC, "Peri Dist:"},
  227. X    {P_QP, CHG, PARABOLIC, "Perihelion distance (AU):"},
  228. X    {P_LAN, 0, PARABOLIC, "Long of Asc Nod:"},
  229. X    {P_LAN, CHG, PARABOLIC, "Longitude of ascending node (degs):"},
  230. X    {P_EPOCH, 0, PARABOLIC, "Epoch:"},
  231. X    {P_EPOCH, CHG, PARABOLIC, "Reference epoch (UT Date, m/d.d/y or year.d):"},
  232. X    {P_G, 0, PARABOLIC, "g:"},
  233. X    {P_G, CHG, PARABOLIC, "g, as in m = g + 5*log(delta) + 2.5*k*log(r):"},
  234. X    {P_K, 0, PARABOLIC, "k:"},
  235. X    {P_K, CHG, PARABOLIC, "k, as in m = g + 5*log(delta) + 2.5*k*log(r):"},
  236. X    {P_SIZE, 0, PARABOLIC, "Size:"},
  237. X    {P_SIZE, CHG, PARABOLIC, "Angular Size @ 1 AU (arc secs):"},
  238. };
  239. #define    ASIZ(a)    (sizeof(a)/sizeof(a[0]))
  240. #define    NFM    ASIZ(obj_field_map)
  241. #define    LFM    (&obj_field_map[NFM])
  242. X
  243. static Obj objx;
  244. static Obj objy;
  245. static Obj *objp;
  246. X
  247. X
  248. /* return true if object is now on, else 0.
  249. X */
  250. obj_ison(p)
  251. int p;
  252. {
  253. X    return ((p == OBJX) ? objx.o_on : objy.o_on);
  254. }
  255. X
  256. /* set an alternate database file name.
  257. X * N.B. we assume the storage pointed to by name is permanent.
  258. X */
  259. obj_setdbfilename (name)
  260. char *name;
  261. {
  262. X    dbfile = name;
  263. }
  264. X
  265. /* retrive the name of OBJX or Y */
  266. char *
  267. obj_getname (p)
  268. int p;
  269. {
  270. X    Obj *op = (p == OBJX) ? &objx : &objy;
  271. X
  272. X    switch (op->o_type) {
  273. X    case FIXED: return (op->o_f.f_name);
  274. X    case ELLIPTICAL: return (op->o_e.e_name);
  275. X    case HYPERBOLIC: return (op->o_h.h_name);
  276. X    case PARABOLIC: return (op->o_p.p_name);
  277. X    }
  278. X    return (0);
  279. }
  280. X
  281. X
  282. /* called by the main menu pick.
  283. X * create the main form, if this is the first time we've been called.
  284. X * then we toggle each time.
  285. X */
  286. obj_manage()
  287. {
  288. X    if (!objform_w) {
  289. X        objp = &objx;    /* must agree with way button is initialized */
  290. X        obj_create_form();
  291. X        obj_create_buttons();
  292. X        obj_set_all_buttons();
  293. X        obj_set_type_radiobox ();
  294. X    }
  295. X    
  296. X    if (XtIsManaged(objform_w))
  297. X        XtUnmanageChild (objform_w);
  298. X    else
  299. X        XtManageChild (objform_w);
  300. }
  301. X
  302. /* set object p (OBJX or OBJY) to name */
  303. obj_filelookup (p, name)
  304. int p;
  305. char *name;
  306. {
  307. X    FILE *obj_opendb();
  308. X    char buf[MAXDBLINE];
  309. X    int nl;
  310. X    FILE *fp;
  311. X
  312. X    fp = obj_opendb();
  313. X    if (!fp) 
  314. X        return;
  315. X
  316. X    /* search for first entry with a matching name */
  317. X    nl = strlen (name);
  318. X    while (nxt_db(buf, sizeof(buf), fp) == 0 && strncmp(buf, name, nl))
  319. X        continue;
  320. X
  321. X    if (feof(fp)) {
  322. X        (void) sprintf (buf, "Object %s not found", name);
  323. X        f_msg (buf, 0);
  324. X    } else {
  325. X        objp = (p == OBJX) ? &objx : &objy;
  326. X        (void) obj_crack_dbline (buf);
  327. X    }
  328. X
  329. X    (void) fclose (fp);
  330. }
  331. X
  332. /* called once to build the basic form.
  333. X */
  334. static
  335. obj_create_form ()
  336. {
  337. X    Arg args[20];
  338. X    void obj_xy_cb();
  339. X    void obj_type_cb();
  340. X    void obj_lookup_cb();
  341. X    void obj_select_cb();
  342. X    void obj_close_cb();
  343. X    void obj_help_cb();
  344. X    Widget rb_w, cl_w, lkup_w, help_w, w;
  345. X    XmString str;
  346. X    int n;
  347. X
  348. X    /* create form */
  349. X    n = 0;
  350. X    XtSetArg (args[n], XmNfractionBase, 1000); n++;
  351. X    XtSetArg (args[n], XmNheight, NR*char_height()); n++;
  352. X    XtSetArg (args[n], XmNwidth, NC*char_width()); n++;
  353. X    XtSetArg (args[n], XmNautoUnmanage, False); n++;
  354. X    XtSetArg (args[n], XmNdefaultPosition, False); n++;
  355. X    XtSetArg (args[n], XmNallowOverlap, False); n++;
  356. X    XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
  357. X    objform_w = XmCreateFormDialog (toplevel_w, "Obj", args, n);
  358. X
  359. X    /* set some stuff in the parent DialogShell.
  360. X     * setting XmNdialogTitle in the Form didn't work..
  361. X     */
  362. X    n = 0;
  363. X    XtSetArg (args[n], XmNtitle, "xephem ObjX/Y Menu"); n++;
  364. X    XtSetValues (XtParent(objform_w), args, n);
  365. X
  366. X    /* make the help button */
  367. X    str = XmStringCreate("Help", XmSTRING_DEFAULT_CHARSET);
  368. X    n = 0;
  369. X    XtSetArg (args[n], XmNlabelString, str); n++;
  370. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  371. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  372. X    help_w = XmCreatePushButtonGadget (objform_w, "ObjHelp", args, n);
  373. X    XtAddCallback (help_w, XmNactivateCallback, obj_help_cb, 0);
  374. X    XtManageChild (help_w);
  375. X    XmStringFree (str);
  376. X
  377. X    /* make the "lookup" button */
  378. X    n = 0;
  379. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  380. X    XtSetArg (args[n], XmNbottomWidget, help_w); n++;
  381. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  382. X    XtSetArg (args[n], XmNleftOffset, TBLW*char_width()); n++;
  383. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  384. X    lkup_w = XmCreatePushButtonGadget (objform_w, "Lookup", args, n);
  385. X    XtAddCallback(lkup_w, XmNarmCallback, obj_lookup_cb, 0);
  386. X    XtManageChild (lkup_w);
  387. X
  388. X    /* create the lookup scrolled list widget */
  389. X    n = 0;
  390. X    XtSetArg (args[n], XmNselectionPolicy, XmSINGLE_SELECT); n++;
  391. X    XtSetArg (args[n], XmNvisibleItemCount, NR-3); n++;
  392. X    XtSetArg (args[n], XmNlistSizePolicy, XmRESIZE_IF_POSSIBLE); n++;
  393. X    objsl_w = XmCreateScrolledList (objform_w, "ScrolledList", args, n);
  394. X    XtAddCallback(objsl_w, XmNsingleSelectionCallback, obj_select_cb, 0);
  395. X    n = 0;
  396. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  397. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  398. X    XtSetArg (args[n], XmNbottomWidget, lkup_w); n++;
  399. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  400. X    XtSetArg (args[n], XmNleftWidget, lkup_w); n++;
  401. X    XtSetArg (args[n], XmNleftOffset, 0); n++; /* override hSep */
  402. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  403. X    XtSetValues (XtParent(objsl_w), args, n);
  404. X    XtManageChild (objsl_w);
  405. X
  406. X    /* make the x/y selection radio box */
  407. X    n = 0;
  408. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  409. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  410. X    XtSetArg (args[n], XmNrightWidget, XtParent(objsl_w)); n++;
  411. X    XtSetArg (args[n], XmNrightOffset, char_width()); n++;
  412. X    XtSetArg (args[n], XmNorientation, XmVERTICAL); n++;
  413. X    rb_w = XmCreateRadioBox (objform_w, "ObjXYRadioBox", args, n);
  414. X    XtManageChild (rb_w);
  415. X
  416. X    n = 0;
  417. X    XtSetArg (args[n], XmNset, True); n++;    /* ObjX is initial default */
  418. X    w = XmCreateToggleButtonGadget (rb_w, "ObjX", args, n);
  419. X    XtAddCallback (w, XmNvalueChangedCallback, obj_xy_cb, OBJX);
  420. X    XtManageChild (w);
  421. X
  422. X    n = 0;
  423. X    w = XmCreateToggleButtonGadget (rb_w, "ObjY", args, n);
  424. X    XtAddCallback (w, XmNvalueChangedCallback, obj_xy_cb, OBJY);
  425. X    XtManageChild (w);
  426. X
  427. X    /* make the type control radio box.
  428. X     * we save the widget ids so we can force the type to be what
  429. X     * was selected from the database.
  430. X     */
  431. X    n = 0;
  432. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  433. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  434. X    XtSetArg (args[n], XmNorientation, XmVERTICAL); n++;
  435. X    rb_w = XmCreateRadioBox (objform_w, "ObjTypeRadioBox", args, n);
  436. X    XtManageChild (rb_w);
  437. X
  438. X    n = 0;
  439. X    objf_w = XmCreateToggleButtonGadget (rb_w, "Fixed", args, n);
  440. X    XtAddCallback (objf_w, XmNvalueChangedCallback, obj_type_cb, FIXED);
  441. X    XtManageChild (objf_w);
  442. X
  443. X    n = 0;
  444. X    obje_w = XmCreateToggleButtonGadget (rb_w, "Elliptical", args, n);
  445. X    XtAddCallback(obje_w,XmNvalueChangedCallback,obj_type_cb,ELLIPTICAL);
  446. X    XtManageChild (obje_w);
  447. X
  448. X    n = 0;
  449. X    objh_w = XmCreateToggleButtonGadget (rb_w, "Hyperbolic", args, n);
  450. X    XtAddCallback(objh_w,XmNvalueChangedCallback,obj_type_cb,HYPERBOLIC);
  451. X    XtManageChild (objh_w);
  452. X
  453. X    n = 0;
  454. X    objp_w = XmCreateToggleButtonGadget (rb_w, "Parabolic", args, n);
  455. X    XtAddCallback (objp_w, XmNvalueChangedCallback,obj_type_cb,PARABOLIC);
  456. X    XtManageChild (objp_w);
  457. X
  458. X    /* make the close button */
  459. X    str = XmStringCreate("Close", XmSTRING_DEFAULT_CHARSET);
  460. X    n = 0;
  461. X    XtSetArg (args[n], XmNlabelString, str); n++;
  462. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  463. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  464. X    cl_w = XmCreatePushButtonGadget (objform_w, "ObjClose", args, n);
  465. X    XtAddCallback (cl_w, XmNactivateCallback, obj_close_cb, 0);
  466. X    XtManageChild (cl_w);
  467. X    XmStringFree (str);
  468. }
  469. X
  470. /* add the labels and buttons to the form for the current object type. */
  471. static
  472. obj_create_buttons()
  473. {
  474. X    void obj_activate_cb();
  475. X    Arg args[20];
  476. X    FieldMap *fp;
  477. X    int r;
  478. X    int t;
  479. X    int n;
  480. X
  481. X    r = FIRST_ROW;
  482. X    t = objp->o_type;
  483. X    for (fp = obj_field_map; fp < LFM; fp++) {
  484. X        if (fp->type == t) {
  485. X        n = 0;
  486. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  487. X        XtSetArg (args[n], XmNtopPosition, r2ypos(r)); n++;
  488. X        if (fp->how) {
  489. X            /* pushbutton */
  490. X            XtSetArg (args[n], XmNrightAttachment, XmATTACH_WIDGET);n++;
  491. X            XtSetArg (args[n], XmNrightWidget, XtParent(objsl_w)); n++;
  492. X            XtSetArg (args[n], XmNrightOffset, char_width()); n++;
  493. X            XtSetArg (args[n], XmNalignment, XmALIGNMENT_END); n++;
  494. X            fp->w = XtCreateManagedWidget ("ObjButton",
  495. X                xmPushButtonGadgetClass, objform_w, args, n);
  496. X            XtAddCallback(fp->w,XmNactivateCallback,obj_activate_cb,fp);
  497. X            r++;   /* here's why buttons come after labels in map */
  498. X        } else {
  499. X            /* label */
  500. X            XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  501. X            XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING);n++;
  502. X            fp->w = XtCreateManagedWidget (fp->prompt,
  503. X                    xmLabelGadgetClass, objform_w, args, n);
  504. X        }
  505. X        }
  506. X    }
  507. }
  508. X
  509. /* destroy the buttons and labels for the current object type
  510. X * N.B. we know ALL existing widgets should be destroyed. if we needed to
  511. X *   know the exact ones based on type for example, it would mean obj_select_cb
  512. X *   and its use of this would need to be changed because of how obj_crack_
  513. X *   dbline changes objp->o_type on the fly.
  514. X */
  515. static
  516. obj_destroy_buttons()
  517. {
  518. X    FieldMap *fp;
  519. X
  520. X    for (fp = obj_field_map; fp < LFM; fp++)
  521. X        if (fp->w) {
  522. X        XtDestroyWidget (fp->w);
  523. X        fp->w = 0;
  524. X        }
  525. }
  526. X
  527. /* callback from any of the obj menu buttons being activated.  */
  528. void
  529. obj_activate_cb (w, client, call)
  530. Widget w;
  531. caddr_t client;
  532. caddr_t call;
  533. {
  534. X    FieldMap *fp = (FieldMap *)client;
  535. X    prompt (fp);
  536. }
  537. X
  538. /* callback from the Close button. */
  539. void
  540. obj_close_cb (w, client, call)
  541. Widget w;
  542. caddr_t client;
  543. caddr_t call;
  544. {
  545. X    XtUnmanageChild (objform_w);
  546. }
  547. X
  548. /* callback from the Help button. */
  549. void
  550. obj_help_cb (w, client, call)
  551. Widget w;
  552. caddr_t client;
  553. caddr_t call;
  554. {
  555. X    static char *msg[] = {
  556. "Object X and Object Y may be set to any of four types of objects: fixed or in",
  557. "heliocentric elliptical, hyperbolic or parabolic orbits. Give the location or",
  558. "orbital elements are necessary.",
  559. "",
  560. "The object may also be loaded from a database, if available. The database",
  561. "filename is ephem.db by default, or set from the EPHEMDB environ variable."
  562. };
  563. X
  564. X    switch (objp->o_type) {
  565. X    case FIXED:
  566. X        hlp_dialog ("Fixed Object", msg, sizeof(msg)/sizeof(msg[0]));
  567. X        break;
  568. X    case ELLIPTICAL:
  569. X        hlp_dialog ("Elliptical Object", msg, sizeof(msg)/sizeof(msg[0]));
  570. X        break;
  571. X    case HYPERBOLIC:
  572. X        hlp_dialog ("Hyperbolic Object", msg, sizeof(msg)/sizeof(msg[0]));
  573. X        break;
  574. X    case PARABOLIC:
  575. X        hlp_dialog ("Parabolic Object", msg, sizeof(msg)/sizeof(msg[0]));
  576. X        break;
  577. X    default:
  578. X        hlp_dialog ("Object", msg, sizeof(msg)/sizeof(msg[0]));
  579. X        break;
  580. X    }
  581. }
  582. X
  583. /* callback for which object (x or y) toggle. */
  584. void
  585. obj_xy_cb (w, client, call)
  586. Widget w;
  587. caddr_t client;
  588. caddr_t call;
  589. {
  590. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  591. X    int xy = (int)client;
  592. X
  593. X    if (t->set && objp != (xy == OBJX ? &objx : &objy)) {
  594. X        obj_destroy_buttons();
  595. X        objp = xy == OBJX ? &objx : &objy;
  596. X        obj_create_buttons();
  597. X        obj_set_all_buttons();
  598. X        obj_set_type_radiobox ();
  599. X    }
  600. }
  601. X
  602. /* callback for what type of object toggles */
  603. void
  604. obj_type_cb (w, client, call)
  605. Widget w;
  606. caddr_t client;
  607. caddr_t call;
  608. {
  609. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  610. X    int type = (int)client;
  611. X
  612. X    if (t->set && objp->o_type != type) {
  613. X        obj_destroy_buttons();
  614. X        objp->o_type = type;
  615. X        obj_create_buttons();
  616. X        obj_set_all_buttons();
  617. X    }
  618. }
  619. X
  620. /* callback for the Lookup button 
  621. X * open the database, and stick everything with current type into the list.
  622. X * put up watch cursor because it can take a while.
  623. X */
  624. void
  625. obj_lookup_cb (w, client, call)
  626. Widget w;
  627. caddr_t client;
  628. caddr_t call;
  629. {
  630. X    static Cursor wc;
  631. X
  632. X    if (!wc)
  633. X        wc = XCreateFontCursor (XtDisplay(objform_w), XC_watch);
  634. X
  635. X    XDefineCursor (XtDisplay(objform_w), XtWindow(objform_w), wc);
  636. X
  637. X    /* it looks better if we do it while it's unmanaged, IMHO. */
  638. X    XtUnmanageChild (objsl_w);
  639. X
  640. X    obj_reset_list();
  641. X    obj_load_list();
  642. X
  643. X    XtManageChild (objsl_w);
  644. X
  645. X    XUndefineCursor (XtDisplay(objform_w), XtWindow(objform_w));
  646. }
  647. X
  648. /* callback when an item is selected from the scrolled list.
  649. X */
  650. void
  651. obj_select_cb (w, client, call)
  652. Widget w;
  653. caddr_t client;
  654. caddr_t call;
  655. {
  656. X    XmListCallbackStruct *l = (XmListCallbackStruct *) call;
  657. X    char *text;
  658. X
  659. X    XmStringGetLtoR (l->item, XmSTRING_DEFAULT_CHARSET, &text);
  660. X    if (obj_crack_dbline (text) == 0) {
  661. X        /* reset up all the buttons, push the right type
  662. X         * and update the other menus too.
  663. X         */
  664. X        obj_destroy_buttons(); /* doesn't need the previous type */
  665. X        obj_create_buttons();
  666. X        obj_set_all_buttons();
  667. X        obj_set_type_radiobox();
  668. X        redraw_screen (0);
  669. X    }
  670. X
  671. X    /* XmStringGetLtoR man pages doesn't mention XtFreeing text...
  672. X    XtFree (text);
  673. X    */
  674. }
  675. X
  676. /* set the type radio to reflect the type of objp
  677. X * if o_type is undefined, well then all buttons should be released.
  678. X */
  679. static
  680. obj_set_type_radiobox ()
  681. {
  682. X    Widget tw = 0;
  683. X
  684. X    switch (objp->o_type) {
  685. X    case FIXED: tw = objf_w; break;
  686. X    case ELLIPTICAL: tw = obje_w; break;
  687. X    case HYPERBOLIC: tw = objh_w; break;
  688. X    case PARABOLIC: tw = objp_w; break;
  689. X    }
  690. X
  691. X    set_something (objf_w, XmNset, tw == objf_w);
  692. X    set_something (obje_w, XmNset, tw == obje_w);
  693. X    set_something (objh_w, XmNset, tw == objh_w);
  694. X    set_something (objp_w, XmNset, tw == objp_w);
  695. }
  696. X
  697. /* using the data in the current object, set all the buttons.
  698. X * N.B. we assume the buttons are already made for the current type.
  699. X */
  700. static
  701. obj_set_all_buttons()
  702. {
  703. X    FieldMap *fp;
  704. X
  705. X    for (fp = obj_field_map; fp < LFM; fp++)
  706. X        if (fp->w && fp->how == CHG)
  707. X        obj_set_button (fp);
  708. }
  709. X
  710. /* define current objp based on the ephem.db line, s.
  711. X * format: name,type,[other fields, as per corresponding ObjX typedef]
  712. X * return 0 if ok else print reason why not with f_msg() and return -1.
  713. X * N.B. we set objp->o_type on the fly. this means trouble if caller needs
  714. X *    to do something with the old type.
  715. X */
  716. static
  717. obj_crack_dbline (s)
  718. char *s;
  719. {
  720. #define    MAXARGS    20
  721. X    static char zero[] = "0";
  722. X    char *av[MAXARGS];    /* point to each field for easy reference */
  723. X    char scopy[MAXDBLINE];
  724. X    char ebuf[MAXDBLINE+100];
  725. X    char *s_sav = s;
  726. X    int ac;
  727. X    char c;
  728. X    int i;
  729. X
  730. X    /* we replace ',' with '\0' in place, so copy s into scopy then
  731. X     * point s back at scopy.
  732. X     */
  733. X    strncpy (scopy, s, sizeof(scopy));
  734. X    scopy[sizeof(scopy)-1] = '\0';
  735. X    s = scopy;
  736. X
  737. X    /* parse into comma separated fields */
  738. X    ac = 0;
  739. X    av[0] = scopy;
  740. X    do {
  741. X        c = *s++;
  742. X        if (c == ',' || c == '\0') {
  743. X        s[-1] = '\0';
  744. X        av[++ac] = s;
  745. X        }
  746. X    } while (c);
  747. X
  748. X    if (ac < 2) {
  749. X        (void) sprintf (ebuf, "Too few fields in Database line: %s", s_sav);
  750. X        f_msg (ebuf, 1);
  751. X        return (-1);
  752. X    }
  753. X
  754. X    /* switch out on type of object - the second field */
  755. X    switch (av[1][0]) {
  756. X    case 'f': {
  757. X        static int ids[] = {F_RA, F_DEC, F_MAG, F_EPOCH};
  758. X        if (ac != 6 && ac != 7) {
  759. X        (void) sprintf(ebuf,
  760. X            "Need ra,dec,mag,D[,siz] for fixed object %s", av[0]);
  761. X        f_msg (ebuf, 1);
  762. X        return (-1);
  763. X        }
  764. X        objp->o_type = FIXED;
  765. X        obj_set_field (av[0], F_NAME);
  766. X        for (i = 2; i < ASIZ(ids)+2; i++)
  767. X        obj_set_field (av[i], ids[i-2]);
  768. X        obj_set_field (ac == 7 ? av[6] : zero, F_SIZE);
  769. X        break;
  770. X    }
  771. X
  772. X    case 'e': {
  773. X        static int ids[] = {E_INC, E_LAN, E_AOP, E_A, E_N, E_E, E_M,
  774. X                        E_CEPOCH, E_EPOCH, E_M1, E_M2
  775. X        };
  776. X        if (ac != 13 && ac != 14) {
  777. X        (void) sprintf (ebuf,
  778. X        "Need i,O,o,a,n,e,M,E,D,H/g,G/k[,siz] for elliptical object %s",
  779. X                                    av[0]);
  780. X        f_msg (ebuf, 1);
  781. X        return (-1);
  782. X        }
  783. X        objp->o_type = ELLIPTICAL;
  784. X        obj_set_field (av[0], E_NAME);
  785. X        for (i = 2; i < ASIZ(ids)+2; i++)
  786. X        obj_set_field (av[i], ids[i-2]);
  787. X        obj_set_field (ac == 14 ? av[13] : zero, E_SIZE);
  788. X        break;
  789. X    }
  790. X
  791. X    case 'h': {
  792. X        static int ids[]= {H_EP,H_INC,H_LAN,H_AOP,H_E,H_QP,H_EPOCH,H_G,H_K};
  793. X        if (ac != 11 && ac != 12) {
  794. X        (void) sprintf (ebuf,
  795. X        "Need T,i,O,o,e,q,D,g,k[,siz] for hyperbolic object %s", av[0]);
  796. X        f_msg (ebuf, 1);
  797. X        return (-1);
  798. X        }
  799. X        objp->o_type = HYPERBOLIC;
  800. X        obj_set_field (av[0], H_NAME);
  801. X        for (i = 2; i < ASIZ(ids)+2; i++)
  802. X        obj_set_field (av[i], ids[i-2]);
  803. X        obj_set_field (ac == 12 ? av[11] : zero, H_SIZE);
  804. X        break;
  805. X    }
  806. X
  807. X    case 'p': {
  808. X        static int ids[] = {P_EP,P_INC,P_AOP,P_QP,P_LAN,P_EPOCH,P_G,P_K};
  809. X        if (ac != 10 && ac != 11) {
  810. X        (void) sprintf (ebuf,
  811. X            "Need T,i,o,q,O,D,g,k[,siz] for parabolic object %s", av[0]);
  812. X        f_msg (ebuf, 1);
  813. X        return (-1);
  814. X        }
  815. X        objp->o_type = PARABOLIC;
  816. X        obj_set_field (av[0], P_NAME);
  817. X        for (i = 2; i < ASIZ(ids)+2; i++)
  818. X        obj_set_field (av[i], ids[i-2]);
  819. X        obj_set_field (ac == 11 ? av[10] : zero, P_SIZE);
  820. X        break;
  821. X    }
  822. X
  823. X    default:
  824. X        (void) sprintf (ebuf, "Unknown type for Object %s: %s",
  825. X                                av[0], av[1]);
  826. X        f_msg (ebuf, 1);
  827. X        return (-1);
  828. X    }
  829. X
  830. X    return (0);
  831. }
  832. X
  833. /* reset the scrolled list.
  834. X */
  835. static
  836. obj_reset_list()
  837. {
  838. X    XmListDeleteAllItems(objsl_w);
  839. }
  840. X
  841. /* read all objects from the database file into the scrolled list.
  842. X * if -d was used use it; else if EPHEMDB env set use it, else use default.
  843. X */
  844. static
  845. obj_load_list ()
  846. {
  847. X    FILE *obj_opendb();
  848. X    FILE *fp;
  849. X    char buf[MAXDBLINE];
  850. X
  851. X    fp = obj_opendb();
  852. X    if (!fp)
  853. X        return;
  854. X
  855. X    while (nxt_db (buf, sizeof(buf), fp) == 0) {
  856. X        XmString str;
  857. X        str = XmStringCreate (buf, XmSTRING_DEFAULT_CHARSET);
  858. X        XmListAddItemUnselected (objsl_w, str, 0);
  859. X        XmStringFree(str);
  860. X    }
  861. X
  862. X    (void) fclose (fp);
  863. }
  864. X
  865. /* open the database file and return a FILE * */
  866. static FILE *
  867. obj_opendb()
  868. {
  869. X    char *fn;
  870. X    FILE *fp;
  871. X
  872. X    if (dbfile)
  873. X        fn = dbfile;
  874. X    else {
  875. X        fn = getenv ("EPHEMDB");
  876. X        if (!fn)
  877. X        fn = dbfdef;
  878. X    }
  879. X
  880. X    fp = fopen (fn, "r");
  881. X    if (!fp) {
  882. X        char buf[100];
  883. X        (void) sprintf (buf, "Can not open database file %s", fn);
  884. X        f_msg(buf, 1);
  885. X    }
  886. X    return (fp);
  887. }
  888. X
  889. /* read database file fp and put next valid entry (sans trailing \n) into buf.
  890. X * return 0 if ok, else -1
  891. X */
  892. static
  893. nxt_db (buf, blen, fp)
  894. char buf[];
  895. int blen;
  896. FILE *fp;
  897. {
  898. X    char s;
  899. X
  900. X    while (1) {
  901. X        if (fgets (buf, blen, fp) == 0)
  902. X        return (-1);
  903. X        s = buf[0];
  904. X        if (isalpha(s) || isdigit(s)) {
  905. X        buf[strlen(buf)-1] = '\0';
  906. X        return (0);
  907. X        }
  908. X    }
  909. }
  910. X
  911. /* user typed OK to a prompt for fp. get his new value and use it */
  912. static void
  913. prompt_ok_cb (w, client, call)
  914. Widget w;
  915. caddr_t client;
  916. caddr_t call;
  917. {
  918. X    FieldMap *fp = (FieldMap *)client;
  919. X    char *text;
  920. X    
  921. X    get_xmstring(w, XmNtextString, &text);
  922. X    obj_set_field (text, fp->id);
  923. X    obj_set_button (fp);
  924. X    XtDestroyWidget (w);
  925. X    XtFree (text);
  926. }
  927. X
  928. /* put up a prompt dialog to ask about fp */
  929. static
  930. prompt (fp)
  931. FieldMap *fp;
  932. {
  933. X    Widget w, dw;
  934. X    XmString str;
  935. X    Arg args[20];
  936. X    int n;
  937. X    
  938. X    n = 0;
  939. X    str = XmStringCreate (fp->prompt, XmSTRING_DEFAULT_CHARSET);
  940. X    XtSetArg(args[n], XmNselectionLabelString, str);  n++;
  941. X    dw = XmCreatePromptDialog(toplevel_w, "xephem Prompt", args, n);
  942. X    w = XmSelectionBoxGetChild (dw, XmDIALOG_HELP_BUTTON);
  943. X    XtUnmanageChild (w);
  944. X    XmStringFree (str);
  945. X    XtAddCallback (dw, XmNokCallback, prompt_ok_cb, fp);
  946. X    XtManageChild (dw);
  947. X    w = XmSelectionBoxGetChild (dw, XmDIALOG_TEXT);
  948. X    XmProcessTraversal (w, XmTRAVERSE_CURRENT);
  949. X    XmProcessTraversal (w, XmTRAVERSE_CURRENT); /* yes, twice!! */
  950. }
  951. X
  952. /* format the button for fp */
  953. static
  954. obj_set_button (fp)
  955. FieldMap *fp;
  956. {
  957. X    static char me[] = "obj_set_button";
  958. X    Widget w = fp->w;
  959. X
  960. X    switch (fp->id) {
  961. X    case F_NAME:
  962. X        f_string (w, objp->o_f.f_name);
  963. X        break;
  964. X    case F_RA:
  965. X        f_ra (w, objp->o_f.f_ra);
  966. X        break;
  967. X    case F_DEC:
  968. X        f_gangle (w, objp->o_f.f_dec);
  969. X        break;
  970. X    case F_MAG:
  971. X        f_double (w, "%g", objp->o_f.f_mag);
  972. X        break;
  973. X    case F_EPOCH:
  974. X        epoch_as_decimal (w, objp->o_f.f_epoch);
  975. X        break;
  976. X    case F_SIZE:
  977. X        f_double (w, "%g", objp->o_f.f_siz);
  978. X        break;
  979. X
  980. X    case E_NAME:
  981. X        f_string (w, objp->o_e.e_name);
  982. X        break;
  983. X    case E_INC:
  984. X        f_double (w, "%g", objp->o_e.e_inc);
  985. X        break;
  986. X    case E_LAN:
  987. X        f_double (w, "%g", objp->o_e.e_Om);
  988. X        break;
  989. X    case E_AOP:
  990. X        f_double (w, "%g", objp->o_e.e_om);
  991. X        break;
  992. X    case E_A:
  993. X        f_double (w, "%g", objp->o_e.e_a);
  994. X        break;
  995. X    case E_N:
  996. X        f_double (w, "%g", objp->o_e.e_n);
  997. X        break;
  998. X    case E_E:
  999. X        f_double (w, "%g", objp->o_e.e_e);
  1000. X        break;
  1001. X    case E_M:
  1002. X        f_double (w, "%g", objp->o_e.e_M);
  1003. X        break;
  1004. X    case E_CEPOCH:
  1005. X        epoch_as_mdy (w, objp->o_e.e_cepoch);
  1006. X        break;
  1007. X    case E_EPOCH:
  1008. X        epoch_as_decimal (w, objp->o_e.e_epoch);
  1009. X        break;
  1010. X    case E_M1: {
  1011. X        char buf[64];
  1012. X        (void) sprintf (buf, "%c%g",
  1013. X                objp->o_e.e_mag.m_whichm == MAG_HG ? 'H' : 'g',
  1014. X                objp->o_e.e_mag.m_m1);
  1015. X        f_string (w, buf);
  1016. X        break;
  1017. X    }
  1018. X    case E_M2: {
  1019. X        char buf[64];
  1020. X        (void) sprintf (buf, "%c%g",
  1021. X                objp->o_e.e_mag.m_whichm == MAG_HG ? 'G' : 'k',
  1022. X                objp->o_e.e_mag.m_m2);
  1023. X        f_string (w, buf);
  1024. X        break;
  1025. X    }
  1026. X    case E_SIZE:
  1027. X        f_double (w, "%g", objp->o_e.e_siz);
  1028. X        break;
  1029. X
  1030. X    case H_NAME:
  1031. X        f_string (w, objp->o_h.h_name);
  1032. X        break;
  1033. X    case H_EP:
  1034. X        epoch_as_mdy (w, objp->o_h.h_ep);
  1035. X        break;
  1036. X    case H_INC:
  1037. X        f_double (w, "%g", objp->o_h.h_inc);
  1038. X        break;
  1039. X    case H_LAN:
  1040. X        f_double (w, "%g", objp->o_h.h_Om);
  1041. X        break;
  1042. X    case H_AOP:
  1043. X        f_double (w, "%g", objp->o_h.h_om);
  1044. X        break;
  1045. X    case H_E:
  1046. X        f_double (w, "%g", objp->o_h.h_e);
  1047. X        break;
  1048. X    case H_QP:
  1049. X        f_double (w, "%g", objp->o_h.h_qp);
  1050. X        break;
  1051. X    case H_EPOCH:
  1052. X        epoch_as_decimal (w, objp->o_h.h_epoch);
  1053. X        break;
  1054. X    case H_G:
  1055. X        f_double (w, "%g", objp->o_h.h_g);
  1056. X        break;
  1057. X    case H_K:
  1058. X        f_double (w, "%g", objp->o_h.h_k);
  1059. X        break;
  1060. X    case H_SIZE:
  1061. X        f_double (w, "%g", objp->o_h.h_siz);
  1062. X        break;
  1063. X
  1064. X    case P_NAME:
  1065. X        f_string (w, objp->o_p.p_name);
  1066. X        break;
  1067. X    case P_EP:
  1068. X        epoch_as_mdy (w, objp->o_p.p_ep);
  1069. X        break;
  1070. X    case P_INC:
  1071. X        f_double (w, "%g", objp->o_p.p_inc);
  1072. X        break;
  1073. X    case P_AOP:
  1074. X        f_double (w, "%g", objp->o_p.p_om);
  1075. X        break;
  1076. X    case P_QP:
  1077. X        f_double (w, "%g", objp->o_p.p_qp);
  1078. X        break;
  1079. X    case P_LAN:
  1080. X        f_double (w, "%g", objp->o_p.p_Om);
  1081. X        break;
  1082. X    case P_EPOCH:
  1083. X        epoch_as_decimal (w, objp->o_p.p_epoch);
  1084. X        break;
  1085. X    case P_G:
  1086. X        f_double (w, "%g", objp->o_p.p_g);
  1087. X        break;
  1088. X    case P_K:
  1089. X        f_double (w, "%g", objp->o_p.p_k);
  1090. X        break;
  1091. X    case P_SIZE:
  1092. X        f_double (w, "%g", objp->o_p.p_siz);
  1093. X        break;
  1094. X    default:
  1095. X        printf ("%s: bad parabolic id: %d\n", me, fp->id);
  1096. X        exit (1);
  1097. X    }
  1098. }
  1099. X
  1100. static
  1101. epoch_as_decimal (w, e)
  1102. Widget w;
  1103. double e;
  1104. {
  1105. X    double y;
  1106. X    mjd_year (e, &y);
  1107. X    f_double (w, "%g", y);
  1108. }
  1109. X
  1110. static
  1111. epoch_as_mdy (w, e)
  1112. Widget w;
  1113. double e;
  1114. {
  1115. X    int m, y;
  1116. X    double d;
  1117. X    char buf[100];
  1118. X
  1119. X    mjd_cal (e, &m, &d, &y);
  1120. X    (void) sprintf (buf, "%d/%g/%d", m, d, y);
  1121. X    f_string (w, buf);
  1122. }
  1123. X
  1124. /* given a text buffer and a field id, set the corresponding member in objp. */
  1125. static
  1126. obj_set_field (bp, id)
  1127. char bp[];
  1128. int id;
  1129. {
  1130. X    /* object is "on" once it has a field set */
  1131. X    objp->o_on = 1;
  1132. X
  1133. X    switch (id) {
  1134. X    case F_NAME:
  1135. X        strncpy (objp->o_f.f_name, bp, sizeof(objp->o_f.f_name)-1);
  1136. X        break;
  1137. X    case F_RA: {
  1138. X        int h, m, s;
  1139. X        f_dec_sexsign (radhr(objp->o_f.f_ra), &h, &m, &s);
  1140. X        f_sscansex (bp, &h, &m, &s);
  1141. X        sex_dec (h, m, s, &objp->o_f.f_ra);
  1142. X        objp->o_f.f_ra = hrrad(objp->o_f.f_ra);
  1143. X        break;
  1144. X    }
  1145. X    case F_DEC: {
  1146. X        int dg, m, s;
  1147. X        f_dec_sexsign (raddeg(objp->o_f.f_dec), &dg, &m, &s);
  1148. X        f_sscansex (bp, &dg, &m, &s);
  1149. X        sex_dec (dg, m, s, &objp->o_f.f_dec);
  1150. X        objp->o_f.f_dec = degrad(objp->o_f.f_dec);
  1151. X        break;
  1152. X    }
  1153. X    case F_MAG:
  1154. X        objp->o_f.f_mag = atof (bp);
  1155. X        break;
  1156. X    case F_EPOCH:
  1157. X        crack_year (bp, &objp->o_f.f_epoch);
  1158. X        break;
  1159. X    case F_SIZE:
  1160. X        objp->o_f.f_siz = atof (bp);
  1161. X        break;
  1162. X
  1163. X    case E_NAME:
  1164. X        strncpy (objp->o_e.e_name, bp, sizeof(objp->o_e.e_name)-1);
  1165. X        break;
  1166. X    case E_INC:
  1167. X        objp->o_e.e_inc = atof (bp);
  1168. X        break;
  1169. X    case E_LAN:
  1170. X        objp->o_e.e_Om = atof (bp);
  1171. X        break;
  1172. X    case E_AOP:
  1173. X        objp->o_e.e_om = atof (bp);
  1174. X        break;
  1175. X    case E_A:
  1176. X        objp->o_e.e_a = atof (bp);
  1177. X        break;
  1178. X    case E_N:
  1179. X        objp->o_e.e_n = atof (bp);
  1180. X        break;
  1181. X    case E_E:
  1182. X        objp->o_e.e_e = atof (bp);
  1183. X        break;
  1184. X    case E_M:
  1185. X        objp->o_e.e_M = atof (bp);
  1186. X        break;
  1187. X    case E_CEPOCH:
  1188. X        crack_year (bp, &objp->o_e.e_cepoch);
  1189. X        break;
  1190. X    case E_EPOCH:
  1191. X        crack_year (bp, &objp->o_e.e_epoch);
  1192. X        break;
  1193. X    case E_M1:
  1194. X        switch (bp[0]) {
  1195. X        case 'g':
  1196. X        objp->o_e.e_mag.m_whichm = MAG_gk;
  1197. X        bp++;
  1198. X        break;
  1199. X        case 'H':
  1200. X        objp->o_e.e_mag.m_whichm = MAG_HG;
  1201. X        bp++;
  1202. X        break;
  1203. X        default:
  1204. X        /* leave type unchanged if no or unrecognized prefix */
  1205. X        break;
  1206. X        }
  1207. X        objp->o_e.e_mag.m_m1 = atof(bp);
  1208. X        break;
  1209. X    case E_M2:
  1210. X        switch (bp[0]) {
  1211. X        case 'k':
  1212. X        objp->o_e.e_mag.m_whichm = MAG_gk;
  1213. X        bp++;
  1214. X        break;
  1215. X        case 'G':
  1216. X        objp->o_e.e_mag.m_whichm = MAG_HG;
  1217. X        bp++;
  1218. X        break;
  1219. X        default:
  1220. X        /* leave type unchanged if no or unrecognized prefix */
  1221. X        break;
  1222. X        }
  1223. X        objp->o_e.e_mag.m_m2 = atof(bp);
  1224. X        break;
  1225. X    case E_SIZE:
  1226. X        objp->o_e.e_siz = atof (bp);
  1227. X        break;
  1228. X
  1229. X    case H_NAME:
  1230. X        strncpy (objp->o_h.h_name, bp, sizeof(objp->o_h.h_name)-1);
  1231. X        break;
  1232. X    case H_EP:
  1233. X        crack_year (bp, &objp->o_h.h_ep);
  1234. X        break;
  1235. X    case H_INC:
  1236. X        objp->o_h.h_inc = atof (bp);
  1237. X        break;
  1238. X    case H_LAN:
  1239. X        objp->o_h.h_Om = atof (bp);
  1240. X        break;
  1241. X    case H_AOP:
  1242. X        objp->o_h.h_om = atof (bp);
  1243. X        break;
  1244. X    case H_E:
  1245. X        objp->o_h.h_e = atof (bp);
  1246. X        break;
  1247. X    case H_QP:
  1248. X        objp->o_h.h_qp = atof (bp);
  1249. X        break;
  1250. X    case H_EPOCH:
  1251. X        crack_year (bp, &objp->o_h.h_epoch);
  1252. X        break;
  1253. X    case H_G:
  1254. X        objp->o_h.h_g = atof (bp);
  1255. X        break;
  1256. X    case H_K:
  1257. X        objp->o_h.h_k = atof (bp);
  1258. X        break;
  1259. X    case H_SIZE:
  1260. X        objp->o_h.h_siz = atof (bp);
  1261. X        break;
  1262. X
  1263. X    case P_NAME:
  1264. X        strncpy (objp->o_p.p_name, bp, sizeof(objp->o_p.p_name)-1);
  1265. X        break;
  1266. X    case P_EP:
  1267. X        crack_year (bp, &objp->o_p.p_ep);
  1268. X        break;
  1269. X    case P_INC:
  1270. X        objp->o_p.p_inc = atof (bp);
  1271. X        break;
  1272. X    case P_AOP:
  1273. X        objp->o_p.p_om = atof (bp);
  1274. X        break;
  1275. X    case P_QP:
  1276. X        objp->o_p.p_qp = atof (bp);
  1277. X        break;
  1278. X    case P_LAN:
  1279. X        objp->o_p.p_Om = atof (bp);
  1280. X        break;
  1281. X    case P_EPOCH:
  1282. X        crack_year (bp, &objp->o_p.p_epoch);
  1283. X        break;
  1284. X    case P_G:
  1285. X        objp->o_p.p_g = atof (bp);
  1286. X        break;
  1287. X    case P_K:
  1288. X        objp->o_p.p_k = atof (bp);
  1289. X        break;
  1290. X    case P_SIZE:
  1291. X        objp->o_p.p_siz = atof (bp);
  1292. X        break;
  1293. X    default:
  1294. X        printf ("obj_set_field: bad id: %d\n", id);
  1295. X        exit (1);
  1296. X    }
  1297. }
  1298. X
  1299. /* given either a decimal year (xxxx. something) or a calendar (x/x/x)
  1300. X * convert it to an mjd and store it at *p;
  1301. X */
  1302. static
  1303. crack_year (bp, p)
  1304. char *bp;
  1305. double *p;
  1306. {
  1307. X    if (decimal_year(bp)) {
  1308. X        double y = atof (bp);
  1309. X        year_mjd (y, p);
  1310. X    } else {
  1311. X        int m, y;
  1312. X        double d;
  1313. X        mjd_cal (*p, &m, &d, &y);    /* init with current */
  1314. X        f_sscandate (bp, &m, &d, &y);
  1315. X        cal_mjd (m, d, y, p);
  1316. X    }
  1317. }
  1318. X
  1319. /* fill in info about object x or y.
  1320. X * most arguments and conditions are the same as for plans().
  1321. X * only difference is that mag is already apparent, not absolute magnitude.
  1322. X * this is called by body_cir() for object x and y just like plans() is called
  1323. X * for the planets.
  1324. X */
  1325. obj_cir (jd, p, lpd0, psi0, rp0, rho0, lam, bet, siz, mag)
  1326. double jd;    /* mjd now */
  1327. int p;        /* OBJX or OBJY */
  1328. double *lpd0;    /* heliocentric longitude, or NOHELIO  */
  1329. double *psi0;    /* heliocentric latitude, or 0 if *lpd0 set to NOHELIO */
  1330. double *rp0;    /* distance from the sun, or 0 */
  1331. double *rho0;    /* true distance from the Earth, or 0 */
  1332. double *lam;    /* apparent geocentric ecliptic longitude */
  1333. double *bet;    /* apparent geocentric ecliptic latitude */
  1334. double *siz;    /* angular size of object, arc seconds */
  1335. double *mag;    /* APPARENT magnitude */
  1336. {
  1337. X    Obj *op = (p == OBJX) ? &objx : &objy;
  1338. X
  1339. X    switch (op->o_type) {
  1340. X    case FIXED: {
  1341. X        double xr, xd;
  1342. X        xr = op->o_f.f_ra;
  1343. X        xd = op->o_f.f_dec;
  1344. X        if (op->o_f.f_epoch != jd)
  1345. X        precess (op->o_f.f_epoch, jd, &xr, &xd);
  1346. X        eq_ecl (jd, xr, xd, bet, lam);
  1347. X
  1348. X        *lpd0 = NOHELIO;
  1349. X        *psi0 = *rp0 = *rho0 = 0.0;
  1350. X        *mag = op->o_f.f_mag;
  1351. X        *siz = op->o_f.f_siz;
  1352. X        }
  1353. X        break;
  1354. X
  1355. X    case ELLIPTICAL: {
  1356. X        /* this is basically the same code as pelement() and plans()
  1357. X         * combined and simplified for the special case of osculating
  1358. X         * (unperturbed) elements.
  1359. X         * inputs have been changed to match the Astronomical Almanac.
  1360. X         * we have added reduction of elements using reduce_elements().
  1361. X         */
  1362. X        double dt, lg, lsn, rsn;
  1363. X        double nu, ea;
  1364. X        double ma, rp, lo, slo, clo;
  1365. X        double inc, psi, spsi, cpsi;
  1366. X        double y, lpd, rpd, ll, rho, sll, cll;
  1367. X        double om;        /* arg of perihelion */
  1368. X        double Om;        /* long of ascending node. */
  1369. X        double e;
  1370. X        int pass;
  1371. X
  1372. X        dt = 0;
  1373. X        sunpos (jd, &lsn, &rsn);
  1374. X        lg = lsn + PI;
  1375. X        e = op->o_e.e_e;
  1376. X
  1377. X        for (pass = 0; pass < 2; pass++) {
  1378. X
  1379. X        reduce_elements (op->o_e.e_epoch, jd-dt, degrad(op->o_e.e_inc),
  1380. X                degrad (op->o_e.e_om), degrad (op->o_e.e_Om),
  1381. X                &inc, &om, &Om);
  1382. X
  1383. X        ma = degrad (op->o_e.e_M
  1384. X                + (jd - op->o_e.e_cepoch - dt) * op->o_e.e_n);
  1385. X        anomaly (ma, e, &nu, &ea);
  1386. X        rp = op->o_e.e_a * (1-e*e) / (1+e*cos(nu));
  1387. X        lo = nu + om;
  1388. X        slo = sin(lo);
  1389. X        clo = cos(lo);
  1390. X        spsi = slo*sin(inc);
  1391. X        y = slo*cos(inc);
  1392. X        psi = asin(spsi);
  1393. X        lpd = atan(y/clo)+Om;
  1394. X        if (clo<0) lpd += PI;
  1395. X        range (&lpd, 2*PI);
  1396. X        cpsi = cos(psi);
  1397. X        rpd = rp*cpsi;
  1398. X        ll = lpd-lg;
  1399. X        rho = sqrt(rsn*rsn+rp*rp-2*rsn*rp*cpsi*cos(ll));
  1400. X        dt = rho*5.775518e-3;    /* light travel time, in days */
  1401. X        if (pass == 0) {
  1402. X            *lpd0 = lpd;
  1403. X            *psi0 = psi;
  1404. X            *rp0 = rp;
  1405. X            *rho0 = rho;
  1406. X        }
  1407. X        }
  1408. X
  1409. X        sll = sin(ll);
  1410. X        cll = cos(ll);
  1411. X        if (rpd < rsn)
  1412. X        *lam = atan(-1*rpd*sll/(rsn-rpd*cll))+lg+PI;
  1413. X        else
  1414. X        *lam = atan(rsn*sll/(rpd-rsn*cll))+lpd;
  1415. X        range (lam, 2*PI);
  1416. X        *bet = atan(rpd*spsi*sin(*lam-lpd)/(cpsi*rsn*sll));
  1417. X
  1418. X        if (op->o_e.e_mag.m_whichm == MAG_HG) {
  1419. X        /* the H and G parameters from the Astro. Almanac.
  1420. X         */
  1421. X        double psi_t, Psi_1, Psi_2, beta;
  1422. X        beta = acos((rp*rp + rho*rho - rsn*rsn)/ (2*rp*rho));
  1423. X        psi_t = exp(log(tan(beta/2.0))*0.63);
  1424. X        Psi_1 = exp(-3.33*psi_t);
  1425. X        psi_t = exp(log(tan(beta/2.0))*1.22);
  1426. X        Psi_2 = exp(-1.87*psi_t);
  1427. X        *mag = op->o_e.e_mag.m_m1 + 5.0*log10(rp*rho)
  1428. X            - 2.5*log10((1-op->o_e.e_mag.m_m2)*Psi_1
  1429. X            + op->o_e.e_mag.m_m2*Psi_2);
  1430. X        } else {
  1431. X        /* the g/k model of comets */
  1432. X        *mag = op->o_e.e_mag.m_m1 + 5*log10(rho)
  1433. X                    + 2.5*op->o_e.e_mag.m_m2*log10(rp);
  1434. X        }
  1435. X        *siz = op->o_e.e_siz / rho;
  1436. X        }
  1437. X        break;
  1438. X
  1439. X    case HYPERBOLIC: {
  1440. X        double dt, lg, lsn, rsn;
  1441. X        double nu, ea;
  1442. X        double ma, rp, lo, slo, clo;
  1443. X        double inc, psi, spsi, cpsi;
  1444. X        double y, lpd, rpd, ll, rho, sll, cll;
  1445. X        double om;        /* arg of perihelion */
  1446. X        double Om;        /* long of ascending node. */
  1447. X        double e;
  1448. X        double a, n;    /* semi-major axis, mean daily motion */
  1449. X        int pass;
  1450. X
  1451. X        dt = 0;
  1452. X        sunpos (jd, &lsn, &rsn);
  1453. X        lg = lsn + PI;
  1454. X        e = op->o_h.h_e;
  1455. X        a = op->o_h.h_qp/(e - 1.0);
  1456. X        n = .98563/sqrt(a*a*a);
  1457. X
  1458. X        for (pass = 0; pass < 2; pass++) {
  1459. X
  1460. X        reduce_elements (op->o_h.h_epoch, jd-dt, degrad(op->o_h.h_inc),
  1461. X                degrad (op->o_h.h_om), degrad (op->o_h.h_Om),
  1462. X                &inc, &om, &Om);
  1463. X
  1464. X        ma = degrad ((jd - op->o_h.h_ep - dt) * n);
  1465. X        anomaly (ma, e, &nu, &ea);
  1466. X        rp = a * (e*e-1.0) / (1.0+e*cos(nu));
  1467. X        lo = nu + om;
  1468. X        slo = sin(lo);
  1469. X        clo = cos(lo);
  1470. X        spsi = slo*sin(inc);
  1471. X        y = slo*cos(inc);
  1472. X        psi = asin(spsi);
  1473. X        lpd = atan(y/clo)+Om;
  1474. X        if (clo<0) lpd += PI;
  1475. X        range (&lpd, 2*PI);
  1476. X        cpsi = cos(psi);
  1477. X        rpd = rp*cpsi;
  1478. X        ll = lpd-lg;
  1479. X        rho = sqrt(rsn*rsn+rp*rp-2*rsn*rp*cpsi*cos(ll));
  1480. X        dt = rho*5.775518e-3;    /* light travel time, in days */
  1481. X        if (pass == 0) {
  1482. X            *lpd0 = lpd;
  1483. X            *psi0 = psi;
  1484. X            *rp0 = rp;
  1485. X            *rho0 = rho;
  1486. X        }
  1487. X        }
  1488. X
  1489. X        sll = sin(ll);
  1490. X        cll = cos(ll);
  1491. X        if (rpd < rsn)
  1492. X        *lam = atan(-1*rpd*sll/(rsn-rpd*cll))+lg+PI;
  1493. X        else
  1494. X        *lam = atan(rsn*sll/(rpd-rsn*cll))+lpd;
  1495. X        range (lam, 2*PI);
  1496. X        *bet = atan(rpd*spsi*sin(*lam-lpd)/(cpsi*rsn*sll));
  1497. X
  1498. X        *mag = op->o_h.h_g + 5*log10(rho) + 2.5*op->o_h.h_k*log10(rp);
  1499. X        *siz = op->o_h.h_siz / rho;
  1500. X        }
  1501. X        break;
  1502. X
  1503. X    case PARABOLIC: {
  1504. X        double inc, om, Om;
  1505. X        double lpd, psi, rp, rho;
  1506. X        double dt;
  1507. X        int pass;
  1508. X
  1509. X        /* two passes to correct lam and bet for light travel time. */
  1510. X        dt = 0.0;
  1511. X        for (pass = 0; pass < 2; pass++) {
  1512. X        reduce_elements (op->o_p.p_epoch, jd-dt, degrad(op->o_p.p_inc),
  1513. X            degrad(op->o_p.p_om), degrad(op->o_p.p_Om), &inc, &om, &Om);
  1514. X        comet (jd-dt, op->o_p.p_ep, inc, om, op->o_p.p_qp, Om,
  1515. X                    &lpd, &psi, &rp, &rho, lam, bet);
  1516. X        if (pass == 0) {
  1517. X            *lpd0 = lpd;
  1518. X            *psi0 = psi;
  1519. X            *rp0 = rp;
  1520. X            *rho0 = rho;
  1521. X        }
  1522. X        dt = rho*5.775518e-3;    /* au to light-days */
  1523. X        }
  1524. X        *mag = op->o_p.p_g + 5*log10(rho) + 2.5*op->o_p.p_k*log10(rp);
  1525. X        *siz = op->o_p.p_siz / rho;
  1526. X        }
  1527. X        break;
  1528. X
  1529. X    default:
  1530. X        f_msg ((p == OBJX) ? "Obj X is on but not defined"
  1531. X                   : "Obj Y is on but not defined", 1);
  1532. X        break;
  1533. X    }
  1534. }
  1535. SHAR_EOF
  1536. echo 'File obj.c is complete' &&
  1537. chmod 0644 obj.c ||
  1538. echo 'restore of obj.c failed'
  1539. Wc_c="`wc -c < 'obj.c'`"
  1540. test 41488 -eq "$Wc_c" ||
  1541.     echo 'obj.c: original size 41488, current size' "$Wc_c"
  1542. rm -f _shar_wnt_.tmp
  1543. fi
  1544. # ============= obliq.c ==============
  1545. if test -f 'obliq.c' -a X"$1" != X"-c"; then
  1546.     echo 'x - skipping obliq.c (File already exists)'
  1547.     rm -f _shar_wnt_.tmp
  1548. else
  1549. > _shar_wnt_.tmp
  1550. echo 'x - extracting obliq.c (Text)'
  1551. sed 's/^X//' << 'SHAR_EOF' > 'obliq.c' &&
  1552. #include <stdio.h>
  1553. #include "astro.h"
  1554. X
  1555. /* given the modified Julian date, mjd, find the obliquity of the
  1556. X * ecliptic, *eps, in radians.
  1557. X */
  1558. obliquity (mjd, eps)
  1559. double mjd;
  1560. double *eps;
  1561. {
  1562. X    static double lastmjd = -10000, lasteps;
  1563. X
  1564. X    if (mjd != lastmjd) {
  1565. X        double t;
  1566. X        t = mjd/36525.;
  1567. X        lasteps = degrad(2.345229444E1
  1568. X            - ((((-1.81E-3*t)+5.9E-3)*t+4.6845E1)*t)/3600.0);
  1569. X        lastmjd = mjd;
  1570. X    }
  1571. X    *eps = lasteps;
  1572. }
  1573. SHAR_EOF
  1574. chmod 0644 obliq.c ||
  1575. echo 'restore of obliq.c failed'
  1576. Wc_c="`wc -c < 'obliq.c'`"
  1577. test 421 -eq "$Wc_c" ||
  1578.     echo 'obliq.c: original size 421, current size' "$Wc_c"
  1579. rm -f _shar_wnt_.tmp
  1580. fi
  1581. # ============= parallax.c ==============
  1582. if test -f 'parallax.c' -a X"$1" != X"-c"; then
  1583.     echo 'x - skipping parallax.c (File already exists)'
  1584.     rm -f _shar_wnt_.tmp
  1585. else
  1586. > _shar_wnt_.tmp
  1587. echo 'x - extracting parallax.c (Text)'
  1588. sed 's/^X//' << 'SHAR_EOF' > 'parallax.c' &&
  1589. #include <stdio.h>
  1590. #include <math.h>
  1591. #include "astro.h"
  1592. X
  1593. /* given true ha and dec, tha and tdec, the geographical latitude, phi, the
  1594. X * height above sea-level (as a fraction of the earths radius, 6378.16km),
  1595. X * ht, and the equatorial horizontal parallax, ehp, find the apparent
  1596. X * ha and dec, aha and adec allowing for parallax.
  1597. X * all angles in radians. ehp is the angle subtended at the body by the
  1598. X * earth's equator.
  1599. X */
  1600. ta_par (tha, tdec, phi, ht, ehp, aha, adec)
  1601. double tha, tdec, phi, ht, ehp;
  1602. double *aha, *adec;
  1603. {
  1604. X    static double last_phi, last_ht, rsp, rcp;
  1605. X    double rp;    /* distance to object in Earth radii */
  1606. X    double ctha;
  1607. X    double stdec, ctdec;
  1608. X    double tdtha, dtha;
  1609. X    double caha;
  1610. X
  1611. X    /* avoid calcs involving the same phi and ht */
  1612. X    if (phi != last_phi || ht != last_ht) {
  1613. X        double cphi, sphi, u;
  1614. X        cphi = cos(phi);
  1615. X        sphi = sin(phi);
  1616. X        u = atan(9.96647e-1*sphi/cphi);
  1617. X        rsp = (9.96647e-1*sin(u))+(ht*sphi);
  1618. X        rcp = cos(u)+(ht*cphi);
  1619. X        last_phi  =  phi;
  1620. X        last_ht  =  ht;
  1621. X    }
  1622. X
  1623. X        rp = 1/sin(ehp);
  1624. X
  1625. X        ctha = cos(tha);
  1626. X    stdec = sin(tdec);
  1627. X    ctdec = cos(tdec);
  1628. X        tdtha = (rcp*sin(tha))/((rp*ctdec)-(rcp*ctha));
  1629. X        dtha = atan(tdtha);
  1630. X    *aha = tha+dtha;
  1631. X    caha = cos(*aha);
  1632. X    range (aha, 2*PI);
  1633. X        *adec = atan(caha*(rp*stdec-rsp)/(rp*ctdec*ctha-rcp));
  1634. }
  1635. X
  1636. #ifdef NEEDIT
  1637. /* given the apparent ha and dec, aha and adec, the geographical latitude, phi,
  1638. X * the height above sea-level (as a fraction of the earths radius, 6378.16km),
  1639. X * ht, and the equatorial horizontal parallax, ehp, find the true ha and dec,
  1640. X * tha and tdec allowing for parallax.
  1641. X * all angles in radians. ehp is the angle subtended at the body by the
  1642. X * earth's equator.
  1643. X * uses ta_par() iteratively: find a set of true ha/dec that converts back
  1644. X  *  to the given apparent ha/dec.
  1645. X */
  1646. at_par (aha, adec, phi, ht, ehp, tha, tdec)
  1647. double aha, adec, phi, ht, ehp;
  1648. double *tha, *tdec;
  1649. {
  1650. X    double nha, ndec;    /* ha/dec corres. to current true guesses */
  1651. X    double eha, edec;    /* error in ha/dec */
  1652. X
  1653. X    /* first guess for true is just the apparent */
  1654. X    *tha = aha;
  1655. X    *tdec = adec;
  1656. X
  1657. X    while (1) {
  1658. X        ta_par (*tha, *tdec, phi, ht, ehp, &nha, &ndec);
  1659. X        eha = aha - nha;
  1660. X        edec = adec - ndec;
  1661. X        if (fabs(eha)<1e-6 && fabs(edec)<1e-6)
  1662. X        break;
  1663. X        *tha += eha;
  1664. X        *tdec += edec;
  1665. X    }
  1666. }
  1667. #endif
  1668. SHAR_EOF
  1669. chmod 0644 parallax.c ||
  1670. echo 'restore of parallax.c failed'
  1671. Wc_c="`wc -c < 'parallax.c'`"
  1672. test 2301 -eq "$Wc_c" ||
  1673.     echo 'parallax.c: original size 2301, current size' "$Wc_c"
  1674. rm -f _shar_wnt_.tmp
  1675. fi
  1676. # ============= pelement.c ==============
  1677. if test -f 'pelement.c' -a X"$1" != X"-c"; then
  1678.     echo 'x - skipping pelement.c (File already exists)'
  1679.     rm -f _shar_wnt_.tmp
  1680. else
  1681. > _shar_wnt_.tmp
  1682. echo 'x - extracting pelement.c (Text)'
  1683. sed 's/^X//' << 'SHAR_EOF' > 'pelement.c' &&
  1684. #include <stdio.h>
  1685. #include <math.h>
  1686. #include "astro.h"
  1687. X
  1688. /* this array contains polynomial coefficients to find the various orbital
  1689. X *   elements for the mean orbit at any instant in time for each major planet.
  1690. X *   the first five elements are in the form a0 + a1*t + a2*t**2 + a3*t**3,
  1691. X *   where t is the number of Julian centuries of 36525 Julian days since 1900
  1692. X *   Jan 0.5. the last three elements are constants.
  1693. X *
  1694. X * the orbital element (column) indeces are:
  1695. X *   [ 0- 3]: coefficients for mean longitude, in degrees;
  1696. X *   [ 4- 7]: coefficients for longitude of the perihelion, in degrees;
  1697. X *   [ 8-11]: coefficients for eccentricity;
  1698. X *   [12-15]: coefficients for inclination, in degrees;
  1699. X *   [16-19]: coefficients for longitude of the ascending node, in degrees;
  1700. X *      [20]: semi-major axis, in AU;
  1701. X *      [21]: angular diameter at 1 AU, in arcsec;
  1702. X *      [22]: standard visual magnitude, ie, the visual magnitude of the planet
  1703. X *          when at a distance of 1 AU from both the Sun and the Earth and
  1704. X *          with zero phase angle.
  1705. X *
  1706. X * the planent (row) indeces are:
  1707. X *   [0]: Mercury; [1]: Venus;   [2]: Mars;  [3]: Jupiter; [4]: Saturn;
  1708. X *   [5]: Uranus;  [6]: Neptune; [7]: Pluto.
  1709. X */
  1710. #define    NPELE    (5*4 + 3)    /* 4 coeffs for ea of 5 elems, + 3 constants */
  1711. static double elements[8][NPELE] = {
  1712. X
  1713. X    {   /*     mercury... */
  1714. X
  1715. X        178.179078,    415.2057519,    3.011e-4,    0.0,
  1716. X        75.899697,    1.5554889,    2.947e-4,    0.0,
  1717. X        .20561421,    2.046e-5,    3e-8,        0.0,
  1718. X        7.002881,    1.8608e-3,    -1.83e-5,    0.0,
  1719. X        47.145944,    1.1852083,    1.739e-4,    0.0,
  1720. X        .3870986,    6.74,         -0.42
  1721. X    },
  1722. X
  1723. X    {   /*     venus... */
  1724. X
  1725. X        342.767053,    162.5533664,    3.097e-4,    0.0,
  1726. X        130.163833,    1.4080361,    -9.764e-4,    0.0,
  1727. X        6.82069e-3,    -4.774e-5,    9.1e-8,        0.0,
  1728. X        3.393631,    1.0058e-3,    -1e-6,        0.0,
  1729. X        75.779647,    .89985,        4.1e-4,        0.0,
  1730. X        .7233316,    16.92,        -4.4
  1731. X    },
  1732. X
  1733. X    {   /*     mars... */
  1734. X
  1735. X        293.737334,    53.17137642,    3.107e-4,    0.0,
  1736. X        3.34218203e2, 1.8407584,    1.299e-4,    -1.19e-6,
  1737. X        9.33129e-2,    9.2064e-5,    7.7e-8,        0.0,
  1738. X        1.850333,    -6.75e-4,    1.26e-5,    0.0,
  1739. X        48.786442,    .7709917,    -1.4e-6,    -5.33e-6,
  1740. X        1.5236883,    9.36,        -1.52
  1741. X    },
  1742. X
  1743. X    {   /*     jupiter... */
  1744. X
  1745. X        238.049257,    8.434172183,    3.347e-4,    -1.65e-6,
  1746. X        1.2720972e1, 1.6099617,    1.05627e-3,    -3.43e-6,
  1747. X        4.833475e-2, 1.6418e-4,    -4.676e-7,    -1.7e-9,
  1748. X        1.308736,    -5.6961e-3,    3.9e-6,        0.0,
  1749. X        99.443414,    1.01053,    3.5222e-4,    -8.51e-6,
  1750. X        5.202561,    196.74,        -9.4
  1751. X    },
  1752. X
  1753. X    {   /*     saturn... */
  1754. X
  1755. X        266.564377,    3.398638567,    3.245e-4,    -5.8e-6,
  1756. X        9.1098214e1, 1.9584158,    8.2636e-4,    4.61e-6,
  1757. X        5.589232e-2, -3.455e-4,    -7.28e-7,    7.4e-10,
  1758. X        2.492519,    -3.9189e-3,    -1.549e-5,    4e-8,
  1759. X        112.790414,    .8731951,    -1.5218e-4,    -5.31e-6,
  1760. X        9.554747,    165.6,        -8.88
  1761. X    },
  1762. X
  1763. X    {   /*     uranus... */
  1764. X
  1765. X        244.19747,    1.194065406,    3.16e-4,    -6e-7,
  1766. X        1.71548692e2, 1.4844328,    2.372e-4,    -6.1e-7,
  1767. X        4.63444e-2,    -2.658e-5,    7.7e-8,        0.0,
  1768. X        .772464,    6.253e-4,    3.95e-5,    0.0,
  1769. X        73.477111,    .4986678,    1.3117e-3,    0.0,
  1770. X        19.21814,    65.8,        -7.19
  1771. X    },
  1772. X
  1773. X    {   /*     neptune... */
  1774. X
  1775. X        84.457994,    .6107942056,    3.205e-4,    -6e-7,
  1776. X        4.6727364e1, 1.4245744,    3.9082e-4,    -6.05e-7,
  1777. X        8.99704e-3,    6.33e-6,    -2e-9,        0.0,
  1778. X        1.779242,    -9.5436e-3,    -9.1e-6,    0.0,
  1779. X        130.681389,    1.098935,    2.4987e-4,    -4.718e-6,
  1780. X        30.10957,    62.2,        -6.87
  1781. X    },
  1782. X
  1783. X    {   /*     pluto...(osculating 1984 jan 21) */
  1784. X
  1785. X        95.3113544,    .3980332167,    0.0,        0.0,
  1786. X        224.017,    0.0,        0.0,        0.0,
  1787. X        .25515,    0.0,        0.0,        0.0,
  1788. X        17.1329,    0.0,        0.0,        0.0,
  1789. X        110.191,    0.0,        0.0,        0.0,
  1790. X        39.8151,    8.2,        -1.0
  1791. X    }
  1792. };
  1793. X
  1794. /* given a modified Julian date, mjd, return the elements for the mean orbit
  1795. X *   at that instant of all the major planets, together with their
  1796. X *   mean daily motions in longitude, angular diameter and standard visual
  1797. X *   magnitude.
  1798. X * plan[i][j] contains all the values for all the planets at mjd, such that
  1799. X *   i = 0..7: mercury, venus, mars, jupiter, saturn, unranus, neptune, pluto;
  1800. X *   j = 0..8: mean longitude, mean daily motion in longitude, longitude of 
  1801. X *     the perihelion, eccentricity, inclination, longitude of the ascending
  1802. X *     node, length of the semi-major axis, angular diameter from 1 AU, and
  1803. X *     the standard visual magnitude (see elements[][] comment, above).
  1804. X */
  1805. pelement (mjd, plan)
  1806. double mjd;
  1807. double plan[8][9];
  1808. {
  1809. X    register double *ep, *pp;
  1810. X    register double t = mjd/36525.;
  1811. X    double aa;
  1812. SHAR_EOF
  1813. true || echo 'restore of pelement.c failed'
  1814. fi
  1815. echo 'End of  part 6'
  1816. echo 'File pelement.c is continued in part 7'
  1817. echo 7 > _shar_seq_.tmp
  1818. exit 0
  1819. -- 
  1820. --
  1821. Molecular Simulations, Inc.            mail: dcmartin@msi.com
  1822. 796 N. Pastoria Avenue                uucp: uunet!dcmartin
  1823. Sunnyvale, California 94086            at&t: 408/522-9236
  1824.