home *** CD-ROM | disk | FTP | other *** search
- /* code to manage the stuff on the "saturn" menu.
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #if defined(__STDC__)
- #include <stdlib.h>
- #endif
- #include <X11/Xlib.h>
- #include <Xm/Xm.h>
- #include <Xm/Form.h>
- #include <Xm/Frame.h>
- #include <Xm/Label.h>
- #include <Xm/PushB.h>
- #include <Xm/Scale.h>
- #include <Xm/RowColumn.h>
- #include <Xm/DrawingA.h>
- #include <Xm/ToggleB.h>
- #include "astro.h"
- #include "circum.h"
-
- #if defined(__STDC__) || defined(__cplusplus)
- #define P_(s) s
- #else
- #define P_(s) ()
- #endif
-
- extern Now *mm_get_now P_((void));
- extern int any_ison P_((void));
- extern void f_double P_((Widget w, char *fmt, double f));
- extern void get_something P_((Widget w, char *resource, char *value));
- extern void register_selection P_((char *name));
- extern void set_xmstring P_((Widget w, char *resource, char *txt));
- extern void timestamp P_((Now *np, Widget w));
-
- void sm_manage P_((void));
- int sm_ison P_((void));
- void sm_selection_mode P_((int whether));
- void sm_cursor P_((Cursor c));
- static void sm_create_form_w P_((void));
- static void sm_set_buttons P_((int whether));
- static void sm_set_a_button P_((Widget pbw, int whether));
- static void sm_bigd_cb P_((Widget w, XtPointer client, XtPointer call));
- static void sm_tags_cb P_((Widget w, XtPointer client, XtPointer call));
- static void sm_scale_cb P_((Widget w, XtPointer client, XtPointer call));
- static void sm_activate_cb P_((Widget w, XtPointer client, XtPointer call));
- static void sm_close_cb P_((Widget w, XtPointer client, XtPointer call));
- static void sm_da_exp_cb P_((Widget w, XtPointer client, XtPointer call));
- void sm_update P_((Now *np, int how_much));
- static double polynom P_((double jd, double a[4]));
- static void saturn P_((double jd, double L_, double a_, double e_, double i_, double omega_, double Omega_, double M_, double *r_p, double *l_p, double *b_p, double *C_p));
- static void anom_calc P_((double M, double e, double *E_p, double *nu_p));
- static double obl_jd P_((double jd));
-
- #undef P_
-
- extern Widget toplevel_w;
- #define XtD XtDisplay(toplevel_w)
-
- static Widget satform_w; /* main form */
- static Widget sda_w; /* drawing area */
- static Widget ringt_w; /* widget containing ring tilt */
- static Widget scale_w; /* size scale */
- static Widget dt_w; /* date/time stamp widget */
- #define NM 8 /* number of moons */
- static Widget s_w[NM][4]; /* the data display widgets */
- enum {X, Y, Z, MAG}; /* s_w column index */
- static int sm_selecting; /* set while our fields are being selected */
- static int bigdots; /* whether we want big dots */
- static int s_tags; /* whether we want tags on the drawing */
-
- #define MAXSCALE 20.0 /* max sclae mag factor */
-
- static struct MoonNames {
- char *full;
- char *tag;
- } mnames[NM] = {
- {"Mimas", "I"},
- {"Enceladus","II"},
- {"Tethys", "III"},
- {"Dione", "IV"},
- {"Rhea", "V"},
- {"Titan", "VI"},
- {"Hyperion","VII"},
- {"Iapetus", "VIII"},
- };
-
- /* called when the saturn menu is activated via the main menu pulldown.
- * if never called before, create and manage all the widgets as a child of a
- * form. otherwise, just toggle whether the form is managed.
- */
- void
- sm_manage ()
- {
- if (!satform_w)
- sm_create_form_w();
-
- if (XtIsManaged(satform_w))
- XtUnmanageChild (satform_w);
- else {
- XtManageChild (satform_w);
- sm_set_buttons(sm_selecting);
- /* rely on expose to do the first draw */
- }
- }
-
- sm_ison()
- {
- return (satform_w && XtIsManaged(satform_w));
- }
-
- /* called by other menus as they want to hear from our buttons or not.
- * the "on"s and "off"s stack - only really redo the buttons if it's the
- * first on or the last off.
- */
- void
- sm_selection_mode (whether)
- int whether; /* whether setting up for plotting or for not plotting */
- {
- sm_selecting += whether ? 1 : -1;
-
- if (satform_w && XtIsManaged(satform_w))
- if (whether && sm_selecting == 1 /* first one to want on */
- || !whether && sm_selecting == 0 /* last one to want off */)
- sm_set_buttons (whether);
- }
-
- /* called to put up or remove the watch cursor. */
- void
- sm_cursor (c)
- Cursor c;
- {
- Window win;
-
- if (satform_w && (win = XtWindow(satform_w))) {
- Display *dsp = XtDisplay(satform_w);
- if (c)
- XDefineCursor (dsp, win, c);
- else
- XUndefineCursor (dsp, win);
- }
- }
-
- static void
- sm_create_form_w()
- {
- Widget w;
- Widget f_w, fr_w, frame_w, r_w, title_w, col_w;
- XmString str;
- Arg args[20];
- int n;
- int i;
-
- /* create form */
- n = 0;
- XtSetArg (args[n], XmNautoUnmanage, False); n++;
- XtSetArg (args[n], XmNdefaultPosition, False); n++;
- XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
- satform_w = XmCreateFormDialog (toplevel_w, "Saturn", args, n);
-
- /* set some stuff in the parent DialogShell.
- * setting XmNdialogTitle in the Form didn't work..
- */
- n = 0;
- XtSetArg (args[n], XmNtitle, "xephem Saturn Table"); n++;
- XtSetValues (XtParent(satform_w), args, n);
-
- /* make top row for ring tilt info */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 50); n++;
- r_w = XmCreatePushButton (satform_w, "SatTiltMsg", args, n);
- XtManageChild (r_w);
- set_xmstring (r_w, XmNlabelString, "Ring tilt (degs):");
- sm_set_a_button (r_w, False);
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNleftPosition, 50); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNuserData, "Saturn.Tilt"); n++;
- w = ringt_w = XmCreatePushButton(satform_w, "SatTilt", args, n);
- XtAddCallback(w, XmNactivateCallback, sm_activate_cb, 0);
- XtManageChild (w);
-
- /* make table title label */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNtopWidget, r_w); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- title_w = XmCreateLabel (satform_w, "SatLab", args, n);
- XtManageChild (title_w);
- set_xmstring (title_w, XmNlabelString,
- " \nMoon positions -- in Saturn Radii");
-
- /* make the moon table, one column at a time */
-
- /* moon designator column */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNtopWidget, title_w); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNentryAlignment, XmALIGNMENT_BEGINNING); n++;
- XtSetArg (args[n], XmNisAligned, True); n++;
- col_w = XmCreateRowColumn (satform_w, "SatDes", args, n);
- XtManageChild (col_w);
-
- n = 0;
- w = XmCreatePushButton (col_w, " ", args, n);
- XtManageChild (w);
- sm_set_a_button (w, False);
-
- for (i = 0; i < NM; i++) {
- n = 0;
- w = XmCreatePushButton (col_w, mnames[i].tag, args, n);
- XtManageChild (w);
- sm_set_a_button (w, False);
- }
-
- /* moon name column */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNtopWidget, title_w); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNleftPosition, 8); n++;
- XtSetArg (args[n], XmNentryAlignment, XmALIGNMENT_BEGINNING); n++;
- XtSetArg (args[n], XmNisAligned, True); n++;
- col_w = XmCreateRowColumn (satform_w, "SatName", args, n);
- XtManageChild (col_w);
-
- n = 0;
- w = XmCreatePushButton (col_w, " ", args, n);
- XtManageChild (w);
- sm_set_a_button (w, False);
-
- for (i = 0; i < NM; i++) {
- n = 0;
- w = XmCreatePushButton (col_w, mnames[i].full, args, n);
- XtManageChild (w);
- sm_set_a_button (w, False);
- }
-
- /* moon X column */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNtopWidget, title_w); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNleftPosition, 30); n++;
- XtSetArg (args[n], XmNentryAlignment, XmALIGNMENT_CENTER); n++;
- XtSetArg (args[n], XmNisAligned, True); n++;
- col_w = XmCreateRowColumn (satform_w, "SatX", args, n);
- XtManageChild (col_w);
-
- n = 0;
- w = XmCreatePushButton (col_w, "SatLab", args, n);
- XtManageChild (w);
- sm_set_a_button (w, False);
- set_xmstring (w, XmNlabelString, "X (+E)");
-
- for (i = 0; i < NM; i++) {
- char *sel;
- sel = XtMalloc (strlen(mnames[i].full) + 3); /* '.X\0' */
- (void) sprintf (sel, "%s.X", mnames[i].full);
- n = 0;
- XtSetArg (args[n], XmNuserData, sel); n++;
- w = s_w[i][X] = XmCreatePushButton(col_w, "SatPB", args, n);
- XtAddCallback(w, XmNactivateCallback, sm_activate_cb, 0);
- XtManageChild (w);
- }
-
- /* moon Y column */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNtopWidget, title_w); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNleftPosition, 50); n++;
- XtSetArg (args[n], XmNentryAlignment, XmALIGNMENT_CENTER); n++;
- XtSetArg (args[n], XmNisAligned, True); n++;
- col_w = XmCreateRowColumn (satform_w, "SatY", args, n);
- XtManageChild (col_w);
-
- n = 0;
- w = XmCreatePushButton (col_w, "SatLab", args, n);
- XtManageChild (w);
- sm_set_a_button (w, False);
- set_xmstring (w, XmNlabelString, "Y (+S)");
-
- for (i = 0; i < NM; i++) {
- char *sel;
- sel = XtMalloc (strlen(mnames[i].full) + 3); /* '.Y\0' */
- (void) sprintf (sel, "%s.Y", mnames[i].full);
- n = 0;
- XtSetArg (args[n], XmNuserData, sel); n++;
- w = s_w[i][Y] = XmCreatePushButton(col_w, "SatPB", args, n);
- XtAddCallback(w, XmNactivateCallback, sm_activate_cb, 0);
- XtManageChild (w);
- }
-
- /* moon Z column */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNtopWidget, title_w); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNleftPosition, 70); n++;
- XtSetArg (args[n], XmNentryAlignment, XmALIGNMENT_CENTER); n++;
- XtSetArg (args[n], XmNisAligned, True); n++;
- col_w = XmCreateRowColumn (satform_w, "SatZ", args, n);
- XtManageChild (col_w);
-
- n = 0;
- w = XmCreatePushButton (col_w, "SatLab", args, n);
- XtManageChild (w);
- sm_set_a_button (w, False);
- set_xmstring (w, XmNlabelString, "Z (+front)");
-
- for (i = 0; i < NM; i++) {
- char *sel;
- sel = XtMalloc (strlen(mnames[i].full) + 3); /* '.Z\0' */
- (void) sprintf (sel, "%s.Z", mnames[i].full);
- n = 0;
- XtSetArg (args[n], XmNuserData, sel); n++;
- w = s_w[i][Z] = XmCreatePushButton(col_w, "SatPB", args, n);
- XtAddCallback(w, XmNactivateCallback, sm_activate_cb, 0);
- XtManageChild (w);
- }
-
- /* moon mag column */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNtopWidget, title_w); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNleftPosition, 90); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNentryAlignment, XmALIGNMENT_CENTER); n++;
- XtSetArg (args[n], XmNisAligned, True); n++;
- col_w = XmCreateRowColumn (satform_w, "SatMag", args, n);
- XtManageChild (col_w);
-
- n = 0;
- w = XmCreatePushButton (col_w, "SatLab", args, n);
- XtManageChild (w);
- sm_set_a_button (w, False);
- set_xmstring (w, XmNlabelString, "Mag");
-
- for (i = 0; i < NM; i++) {
- char *sel;
- sel = XtMalloc (strlen(mnames[i].full) + 5); /* '.Mag\0' */
- (void) sprintf (sel, "%s.Mag", mnames[i].full);
- n = 0;
- XtSetArg (args[n], XmNuserData, sel); n++;
- w = s_w[i][MAG] = XmCreatePushButton(col_w, "SatPB",args,n);
- XtAddCallback(w, XmNactivateCallback, sm_activate_cb, 0);
- XtManageChild (w);
- }
-
- /* make a Form to hold the bottom controls */
-
- n = 0;
- XtSetArg (args[n], XmNfractionBase, 15); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- f_w = XmCreateForm (satform_w, "CtlForm", args, n);
- XtManageChild (f_w);
-
- /* make the close button */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNleftPosition, 1); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 4); n++;
- w = XmCreatePushButton (f_w, "Close", args, n);
- XtAddCallback (w, XmNactivateCallback, sm_close_cb, 0);
- XtManageChild (w);
-
- /* make the tags button in a frame */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNleftPosition, 6); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 9); n++;
- fr_w = XmCreateFrame (f_w, "TagsFr", args, n);
- XtManageChild (fr_w);
- w = XmCreateToggleButton (fr_w, "Tags", args, n);
- XtAddCallback (w, XmNvalueChangedCallback, sm_tags_cb, 0);
- XtManageChild (w);
- s_tags = XmToggleButtonGetState(w);
-
- /* "big dots" toggle button in a frame */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNleftPosition, 11); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 14); n++;
- fr_w = XmCreateFrame(f_w,"BigDotsFr", args, n);
- XtManageChild (fr_w);
- str = XmStringCreate("Big dots", XmSTRING_DEFAULT_CHARSET);
- n = 0;
- XtSetArg (args[n], XmNlabelString, str); n++;
- w = XmCreateToggleButton(fr_w,"BigDots",args,n);
- XtAddCallback(w, XmNvalueChangedCallback, sm_bigd_cb, 0);
- XtManageChild (w);
- XmStringFree (str);
- bigdots = XmToggleButtonGetState(w);
-
- /* make the date/time stamp label */
-
- n = 0;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNbottomWidget, f_w); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- dt_w = XmCreateLabel (satform_w, "DateStamp", args, n);
- timestamp (mm_get_now(), dt_w); /* establishes size */
- XtManageChild (dt_w);
-
- /* make the scale widget
- * attach both top and bottom so it's the one to follow resizing.
- */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNtopWidget, col_w); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNbottomWidget, dt_w); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNmaximum, 100); n++;
- XtSetArg (args[n], XmNminimum, 0); n++;
- XtSetArg (args[n], XmNscaleMultiple, 10); n++;
- XtSetArg (args[n], XmNorientation, XmVERTICAL); n++;
- XtSetArg (args[n], XmNprocessingDirection, XmMAX_ON_TOP); n++;
- scale_w = XmCreateScale (satform_w, "Scale", args, n);
- XtAddCallback (scale_w, XmNdragCallback, sm_scale_cb, 0);
- XtAddCallback (scale_w, XmNvalueChangedCallback, sm_scale_cb, 0);
- XtManageChild (scale_w);
-
- /* make a frame for the drawing area.
- * attach both top and bottom so it's the one to follow resizing.
- */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNtopWidget, col_w); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNbottomWidget, dt_w); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNleftWidget, scale_w); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++;
- frame_w = XmCreateFrame (satform_w, "SatFrame", args, n);
- XtManageChild (frame_w);
-
- /* make a drawing area for drawing the little map */
-
- n = 0;
- sda_w = XmCreateDrawingArea (frame_w, "Map", args, n);
- XtAddCallback (sda_w, XmNexposeCallback, sm_da_exp_cb, 0);
- XtManageChild (sda_w);
- }
-
- /* go through all the buttons pickable for plotting and set whether they
- * should appear to look like buttons or just flat labels.
- */
- static void
- sm_set_buttons (whether)
- int whether; /* whether setting up for plotting or for not plotting */
- {
- int i;
-
- for (i = 0; i < NM; i++) {
- sm_set_a_button (s_w[i][X], whether);
- sm_set_a_button (s_w[i][Y], whether);
- sm_set_a_button (s_w[i][Z], whether);
- sm_set_a_button (s_w[i][MAG], whether);
- }
- sm_set_a_button (ringt_w, whether);
- }
-
- /* set whether the given button looks like a label.
- */
- static void
- sm_set_a_button(pbw, whether)
- Widget pbw;
- int whether;
- {
- static Arg look_like_button[] = {
- {XmNtopShadowColor, (XtArgVal) 0},
- {XmNbottomShadowColor, (XtArgVal) 0},
- {XmNfillOnArm, (XtArgVal) True},
- };
- static Arg look_like_label[] = {
- {XmNtopShadowColor, (XtArgVal) 0},
- {XmNbottomShadowColor, (XtArgVal) 0},
- {XmNfillOnArm, (XtArgVal) False},
- };
- static int called;
- Arg *ap;
- int na;
-
- if (!called) {
- /* get baseline label and shadow appearances.
- */
- Pixel topshad, botshad, bgcol;
- Arg args[20];
- Widget tmpw;
- int n;
-
- n = 0;
- tmpw = XmCreatePushButton (satform_w, "tmp", args, n);
-
- n = 0;
- XtSetArg (args[n], XmNtopShadowColor, &topshad); n++;
- XtSetArg (args[n], XmNbottomShadowColor, &botshad); n++;
- XtSetArg (args[n], XmNbackground, &bgcol); n++;
- XtGetValues (tmpw, args, n);
-
- look_like_button[0].value = topshad;
- look_like_button[1].value = botshad;
- look_like_label[0].value = bgcol;
- look_like_label[1].value = bgcol;
-
- XtDestroyWidget (tmpw);
-
- called = 1;
- }
-
- if (whether) {
- ap = look_like_button;
- na = XtNumber(look_like_button);
- } else {
- ap = look_like_label;
- na = XtNumber(look_like_label);
- }
-
- XtSetValues (pbw, ap, na);
- }
-
- /* callback from the big dots toggle button
- * TODO: really shouldn't get present time, just redo dots in same location.
- */
- /* ARGSUSED */
- static void
- sm_bigd_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- bigdots = XmToggleButtonGetState(w);
- sm_update (mm_get_now(), 1);
- }
-
- /* callback from the tags toggle button
- * TODO: really shouldn't get present time, just redo dots in same location.
- */
- /* ARGSUSED */
- static void
- sm_tags_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- s_tags = XmToggleButtonGetState(w);
- sm_update (mm_get_now(), 1);
- }
-
- /* callback from the scale.
- * TODO: really shouldn't get present time, just redo dots in same location.
- */
- /* ARGSUSED */
- static void
- sm_scale_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- sm_update (mm_get_now(), 1);
- }
-
- /* callback from any of the data menu buttons being activated.
- */
- /* ARGSUSED */
- static void
- sm_activate_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- if (sm_selecting) {
- char *name;
- get_something (w, XmNuserData, (char *)&name);
- register_selection (name);
- }
- }
-
- /* callback from the Close button
- */
- /* ARGSUSED */
- static void
- sm_close_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- XtUnmanageChild (satform_w);
- }
-
- /* callback from either expose or resize of the drawing area.
- */
- /* ARGSUSED */
- static void
- sm_da_exp_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
-
- /* filter out a few oddball cases */
- switch (c->reason) {
- case XmCR_EXPOSE: {
- /* turn off gravity so we get expose events for either shrink or
- * expand.
- */
- static before;
- XExposeEvent *e = &c->event->xexpose;
-
- if (!before) {
- XSetWindowAttributes swa;
- swa.bit_gravity = ForgetGravity;
- XChangeWindowAttributes (e->display, e->window,
- CWBitGravity, &swa);
- before = 1;
- }
- /* wait for the last in the series */
- if (e->count != 0)
- return;
- break;
- }
- default:
- printf ("Unexpected satform_w event. type=%d\n", c->reason);
- exit(1);
- }
-
- sm_update (mm_get_now(), 1);
- }
-
- /* computional support for saturn's detail menu.
- * courtesy Craig Counterman.
- */
-
- typedef struct {
- double alpha, delta; /* position in equinox of date */
- double l, b; /* ecliptical longitude and latitude */
- double lambda, beta; /* geocentric longitude and latitude */
- double Cen; /* Center */
- double psi; /* elongation */
- double r, Delta; /* Distance to sun, and earth */
- double mag, phase, size; /* magnitude, phase (degrees) size (arcsec) */
- double illum_frac; /* illuminated fraction of disk */
- double beta_e;
- /* beta_e, p_n, lambda_e */
- } planet_data_t;
-
-
- typedef struct {
- char *name;
- double alpha, delta; /* position in equinox of date */
- double R, Theta; /* Distance to earth, Theta equinox of date */
- /* times of these events */
- } sun_data_t;
-
- typedef struct {
- double dx, dy, dz; /* relative to planet,
- units of equatorial radius */
- double dalpha, ddelta; /* displacements in RA and dec. */
- double mag;
- char *name;
- } sat_t;
-
- /* functions */
- static void anom_calc();
- static void planet_pos(), sun_pos();
- static double obl_jd();
- static void satsat();
- static void sm_draw_map();
- static double into_range();
-
-
- /* called to recompute and fill in values for the saturn menu.
- * don't bother if it doesn't exist or is unmanaged now or no one is logging.
- */
- void
- sm_update (np, how_much)
- Now *np;
- int how_much;
- {
- static char fmt[] = "%7.3f";
- double jd;
- sat_t saturnsats[8];
- planet_data_t planets;
- sun_data_t sun_data;
- int i;
-
- if (!satform_w)
- return;
- if (!XtIsManaged(satform_w) && !any_ison() && !how_much)
- return;
-
- jd = mjd + MJD0;
- sun_pos(jd, &sun_data);
- planet_pos(jd, sun_data, 4, &planets);
- satsat(jd, planets, saturnsats);
-
- for (i = 0; i < NM; i++) {
- f_double (s_w[i][X], fmt, -saturnsats[i].dx);
- f_double (s_w[i][Y], fmt, -saturnsats[i].dy);
- f_double (s_w[i][Z], fmt, saturnsats[i].dz);
- f_double (s_w[i][MAG], "%5.1f", saturnsats[i].mag);
- }
-
- f_double (ringt_w, fmt, planets.beta_e);
-
- if (XtIsManaged(satform_w)) {
- sm_draw_map (sda_w, saturnsats, planets.beta_e);
- timestamp (np, dt_w);
- }
- }
-
- /* given the loc of the moons, draw a nifty little picture.
- * scale of the locations is in terms of saturn radii == 1.
- */
- static void
- sm_draw_map (w, moons, tilt)
- Widget w;
- sat_t moons[NM];
- double tilt; /* degrees */
- {
- static GC s_fgc, s_bgc, s_xgc;
- static XFontStruct *s_fs;
- static last_nx, last_ny;
- static int cw, ch;
- static Pixmap pm;
- Display *dsp = XtDisplay(w);
- Window win = XtWindow(w);
- Window root;
- double scale;
- int sv;
- char c;
- int x, y;
- unsigned int nx, ny, bw, d;
- int irw, orw, irh, orh, irx, iry, orx, ory;
- int i;
- #define RLW 3 /* ring line width, pixels */
- #define NORM 60.0 /* max Iapetus orbit radius; used to normalize */
- #define MAPSCALE(v) ((v)*((int)nx)/NORM/2*scale)
- #define XCORD(x) ((int)(((int)nx)/2.0 + MAPSCALE(x) + 0.5))
- #define YCORD(y) ((int)(((int)ny)/2.0 - MAPSCALE(y) + 0.5))
-
- if (!s_fgc) {
- XGCValues gcv;
- unsigned int gcm;
- Pixel fg, bg;
-
- gcm = GCForeground;
- get_something (w, XmNforeground, (char *)&fg);
- gcv.foreground = fg;
- s_fgc = XCreateGC (dsp, win, gcm, &gcv);
- s_fs = XQueryFont (dsp, XGContextFromGC (s_fgc));
- cw = s_fs->max_bounds.width;
- ch = s_fs->max_bounds.ascent + s_fs->max_bounds.descent;
-
- gcm = GCForeground;
- get_something (w, XmNbackground, (char *)&bg);
- gcv.foreground = bg;
- s_bgc = XCreateGC (dsp, win, gcm, &gcv);
-
- gcm = GCForeground | GCFunction;
- gcv.foreground = fg ^ bg;
- gcv.function = GXxor;
- s_xgc = XCreateGC (dsp, win, gcm, &gcv);
- }
-
- XmScaleGetValue (scale_w, &sv);
- scale = pow(MAXSCALE, sv/100.0);
-
- XGetGeometry(dsp, win, &root, &x, &y, &nx, &ny, &bw, &d);
- if (!pm || nx != last_nx || ny != last_ny) {
- if (pm)
- XFreePixmap (dsp, pm);
- pm = XCreatePixmap (dsp, win, nx, ny, d);
- last_nx = nx;
- last_ny = ny;
- }
-
- XFillRectangle (dsp, pm, s_bgc, 0, 0, nx, ny);
-
- c = 'E'; XDrawString(dsp, pm, s_fgc, nx-cw-1, ny/2-2, &c, 1);
- c = 'S'; XDrawString(dsp, pm, s_fgc, (nx-cw)/2-1, s_fs->ascent, &c, 1);
-
- /* draw Saturn of radius 1 */
- XFillArc (dsp, pm, s_fgc, XCORD(-1), YCORD(1), 2*(int)MAPSCALE(1),
- 2*(int)MAPSCALE(1), 0, 360*64);
-
- /* rings of radius IRR and ORR.
- * draw rings in front of planet using xor.
- * positive tilt means the southern edge of the rings are in front.
- * always draw the solid s_fgc last in case we are near the ring plane.
- */
- #define IRR 1.528 /* inner edge of ring system */
- #define ORR 2.267 /* outter edge of A ring */
- irh = MAPSCALE(2*IRR*fabs(sin(degrad(tilt))));
- irw = (int)MAPSCALE(2*IRR);
- orh = MAPSCALE(2*ORR*fabs(sin(degrad(tilt))));
- orw = (int)MAPSCALE(2*ORR);
- irx = XCORD(-IRR);
- iry = YCORD(IRR*fabs(sin(degrad(tilt))));
- orx = XCORD(-ORR);
- ory = YCORD(ORR*fabs(sin(degrad(tilt))));
- if (irh < RLW || orh < RLW) {
- /* too near the ring plane to draw a fill ellipse */
- XDrawLine (dsp, pm, s_fgc, orx, ny/2, nx-orx, ny/2);
- } else {
- XDrawArc (dsp, pm, s_xgc, irx, iry, irw, irh,
- tilt > 0.0 ? 0 : 180*64, 180*64-1);
- XDrawArc (dsp, pm, s_xgc, orx, ory, orw, orh,
- tilt > 0.0 ? 0 : 180*64, 180*64-1);
- XDrawArc (dsp, pm, s_fgc, irx, iry, irw, irh,
- tilt > 0.0 ? 180*64 : 0, 180*64-1);
- XDrawArc (dsp, pm, s_fgc, orx, ory, orw, orh,
- tilt > 0.0 ? 180*64 : 0, 180*64-1);
- }
-
- /* draw each moon that is visible.
- */
- for (i = 0; i < NM; i++) {
- double mx = -moons[i].dx;
- double my = -moons[i].dy;
- double mz = moons[i].dz;
- int outside = mx*mx + my*my > 1.0;
- int infront = mz > 0.0;
-
- if (!outside && !infront)
- continue; /* behind saturn */
-
- x = XCORD(mx);
- y = YCORD(my);
- XDrawPoint (dsp, pm, s_xgc, x, y);
- if (bigdots) {
- XDrawPoint(dsp,pm, s_xgc, x+1, y);
- XDrawPoint(dsp,pm, s_xgc, x, y+1);
- XDrawPoint(dsp,pm, s_xgc, x+1, y+1);
- }
- if (s_tags)
- XDrawString(dsp, pm, s_xgc, x-cw/2, y+2*ch,
- mnames[i].tag, strlen(mnames[i].tag));
- }
-
- XCopyArea (dsp, pm, win, s_fgc, 0, 0, nx, ny, 0, 0);
- }
-
-
- /* the following is from starchart */
-
- #define DEG_TO_RAD 0.01745329251994329600
- #define RAD_TO_DEG 57.29577951308232
- #define DSIN(x) (sin((x)*DEG_TO_RAD))
- #define DCOS(x) (cos((x)*DEG_TO_RAD))
- #define DTAN(x) (tan((x)*DEG_TO_RAD))
- #define DASIN(x) (asin(x)*RAD_TO_DEG)
- #define DACOS(x) (acos(x)*RAD_TO_DEG)
- #define DATAN(x) (atan(x)*RAD_TO_DEG)
- #define DATAN2(x,y) (atan2(x,y)*RAD_TO_DEG)
-
- /* siderial Periods of satellites:
- 0.942421813
- 1.370217855
- 1.887802160
- 2.736914742
- 4.517500436
- 15.94542068
- 21.2766088
- 79.3301825
-
- synodic (approx)
- 0.94250436287643326
- 1.3703923657888438
- 1.8881334260185879
- 2.7376110810451278
- 4.519397869256954
- 15.969085530060568
- 21.318764097751611
- 79.919403771981642
-
- semimajor axes
- 185.52
- 238.02
- 294.66
- 377.40
- 527.04
- 1221.83
- 1481.1
- 3561.3
- */
-
- static struct {
- double off; /* angle of satellite at jd 2415020.0 */
- double angvel; /* anbular velocity, degrees per day */
- double r; /* Distance to saturn in saturn radii */
- double mag; /* V(1,0) */
- char *name; /* Name */
- } satsat_data[] = {
- {49.0, 381.96109660576467, 3.092, 3.3, "Mimas"},
- {98.7, 262.69848620527883, 3.967, 2.1, "Enceladus"},
- {263.0, 190.66449173515979, 4.911, 0.6, "Tethys"},
- {101.3, 131.50151330574105, 6.290, 0.8, "Dione"},
- {11.2, 79.656629138338852, 8.784, 0.1, "Rhea"},
- {183.7, 22.543557633424146, 20.364, -1.28, "Titan"},
- {95.0, 16.886532368823739, 24.685, 4.63, "Hyperion"},
- {338.4, 4.5045381097576426, 59.355, 1.5, "Iapetus"}
- };
-
- /* given jd, return sat_t list of major satellites of Saturn */
- /* Ignore many corrections to Saturn's orbit,
- assume moons in circular orbits in Saturn's equatorial plane */
- static void
- satsat(jd, saturn, sats)
- double jd;
- planet_data_t saturn;
- sat_t sats[8];
- {
- double d; /* modified julian date */
- double B; /* Center of saturn */
- double Delta; /* Distance from earth to Saturn */
- double psi; /* Phase angle */
- double u[8]; /* angle */
- double X[8]; /* relative Positions (radii) */
- double Y[8]; /* relative Positions (radii) */
- double Z[8]; /* relative Positions (radii) */
- double dmag;
- int i;
-
- d = jd - MJD0;
-
- Delta = saturn.Delta;
- psi = saturn.phase;
- B = saturn.Cen;
-
-
- dmag = 5.0 * log10(saturn.r*saturn.Delta)
- - 2.5 * log10(saturn.illum_frac);
-
- for (i = 0; i < 8; i++) {
- u[i] = satsat_data[i].off
- + satsat_data[i].angvel * (d - Delta * 0.00577167643528) + psi - B;
- u[i] = into_range(u[i]);
-
- X[i] = satsat_data[i].r * DSIN(u[i]);
- Z[i] = satsat_data[i].r * DCOS(u[i]);
- Y[i] = - satsat_data[i].r * DCOS(u[i]) * DSIN(saturn.beta_e);
-
- sats[i].dx = X[i];
- sats[i].dy = Y[i];
- sats[i].dz = Z[i];
- sats[i].name = satsat_data[i].name;
- sats[i].mag = satsat_data[i].mag + dmag;
- };
- }
-
- typedef struct {
- double L[4];
- double a;
- double e[4];
- double i[4];
- double omega[4];
- double Omega[4];
- double size_1au;
- double mag0;
- } pelements;
-
- static pelements peles = {
-
- /* Saturn */
- {266.564377, 1223.509884, 0.0003245, -0.0000058},
- 9.554747,
- {0.05589232, -0.00034550, -0.000000728, 0.00000000074},
- {2.492519, -0.0039189, -0.00001549, 0.00000004},
- {338.307800, 1.0852207, 0.00097854, 0.00000992},
- {112.790414, 0.8731951, -0.00015218, -0.00000531},
- 165.6,
- -8.88
-
- };
-
- typedef struct {
- double alpha_1, delta_1;
- double W_0, W_dot;
- } rot_els_t;
- static rot_els_t rot_els = {
- 40.09, 83.49,
- 223.60, 810.79390
- };
-
- static double polynom(jd, a)
- double jd;
- double a[4];
- {
- double T;
-
- T = (jd - MJD0)/36525.0;
-
- return (a[0] + a[1]*T + a[2]*T*T + a[3]*T*T*T);
- }
-
- static void saturn();
-
-
- /* Calculate alpha and delta
- from lambda and beta (and epsilon)
- which are from r, Delta, psi, b, l, and Theta (in sun_data)
- which are from u, i (given), and Omega (given)
- u is from L (given), nu, and M
- nu and M are calculated.
- r is from E, a (given) and e (given)
- E is calculated
-
- calculate mag from Delta, size form Delta, phase (== beta).
- */
-
- /* ARGSUSED */
- static void
- planet_pos(jd, sun_data, nplanet, data)
- double jd; /* time, jd */
- sun_data_t sun_data;
- planet_data_t *data;
- {
- double L_, a_, e_, i_, omega_, Omega_, M_;
- double r; /* radius distance to sun */
- double l, b; /* ecliptical longitude and latitude */
- double Delta; /* Distance to earth */
- double lambda, beta; /* geocentric longitude and latitude */
- double alpha, delta; /* R.A. and dec. both degrees */
- double psi; /* elongation */
- double N, D; /* temporary variables */
- double Theta; /* Theta of the sun */
- double epsilon; /* obliquity */
- double Cen; /* center */
-
- L_ = into_range(polynom(jd, peles.L));
- a_ = peles.a;
- e_ = polynom(jd, peles.e);
- i_ = polynom(jd, peles.i);
- omega_ = into_range(polynom(jd, peles.omega));
- Omega_ = into_range(polynom(jd, peles.Omega));
- M_ = into_range(L_ - omega_ - Omega_);
-
- /* Perturb */
- saturn(jd, L_, a_, e_, i_, omega_, Omega_, M_, &r, &l, &b, &Cen);
-
- Theta = sun_data.Theta;
- N = r * DCOS(b) * DSIN(l - Theta);
- D = r * DCOS(b) * DCOS(l - Theta) + sun_data.R;
-
- epsilon = obl_jd(jd);
-
- lambda = into_range(RAD_TO_DEG * atan2(N, D)) + Theta;
- Delta = sqrt(N*N + D*D + (r * DSIN(b))*(r * DSIN(b)));
- beta = RAD_TO_DEG * asin(r * DSIN(b) / Delta);
- psi = RAD_TO_DEG * acos(DCOS(beta) * DCOS(lambda - Theta));
- if (into_range(lambda - Theta) > 180.0)
- psi = -psi;
- alpha = RAD_TO_DEG * atan2(DSIN(lambda)*DCOS(epsilon)
- - DTAN(beta) * DSIN(epsilon),
- DCOS(lambda));
- delta = RAD_TO_DEG * asin(DSIN(beta)*DCOS(epsilon)
- + DCOS(beta)*DSIN(epsilon)*DSIN(lambda));
- alpha = into_range(alpha);
-
- /* should correct for nutation and aberration */
- data->alpha = alpha;
- data->delta = delta;
- data->l = l;
- data->b = b;
- data->lambda = lambda;
- data->beta = beta;
- data->psi = psi;
- data->phase =
- DACOS((r*r + Delta*Delta - sun_data.R*sun_data.R) / (2*r*Delta));
- if (psi < 0) data->phase = -data->phase;
- data->r = r;
- data->Delta = Delta;
- data->illum_frac = ((r+Delta)*(r+Delta) - sun_data.R*sun_data.R)/(4*r*Delta);
- data->Cen = Cen;
-
- data->mag = 5.0 * log10(r*Delta)
- - 2.5 * log10(data->illum_frac)
- + peles.mag0;
-
- data->size = peles.size_1au / Delta;
-
- data->beta_e =
- DASIN(-DSIN(rot_els.delta_1)*DSIN(delta)
- - DCOS(rot_els.delta_1) * DCOS(delta)
- * DCOS(rot_els.alpha_1 - alpha));
-
-
- }
-
- static void saturn(jd, L_, a_, e_, i_, omega_, Omega_, M_, r_p, l_p, b_p, C_p)
- double jd, L_, a_, e_, i_, omega_, Omega_, M_;
- double *r_p, *l_p, *b_p, *C_p;
- {
- double E, nu;
- double r, l, b;
-
- double u; /* argument of latitude */
- double T;
- double A, B, e_pert, a_pert, b_pert, v, zeta;
- double P, Q, V;
- double Szeta, S2zeta, Dzeta, D2zeta,
- DQ, SQ, D2Q, S2Q;
-
- /* for perturbations */
- T = (jd - MJD0)/36525.0;
-
- v = T/5.0 + 0.1;
- P = 237.47555 +3034.9061*T;
- Q = 265.91650 + 1222.1139*T;
- V = 5.0*Q -2.0*P;
- zeta = Q - P;
-
- Szeta = DSIN(zeta);
- S2zeta = DSIN(2*zeta);
- Dzeta = DCOS(zeta);
- D2zeta = DCOS(2*zeta);
- DQ = DCOS(Q);
- D2Q = DCOS(2*Q);
- SQ = DSIN(Q);
- S2Q = DSIN(2*Q);
- A = (-0.814181 + 0.018150*v + 0.016714*v*v)*DSIN(V)
- +(-0.010497 + 0.160906*v - 0.004100*v*v)*DCOS(V);
- A += -0.040786*S2zeta
- + ( (0.008931 + 0.002728*v)*Szeta )*SQ;
-
-
- A += ((0.081344 )*Dzeta+
- 0.015019*D2zeta)*SQ;
- A += ((0.085581 + 0.002494*v)*Szeta
- +(0.025328 - 0.003117*v)*Dzeta
- )*DQ;
-
-
- e_pert = (-.0007927 + .0002548*v +.0000091*v*v)*DSIN(V)
- +(.0013381 + .0001226*v -.0000253*v*v)*DCOS(V)
- ;
- e_pert += .0012415*SQ;
- e_pert += (
- .0026599*Dzeta)*SQ;
- e_pert += (
- -.0012696*Szeta
- )*DQ;
-
-
-
- B = (0.077108 + 0.007186*v - 0.001533*v*v)*DSIN(V)
- +(0.045803 - 0.014766*v - 0.000536*v*v)*DCOS(V);
- B +=
- (-0.075825*Szeta
- -0.024839*S2zeta
- )*SQ;
- B += (-0.072586
- -0.150383*Dzeta
- +0.026897*D2zeta
- )*DQ;
- B += (-(0.013597 +0.001719*v)*Szeta
- )*S2Q;
- B += ( (-0.013667 + 0.001239*v)*Szeta
- +0.011981*S2zeta
- +(0.014861 + 0.001136*v)*Dzeta
- -(0.013064 + 0.001628*v)*D2zeta)*D2Q;
-
- a_pert = .033629*Dzeta
- -.003081*D2zeta ;
- a_pert += (.001098
- -.002812*Szeta
- +.002138*Dzeta
- )*SQ;
- a_pert += ( -.000890
- +.002206*Szeta)*DQ;
- L_ += A;
- M_ += A - B / e_;
- e_ += e_pert;
- a_ += a_pert;
- omega_ += B;
-
- /* Calculate E and nu */
- anom_calc(M_, e_, &E, &nu);
- r = a_ * (1 - e_ * DCOS(E));
-
-
- u = L_ + nu - M_ - Omega_;
- *C_p = nu - M_;
- l = into_range(RAD_TO_DEG * atan2(DCOS(i_) * DSIN(u), DCOS(u)) + Omega_);
- b = RAD_TO_DEG * asin(DSIN(u)*DSIN(i_));
-
- b_pert = 0.000747*Dzeta*SQ
- +0.001069*Dzeta*DQ
- +0.002108*S2zeta*S2Q;
- b_pert += 0.001261*D2zeta*S2Q
- +0.001236*S2zeta*D2Q
- -0.002075*D2zeta*D2Q;
-
- *r_p = r;
- *l_p = l;
- *b_p = b + b_pert;
- }
-
- static void anom_calc(M, e, E_p, nu_p)
- double M, e, *E_p, *nu_p;
- {
- double corr, e_0, E_0, E_1;
-
- e_0 = e * RAD_TO_DEG;
-
- corr = 1;
- E_0 = M;
- while (corr > 0.00001) {
- corr = (M + e_0 * DSIN(E_0) - E_0)/(1 - e * DCOS(E_0));
- E_1 = E_0 + corr;
- if (corr < 0) corr *= -1.0;
- E_0 = E_1;
- };
-
- *E_p = E_1;
-
- *nu_p = 2.0 * RAD_TO_DEG * atan(sqrt((1+e)/(1-e))*DTAN(E_1/2));
- }
-
-
-
-
- /* Obliquity epsilon
- epsilon = 23.439291 - 0.0130042* T - 0.00000016* T*T - 0.000000504* T*T*T;
- */
- static double
- obl_jd(jd)
- double jd;
- {
- double T = (jd - 2451545.0)/36525.0;
-
- return (23.439291 - 0.0130042* T - 0.00000016* T*T - 0.000000504* T*T*T);
- }
-
-
-
- static double
- into_range(ang)
- double ang;
- {
- long i;
-
- i = (long)floor(ang/360.0);
-
- ang = ang - i * 360;
-
- return(ang);
- }
-
- static void
- sun_pos(jd, sun_data)
- double jd;
- sun_data_t *sun_data;
- {
- double L, M, Theta, R;
- double e, nu, E;
- double T;
- double epsilon;
-
- T = (jd - MJD0)/36525.0;
-
- M = into_range(358.47583 + 35999.04975*T - 0.000150*T*T - 0.0000033*T*T*T);
- e = 0.01675104 - 0.0000418*T - 0.000000126*T*T;
- L = into_range(279.69668 + 36000.76892*T + 0.0003025*T*T);
- anom_calc(M, e, &E, &nu);
- Theta = into_range(L + nu - M);
- R = 1.0000002*(1.0 - e * DCOS(E));
-
-
- sun_data->R = R;
- sun_data->Theta = Theta;
- epsilon = 23.439291 - 0.0130042* T - 0.00000016* T*T - 0.000000504* T*T*T;
- sun_data->alpha
- = into_range(RAD_TO_DEG * atan2(DCOS(epsilon)*DSIN(Theta), DCOS(Theta)));
- sun_data->delta =
- RAD_TO_DEG * asin(DSIN(epsilon)*DSIN(Theta));
- }
-