Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

xstarplot3.C

Go to the documentation of this file.
00001 
00016 
00017 //.............................................................................
00018 //    version 1:  May 1989   Piet Hut            email: piet@iassns.bitnet
00019 //                           Institute for Advanced Study, Princeton, NJ, USA
00020 //    version 2:  Dec 1992   Piet Hut      adapted to the new C++-based Starlab
00021 //    version 3:  Dec 1992   Steve McMillan      email: steve@zonker.drexel.edu
00022 //                           Drexel University, Philadelphia, PA, USA
00023 //                           Converted original ASCIIplot to X --- FIRST DRAFT!
00024 //    version 4:  Jan 1994   Biao Lu             email: biao@eagle.drexel.edu
00025 //                           Drexel University, Philadelphia, PA, USA
00026 //                           Use new X interface for movie.
00027 //            Aug/Sep 1994   Cleaned up and expanded, SMcM
00028 //                Sep 1995   Extended to sdyn3 and nonzero radii, SMcM
00029 //                Aug 1996   Added forward/backward step modes, SMcM
00030 //                Aug 1996   Reworked for hdyn and nonzero radii, SMcM
00031 //.............................................................................
00032 //  non-local functions: 
00033 //    xstarplot
00034 //.............................................................................
00035 //  uses:
00036 //    liblux.a (X interface)
00037 //    The X graphics library
00038 //.............................................................................
00039 
00040 // NOTE: On some systems, it appears that overflow can occur, causing the
00041 //       win.lnx and win.lny entries to be overwritten and leading to
00042 //       spurious "log10" errors in draw.c (in lux_set_item, specifically).
00043 //       This isn't fatal, but it should be fixed someday...
00044 
00045 #include "sdyn3.h"
00046 #include "xstarplot.h"
00047 #include "dyn_util.h"
00048 
00049 //-------------------------------------------------------------------------
00050 
00051 // These shouldn't really be global, but keep them this way for now...
00052 
00053 unsigned long  win, dia, instr, colwin;
00054 unsigned long c_energy[10], c_index[N_COLORS+1];
00055 int      init_status = 0;
00056 
00057 // The plotting box is determined completely by origin and lmax3d.
00058 // Its projection onto the viewing plane is xmin, xmax, ymin, ymax
00059 
00060 float  xmin, xmax, ymin, ymax, base_point_size, lmax3d, origin[3];
00061 
00062 int   win_size;
00063 int   point_scale_mode = 0;
00064 int   kx = 1, ky = 2, kproj = 3;
00065 int   origin_star = -1;
00066 int   nodes = 0, links = 0, root = 0;
00067 float theta = 0.33, costheta = cos(0.33), sintheta = sin(0.33), dtheta = 0.03;
00068 float phi = 0.33, cosphi = cos(0.33), sinphi = sin(0.33);
00069 real  local_offset[3];
00070 float delay_time;
00071 float r_factor = 1.0;
00072 
00073 char  graph3d = 1, track = 0, cenergy = 0; // Convenient to distinguish these.
00074 
00075 char   temp_buffer[255];        // Convenient to share this temporary space.
00076 
00077 //-------------------------------------------------------------------------
00078 
00079 // base_point_size defines the size of the default "dot" size on the display.
00080 // It is used (with scaling) for stars and (without scaling) for nodes.
00081 
00082 local void set_base_point_size(float rel_point_size)
00083 {
00084     base_point_size = 2 * SMALL_DOT_SIZE;       // Default point size
00085     if (rel_point_size > 0.0)  base_point_size *= rel_point_size;
00086 }
00087 
00088 local float get_point_size(sdyn3* bi)
00089 {
00090     // Scaling by mass is too extreme.  Use sqrt(mass).
00091     // Also, impose a lower limit on the point size.
00092 
00093     if (point_scale_mode == 1)
00094         return max(SMALL_DOT_SIZE, base_point_size * sqrt(bi->get_mass()));
00095     else if (point_scale_mode == 2)
00096         return max(SMALL_DOT_SIZE, base_point_size * bi->get_radius());
00097     else
00098         return base_point_size;
00099 }
00100 
00101 local void draw_star_point(unsigned long win, float r, float s,
00102                            float actual_point_size, bool f_flag)
00103 
00104 // Plot a point of size actual_point_size at (r,s), filled or unfilled
00105 // according to the value of f_flag.
00106 
00107 {
00108     if (f_flag)
00109         lux_fill_arcf(win, r - actual_point_size/2, s - actual_point_size/2,
00110                       actual_point_size, actual_point_size, 0.0, 360.0);
00111     else
00112         lux_draw_arcf(win, r - actual_point_size/2, s - actual_point_size/2, 
00113                       actual_point_size, actual_point_size, 0.0, 360.0);
00114 }
00115 
00116 local void draw_links_2d(sdyn3* b, float r, float s)
00117 {
00118     for_all_daughters(sdyn3, b, bb) {
00119 
00120         float rr = bb->get_pos()[kx]-local_offset[kx];
00121         float ss = bb->get_pos()[ky]-local_offset[ky];
00122         float stemp;
00123 
00124         // Deal with the 9 possible locations of (rr,ss) with respect
00125         // to the box defined by xmin, xmax, ymin, and ymax.
00126 
00127         if (rr < xmin) {
00128 
00129             if (ss < ymin) {
00130                 float stemp = interp_to_x(r, s, rr, ss, xmin);
00131                 if (stemp >= ymin)
00132                     rr = xmin, ss = stemp;
00133                 else
00134                     rr = interp_to_y(r, s, rr, ss, ymin), ss = ymin;
00135             } else if (ss > ymax) {
00136                 if ((stemp = interp_to_x(r, s, rr, ss, xmin)) <= ymax)
00137                     rr = xmin, ss = stemp;
00138                 else
00139                     rr = interp_to_y(r, s, rr, ss, ymax), ss = ymax;
00140             } else
00141                 ss = interp_to_x(r, s, rr, ss, xmin), rr = xmin;
00142 
00143         } else if (rr > xmax) {
00144 
00145             if (ss < ymin) {
00146                 if ((stemp = interp_to_x(r, s, rr, ss, xmax)) >= ymin)
00147                     rr = xmax, ss = stemp;
00148                 else
00149                     rr = interp_to_y(r, s, rr, ss, ymin), ss = ymin;
00150             } else if (ss > ymax) {
00151                 if ((stemp = interp_to_x(r, s, rr, ss, xmax)) <= ymax)
00152                     rr = xmax, ss = stemp;
00153                 else
00154                     rr = interp_to_y(r, s, rr, ss, ymax), ss = ymax;
00155             } else
00156                 ss = interp_to_x(r, s, rr, ss, xmax), rr = xmax;
00157 
00158         } else {
00159 
00160             if (ss < ymin)
00161                 rr = interp_to_y(r, s, rr, ss, ymin), ss = ymin;
00162             else if (ss > ymax)
00163                 rr = interp_to_y(r, s, rr, ss, ymax), ss = ymax;
00164 
00165         }
00166         lux_draw_linef(win, r, s, rr, ss);
00167     }
00168 }                                          
00169 
00170 local void draw_links_3d(sdyn3* b, float r, float s)
00171 {
00172     for_all_daughters(sdyn3, b, bb) {
00173 
00174         float X = (float)bb->get_pos()[0] - local_offset[0] - origin[0];
00175         float Y = (float)bb->get_pos()[1] - local_offset[1] - origin[1];
00176         float Z = (float)bb->get_pos()[2] - local_offset[2] - origin[2];
00177 
00178         // Don't attempt to deal with the 27 possible locations
00179         // of (X, Y, Z) with respect to the box!
00180 
00181         float rr, ss;
00182         project3d(X, Y, Z, rr, ss, costheta, sintheta, cosphi, sinphi);
00183         lux_draw_linef(win, r, s, rr, ss);
00184     }
00185 }                                          
00186 
00187 local int clean_index(sdyn3* b)
00188 {
00189     int clean_name = 0;
00190 
00191     if (b->get_index() > 0) 
00192         clean_name = b->get_index();
00193     else if (b->get_name()) {
00194         int i = 0;
00195         if (sscanf(b->get_name(), "%d", &i)) clean_name = i;
00196     }
00197 
00198 //  PRC(b->get_index()); PRC(b->get_name()); PRL(clean_name);
00199 
00200     return clean_name;
00201 }
00202 
00203 local int plot_stars(sdyn3* b, int f_flag)
00204 {
00205     int  n_stars = b->n_leaves();
00206     if (b->get_oldest_daughter() == NULL) n_stars = 0;
00207 
00208     int  n_nodes = count_nodes(b);
00209     float r, s;
00210 
00211     if (graph3d) {
00212 
00213         for_all_nodes(sdyn3, b, bi) if (root || bi->get_parent()) {
00214             if (nodes || (bi->get_oldest_daughter() == NULL)) {
00215                 
00216                 float X = (float)bi->get_pos()[0] - local_offset[0] - origin[0];
00217                 float Y = (float)bi->get_pos()[1] - local_offset[1] - origin[1];
00218                 float Z = (float)bi->get_pos()[2] - local_offset[2] - origin[2];
00219                 float actual_point_size = get_point_size(bi);
00220 
00221 
00222                 if (   (X > (-lmax3d + actual_point_size))
00223                     && (X < ( lmax3d - actual_point_size)) 
00224                     && (Y > (-lmax3d + actual_point_size))
00225                     && (Y < ( lmax3d - actual_point_size)) 
00226                     && (Z > (-lmax3d + actual_point_size))
00227                     && (Z < ( lmax3d - actual_point_size))) {
00228 
00229                     // Should really sort by depth here...
00230 
00231                     project3d(X, Y, Z, r, s, costheta, sintheta,
00232                               cosphi, sinphi);
00233 
00234                     // Determine the color to use.
00235 
00236                     bool temp_flag = f_flag;
00237                     if (bi->get_oldest_daughter()) {
00238                         lux_set_color(win, lux_lookup_color(win, "grey"));
00239                         temp_flag =  1 - f_flag;
00240                     } else {
00241                         if (cenergy) {
00242 
00243                             char c;
00244 
00245                             compute_energies(b, bi, c);
00246                             lux_set_color(win, c_energy[c]);
00247 
00248                         } else if (clean_index(bi) > 0) {
00249 
00250                             // Wrap the color map.
00251 
00252                             int ii = clean_index(bi);
00253                             while (ii > N_COLORS) ii -= N_COLORS;
00254 
00255                             lux_set_color(win,c_index[ii]);
00256                         }
00257                     }
00258                     
00259                     if (track) 
00260                         lux_draw_pointf(win, r, s);
00261                     else
00262                         draw_star_point(win, r, s, actual_point_size, f_flag);
00263 
00264                     if (links && bi->get_oldest_daughter())
00265                         draw_links_3d(bi, r, s);
00266                 }
00267             }
00268         }
00269 
00270     } else {
00271 
00272         // Make a list of nodes, *including* the root node if root = 1.
00273         // Root will be at the start of the list if it is being displayed.
00274 
00275         sdyn3ptr* p = new sdyn3ptr[n_nodes+root];
00276 
00277         int ip = 0;
00278         for_all_nodes(sdyn3, b, bi) if (root || bi != b) p[ip++] = bi;
00279         if (ip != n_nodes+root) {
00280             cerr << "plot_stars: n_nodes = " << n_nodes+root
00281                 << " counted " << ip << endl;
00282             exit(1);
00283         }
00284 
00285         // Sort by kproj (note that kproj = 1, 2, or 3 for x, y, or z):
00286 
00287         for (ip = 0; ip < n_nodes+root; ip++)
00288             for (int jp = ip+1; jp < n_nodes+root; jp++)
00289                 if (p[jp]->get_pos()[kproj-1] < p[ip]->get_pos()[kproj-1]) {
00290                     sdyn3ptr bb = p[jp];
00291                     p[jp] = p[ip];
00292                     p[ip] = bb;
00293                 }
00294 
00295         // Plot ordered by depth.
00296 
00297         for (ip = 0; ip < n_nodes+root; ip++) {
00298             sdyn3 * bi = p[ip];
00299             if ( (root || bi != b)
00300                 && (nodes || bi->get_oldest_daughter() == NULL)) {
00301 
00302                 r = (float)bi->get_pos()[kx] - local_offset[kx];
00303                 s = (float)bi->get_pos()[ky] - local_offset[ky];
00304                 float actual_point_size = get_point_size(bi);
00305 
00306                 if (   (r > (xmin + actual_point_size))
00307                     && (r < (xmax - actual_point_size)) 
00308                     && (s > (ymin + actual_point_size))
00309                     && (s < (ymax - actual_point_size)) ) {
00310 
00311                     // Determine the color to use.
00312 
00313                     bool temp_flag = f_flag;
00314                     if (bi->get_oldest_daughter()) {
00315                         lux_set_color(win, lux_lookup_color(win, "grey"));
00316                         temp_flag =  1 - f_flag;
00317                     } else {
00318                         if (cenergy) {
00319 
00320                             char c;
00321 
00322                             compute_energies(b, bi, c);
00323                             lux_set_color(win, c_energy[c]);
00324 
00325                         } else if (clean_index(bi) > 0) {
00326 
00327                             // Wrap the color map.
00328 
00329                             int ii = clean_index(bi);
00330                             while (ii > N_COLORS) ii -= N_COLORS;
00331 
00332                             lux_set_color(win,c_index[ii]);
00333                         }
00334                     }
00335 
00336                     if (track) 
00337                         lux_draw_pointf(win, r, s);
00338                     else
00339                         draw_star_point(win, r, s,
00340                                         actual_point_size, temp_flag);
00341 
00342                     if (links && bi->get_oldest_daughter())
00343                         draw_links_2d(bi, r, s);
00344                 }
00345             }
00346         }
00347         delete p;
00348     }
00349     return n_stars;
00350 }
00351 
00352 local int type(int which)
00353 {
00354     if (which == tracking || which == graph3dim || which == colorenergy)
00355         return BUTTON_WINDOW;
00356     else
00357         return INPUT_WINDOW;
00358 }
00359 
00360 local int subtype(int which)
00361 {
00362     if (which == tracking || which == graph3dim || which == colorenergy)
00363         return CHECK_BUTTON;
00364     else
00365         return NO_TYPE;
00366 }
00367 
00368 local void set_temp_buffer(int which)
00369 {
00370     // Translate ID into a string representing the value.
00371 
00372     char c = -1;
00373     int i = -1;
00374     float f = VERY_LARGE_NUMBER;
00375 
00376     switch (which) {
00377         case colorenergy:       c = cenergy; break;
00378         case tracking:          c = track;   break;
00379         case graph3dim:         c = graph3d; break;
00380         case xminimum:          f = xmin; break;
00381         case xmaximum:          f = xmax; break;
00382         case yminimum:          f = ymin; break;
00383         case ymaximum:          f = ymax; break;
00384         case basepointsize:     f = base_point_size; break;
00385         case pointscalemode:    i = point_scale_mode; break;
00386         case lmax3D:            f = 2*lmax3d; break;
00387         case theta3D:           f = theta; break;
00388         case phi3D:             f = phi; break;
00389         case DelayTime:         f = delay_time; break;
00390         case dtheta3D:          f = dtheta; break;
00391         case Xorigin:           f = origin[0]; break;
00392         case Yorigin:           f = origin[0]; break;
00393         case Zorigin:           f = origin[0]; break;
00394         case view2D:            i = kproj; break;
00395         case originstar:        i = origin_star; break;
00396         default:                cerr << "xstarplot: diag error...\n";
00397     }
00398 
00399     if (f < VERY_LARGE_NUMBER)
00400         sprintf(temp_buffer, "%f", f);
00401     else if (c == -1)
00402         sprintf(temp_buffer, " %d ", i);
00403     else
00404         temp_buffer[0] = c;
00405 }
00406 
00407 local void set_diag_item(int which, char* id, int label_on_left,
00408                          int x1, int x2, int y)
00409 {
00410     set_temp_buffer(which);
00411 
00412     if (label_on_left) {        // label to left of (real) input box
00413 
00414         lux_set_item(dia, which, TEXT_WINDOW, NO_TYPE,
00415                      _R_(x1), _R_(y), strlen(id), id);
00416         lux_set_item(dia, which, INPUT_WINDOW, NO_TYPE,
00417                      _R_(x2), _R_(y), 10, temp_buffer);
00418 
00419     } else {                    // label to right of (integer) input box/button
00420 
00421         if (type(which) == INPUT_WINDOW) {
00422 
00423             lux_set_item(dia, which, INPUT_WINDOW, NO_TYPE,
00424                          _R_(x1), _R_(y), 3, temp_buffer);
00425             lux_set_item(dia, which, TEXT_WINDOW, NO_TYPE,
00426                          _R_(x2), _R_(y), strlen(id), id);
00427 
00428         } else {
00429 
00430             lux_set_item(dia, which, BUTTON_WINDOW, CHECK_BUTTON,
00431                          _R_(x1), _R_(y), 1, temp_buffer);
00432             lux_set_item(dia, which, TEXT_WINDOW, CHECK_BUTTON,
00433                          _R_(x2), _R_(y), strlen(id), id);
00434         }
00435     }
00436 }
00437 
00438 local void initialize_dialog(int xorigin, int yorigin)
00439 {
00440     // Initialize dialog box material (note: y is measured up from bottom!)
00441 
00442     float save = r_factor;
00443     if (r_factor > 1) r_factor = 1;
00444 
00445     int xsize = 550;
00446     int ysize = 550;
00447     if (r_factor <= 0.6) xsize = (int) (xsize / (r_factor/0.6));
00448     dia = lux_open_dialog(xorigin, yorigin, _R_(xsize), _R_(ysize));
00449 
00450     // ---------- 3-D origin info across top of box (special case): ----------
00451 
00452      lux_set_item(dia, Origin, TEXT_WINDOW, NO_TYPE,
00453                  _R_(70), _R_(500), 6, "origin");
00454 
00455     sprintf(temp_buffer, "%f", origin[0]);
00456     lux_set_item(dia, Xorigin, INPUT_WINDOW, NO_TYPE,
00457                  _R_(160), _R_(500), 10, temp_buffer);
00458 
00459     sprintf(temp_buffer, "%f", origin[1]);
00460     lux_set_item(dia, Yorigin, INPUT_WINDOW, NO_TYPE,
00461                  _R_(280), _R_(500), 10, temp_buffer);
00462 
00463     sprintf(temp_buffer, "%f", origin[2]);
00464     lux_set_item(dia, Zorigin, INPUT_WINDOW, NO_TYPE,
00465                  _R_(400), _R_(500), 10, temp_buffer);
00466 
00467 
00468     // ---------- Left-hand column of dialog box: ----------
00469 
00470     //          xmin
00471     //          xmax
00472     //          ymin
00473     //          ymax
00474     //          3-D cube size
00475     //          projection theta
00476     //          projection phi
00477     //          projection dtheta
00478     //          point scale
00479     //          delay time
00480 
00481     // Minima and maxima of 2-D display:
00482 
00483     set_diag_item(xminimum, "xmin", 1, 70, 160, 460);
00484     set_diag_item(xmaximum, "xmax", 1, 70, 160, 420);
00485     set_diag_item(yminimum, "ymin", 1, 70, 160, 380);
00486     set_diag_item(ymaximum, "ymax", 1, 70, 160, 340);
00487 
00488     // 3-D cube size:
00489 
00490     set_diag_item(lmax3D, "cube size", 1, 70, 180, 300);
00491 
00492     // 3-D projection direction:
00493 
00494     set_diag_item(theta3D,  "theta",  1, 70, 180, 260);
00495     set_diag_item(phi3D,    "phi",    1, 70, 180, 220);
00496     set_diag_item(dtheta3D, "dtheta", 1, 70, 180, 180);
00497 
00498     // Point size:
00499 
00500     set_diag_item(basepointsize, "point scale", 1, 70, 180, 140);
00501 
00502     // Delay time:
00503 
00504     set_diag_item(DelayTime, "delay time", 1, 70, 180, 100);
00505 
00506 
00507     // ---------- Right-hand column of dialog box: ----------
00508 
00509     //          origin star
00510     //          2-D view axis
00511     //          3-D plot?
00512 
00513     //          point display mode
00514     //          color by energy?
00515     //          track particles?
00516 
00517     // Origin star:
00518 
00519     set_diag_item(originstar, "Origin Star", 0, 320, 360, 460);
00520 
00521     // 2-D view axis:
00522 
00523     set_diag_item(view2D, "2-D view axis", 0, 320, 360, 420);
00524 
00525     // 3D graphics:
00526 
00527     set_diag_item(graph3dim, "3-D graph", 0, 320, 350, 380);
00528 
00529     // Point display mode
00530 
00531     set_diag_item(pointscalemode, "point display mode", 0, 320, 360, 300);
00532 
00533     // Color by energy:
00534 
00535     set_diag_item(colorenergy, "color by energy", 0, 320, 350, 260);
00536 
00537     // Track particles:
00538 
00539     set_diag_item(tracking, "track particles", 0, 320, 350, 220);
00540 
00541     // lux_draw_palette(dia);
00542 
00543     // OK/cancel:
00544 
00545     lux_set_item(dia, ok, BUTTON_WINDOW, OK_BUTTON,
00546                  _R_(100), _R_(25), 9, "OK, CLEAR");
00547     lux_set_item(dia, ok_keep, BUTTON_WINDOW, OK_KEEP_BUTTON,
00548                  _R_(250), _R_(25), 8, "OK, KEEP");
00549     lux_set_item(dia, cancel, BUTTON_WINDOW, CANCEL_BUTTON,
00550                  _R_(400), _R_(25), 6, "CANCEL");
00551 
00552     r_factor = save;
00553 }
00554 
00555 local void make_relative_to_root(sdyn3* b)
00556 {
00557     vector root_pos = b->get_pos();
00558     vector root_vel = b->get_vel();
00559     for_all_nodes(sdyn3, b, bi) {
00560         bi->inc_pos(-root_pos);
00561         bi->inc_vel(-root_vel);
00562     }
00563 }
00564 
00565 local void update_diag_item(int which)
00566 {
00567     set_temp_buffer(which);
00568     lux_update_itemvalue(dia, which, type(which), subtype(which),
00569                          temp_buffer);
00570 }
00571 
00572 local void get_diag_string(int which) {
00573 }
00574 
00575 // Overloaded function:
00576 
00577 local void read_diag_item(int which, float& f)
00578 {
00579     lux_get_itemvalue(dia, which, type(which), subtype(which),
00580                       temp_buffer);
00581     sscanf(temp_buffer, "%f", &f);
00582 }
00583 
00584 local void read_diag_item(int which, int& i)
00585 {
00586     lux_get_itemvalue(dia, which, type(which), subtype(which),
00587                       temp_buffer);
00588     sscanf(temp_buffer, "%d", &i);
00589 }
00590 
00591 local void read_diag_item(int which, char& c)
00592 {
00593     lux_get_itemvalue(dia, which, type(which), subtype(which),
00594                       temp_buffer);
00595     c = temp_buffer[0];
00596 }
00597 
00598 local void update_from_dialog(bool b_flag)
00599 {
00600     // Read all data from the dialog box.  Note that it is
00601     // important that the box be maintained correctly.
00602     // Any errors in the data displayed in the box will be
00603     // propogated to the "real" data by this procedure.
00604 
00605     read_diag_item(view2D, kproj);
00606     if (kproj == 1)
00607         kx = 1, ky = 2;
00608     else if (kproj == 2)
00609         kx = 2, ky = 0;
00610     else
00611         kx = 0, ky = 1;
00612 
00613     read_diag_item(originstar, origin_star);
00614 
00615     read_diag_item(Xorigin, origin[0]);
00616     read_diag_item(Yorigin, origin[1]);
00617     read_diag_item(Zorigin, origin[2]);
00618 
00619     read_diag_item(lmax3D, lmax3d);
00620     lmax3d /= 2;                        // Display twice lmax3d
00621 
00622     // ------------------------------------------------------
00623 
00624     // NOTE: xmin, xmax, ymin, ymax are IRRELEVANT, since they
00625     // will be forced to be consistent with origin and lmax3d.
00626 
00627     read_diag_item(xminimum, xmin);
00628     read_diag_item(xmaximum, xmax);
00629     read_diag_item(yminimum, ymin);
00630     read_diag_item(ymaximum, ymax);
00631 
00632     set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
00633 
00634     // Make sure entries in the dialog box are consistent:
00635 
00636     update_diag_item(xminimum);
00637     update_diag_item(xmaximum);
00638     update_diag_item(yminimum);
00639     update_diag_item(ymaximum);
00640 
00641     // ------------------------------------------------------
00642 
00643     read_diag_item(basepointsize,base_point_size);
00644 
00645     read_diag_item(theta3D, theta);
00646     costheta = cos(theta);
00647     sintheta = sin(theta);
00648 
00649     read_diag_item(phi3D, phi);
00650     cosphi = cos(phi);
00651     sinphi = sin(phi);
00652 
00653     read_diag_item(dtheta3D, dtheta);
00654 
00655     read_diag_item(DelayTime, delay_time);
00656 
00657     read_diag_item(colorenergy, cenergy);
00658     show_color_scheme(colwin, c_energy, c_index,
00659                       r_factor, cenergy, b_flag, 1);
00660 
00661     read_diag_item(tracking, track);
00662     read_diag_item(graph3dim, graph3d);
00663 
00664     lux_clear_window(win);
00665 
00666     if (graph3d) {
00667         lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d, 
00668                             -FAC3D*lmax3d, FAC3D*lmax3d);
00669         draw3d_axis(win, lmax3d, costheta, sintheta,
00670                     cosphi, sinphi);
00671     } else {
00672         lux_setup_axis(win, xmin, xmax, ymin, ymax);
00673         draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
00674     }
00675 
00676     read_diag_item(pointscalemode, point_scale_mode);
00677 }
00678 
00679 local void show_static_rotation(sdyn3* b, bool f_flag)
00680 {
00681     // Handle static rotation using lux_check_keypress:
00682 
00683     show_instructions(instr, r_factor,
00684                       "Pause...\n  r: rotate, (p,c): continue                ",
00685                       1);
00686 
00687     char rotate = 0;
00688     do {
00689         if (lux_check_keypress(win,'r')) {
00690             show_instructions(instr, r_factor,
00691                       "Rotate... p: pause, c: continue, c: exit rotation     ",
00692                               0);
00693             rotate = 1;
00694 
00695             do {
00696                 theta += dtheta;
00697                 if (theta < 0.0)
00698                     theta += 2*PI;
00699                 else if (theta > PI*2)
00700                     theta -= 2*PI;
00701                 costheta = cos(theta);
00702                 sintheta = sin(theta);
00703                 update_diag_item(theta3D);
00704 
00705                 lux_clear_current_region(win);
00706                 draw3d_axis(win, lmax3d, costheta, sintheta,
00707                             cosphi, sinphi);
00708 
00709                 for_all_leaves(sdyn3, b, bi) {
00710                     float X, Y, Z;
00711                     X = (float)bi->get_pos()[0] - origin[0];
00712                     Y = (float)bi->get_pos()[1] - origin[1];
00713                     Z = (float)bi->get_pos()[2] - origin[2];
00714                     float actual_point_size
00715                         = get_point_size(bi);
00716 
00717                     if (   (X > (-lmax3d + actual_point_size))
00718                         && (X < ( lmax3d - actual_point_size)) 
00719                         && (Y > (-lmax3d + actual_point_size))
00720                         && (Y < ( lmax3d - actual_point_size)) 
00721                         && (Z > (-lmax3d + actual_point_size))
00722                         && (Z < ( lmax3d - actual_point_size))){
00723 
00724                         float r, s;
00725                         project3d(X, Y, Z, r, s,
00726                                   costheta, sintheta,
00727                                   cosphi, sinphi);
00728 
00729                         if (cenergy) {
00730                             char c;
00731                             compute_energies(b, bi, c);
00732                             lux_set_color(win,c_energy[c]);
00733                         } else if (clean_index(bi)>0) {
00734                             if (clean_index(bi) <= N_COLORS)
00735                                 lux_set_color(win,
00736                                               c_index[clean_index(bi)]);
00737                             else
00738                                 lux_set_color(win,c_index[1]);
00739                         }
00740 
00741                         if (track) 
00742                             lux_draw_pointf(win,r,s);
00743                         else
00744                             if (f_flag)
00745                                 lux_fill_arcf(win,
00746                                               r - actual_point_size/2,
00747                                               s - actual_point_size/2, 
00748                                               actual_point_size,
00749                                               actual_point_size,
00750                                               0.0, 360.0);
00751                             else
00752                                 lux_draw_arcf(win,
00753                                               r - actual_point_size/2,
00754                                               s - actual_point_size/2, 
00755                                               actual_point_size,
00756                                               actual_point_size,
00757                                               0.0, 360.0);
00758                     }
00759                 }
00760                 update_with_delay(win, delay_time);
00761 
00762                 if (lux_check_keypress(win,'p')) 
00763                     while(!lux_check_keypress(win,'c'));
00764 
00765             } while(!lux_check_keypress(win,'c'));
00766 
00767             // Flush "c"s from input stream:
00768 
00769             while(lux_check_keypress(win,'c'));
00770         }
00771 
00772     } while(!lux_check_keypress(win,'p')
00773             && !lux_check_keypress(win,'c') && !rotate);
00774 
00775     rotate = 0;
00776     lux_set_color(win,c_energy[default_color]);
00777 }
00778 
00779 local void check_for_input(unsigned long win, sdyn3* b,
00780                            bool b_flag, bool f_flag)
00781 {
00782     // Check for interactive input.
00783     // Loop through the input buffer until no more events remain.
00784 
00785     // lux_next_keypress gets and discards the next key in the input stream.
00786 
00787     char key, string[20], shift, control;
00788 
00789     while (lux_next_keypress(win, &key, string, &shift, &control)) {
00790 
00791         // A "defined" key has been pressed.  See if it is one we want.
00792 
00793         if (key == 0                    // key = 0 for non-ASCII character
00794                                         // e.g. Up, Down, Home, etc.--see win.c
00795             || key == 'h'
00796             || key == 'a') {
00797 
00798             // "Shift" functions:
00799 
00800             int change = 0;
00801 
00802             if (key == 'h')             // Keyboard lookalikes for
00803                 change = 4;             // function keys.
00804             else if (key == 'a')
00805                 change = 5;
00806 
00807             else if (strcmp(string, "Up") == 0) {
00808                 change = ky + 1;
00809                 origin[ky] += lmax3d/2;
00810             } else if (strcmp(string, "Down") == 0) {
00811                 change = ky + 1;
00812                 origin[ky] -= lmax3d/2;
00813             } else if (strcmp(string, "Right") == 0) {
00814                 change = kx + 1;
00815                 origin[kx] += lmax3d/2;
00816             } else if (strcmp(string, "Left") == 0) {
00817                 change = kx + 1;
00818                 origin[kx] -= lmax3d/2;
00819             } else if (strcmp(string, "PgUp") == 0) {
00820                 change = kproj;
00821                 origin[kproj-1] += lmax3d/2;
00822             } else if (strcmp(string, "PgDn") == 0) {
00823                 change = kproj;
00824                 origin[kproj-1] -= lmax3d/2;
00825             } else if (strcmp(string, "Home") == 0)
00826                 change = 4;
00827             else if (strcmp(string, "R11") == 0)
00828                 change = 5;
00829 
00830             if (change) {
00831 
00832                 if (change == 4) {
00833                     origin[kx] = origin[ky] = origin[kproj-1] = 0;
00834                 } else if (change == 5) {
00835 
00836                     real save = lmax3d;
00837                     lmax3d = 0;
00838 
00839                     // Use all dimensions in redetermining the scale!
00840 
00841                     for_all_leaves(sdyn3, b, bi)
00842                         for (int kk = 0; kk < 3; kk++)
00843                             lmax3d = max(lmax3d, abs(bi->get_pos()[kk]
00844                                                      - local_offset[kk]));
00845                 
00846                     // Round lmax3d up to something reasonable:
00847                 
00848                     lmax3d *= 1.2;
00849                     if (lmax3d <= 0) lmax3d = 1;
00850                 
00851                     real m_log = log10(lmax3d);
00852                     int i_log = (int) m_log;
00853                     if (m_log - i_log > 0.699) i_log++;
00854                     real scale = pow(10.0, i_log);
00855                     lmax3d = ((int) (lmax3d/scale) + 1) * scale;
00856 
00857                     origin[kx] = origin[ky] = origin[kproj-1] = 0;              
00858                     base_point_size *= lmax3d/save;
00859                 }
00860 
00861                 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
00862 
00863                 // Update all entries in the dialog box, as needed:
00864 
00865                 update_diag_item(xminimum);
00866                 update_diag_item(xmaximum);
00867                 update_diag_item(yminimum);
00868                 update_diag_item(ymaximum);
00869 
00870                 if (change == 1 || change >= 4) update_diag_item(Xorigin);
00871                 if (change == 2 || change >= 4) update_diag_item(Yorigin);
00872                 if (change == 3 || change >= 4) update_diag_item(Zorigin);
00873 
00874                 if (change == 5) {
00875                     update_diag_item(basepointsize);
00876                     update_diag_item(lmax3D);
00877                 }
00878 
00879                 // No redrawing of axes is needed for 3D graphs for change != 5.
00880                 
00881                 if (!graph3d) {
00882                     lux_clear_window(win);
00883                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
00884                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
00885                 } else if (change == 5) {
00886                     lux_clear_window(win);
00887                     lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d, 
00888                                    -FAC3D*lmax3d, FAC3D*lmax3d);
00889                     draw3d_axis(win, lmax3d, costheta, sintheta,
00890                                 cosphi, sinphi);
00891                 }
00892             }
00893 
00894         } else {                        // Key is the ASCII code.
00895 
00896             // Check for "quit" first.
00897 
00898             if (key == 'q') {
00899                 show_instructions(instr, r_factor,
00900                     "\n   Quitting...                                        ",
00901                                   1);
00902                 lux_exit();     // Note that this is now quick_exit
00903             }
00904 
00905             //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00906 
00907             if (graph3d && !track) {
00908                 int button;
00909 
00910                 // 3-D operations:
00911 
00912                 if (key== 'R') {
00913 
00914                     show_static_rotation(b, f_flag);
00915 
00916                 } else {
00917 
00918                     button = lux_check_buttonpress(win);
00919 
00920                     if (key == '^') {
00921                         phi = phi - dtheta;
00922                         if (phi < -PI) phi = phi + 2.0*PI;
00923                         cosphi = cos(phi);
00924                         sinphi = sin(phi);
00925                         update_diag_item(phi3D);
00926                     } else if (key == 'V') {
00927                         phi = phi + dtheta;
00928                         if (phi > PI) phi = phi - 2.0*PI;
00929                         cosphi = cos(phi);
00930                         sinphi = sin(phi);
00931                         update_diag_item(phi3D);
00932                     } else if (key == '<') {
00933                         theta = theta + dtheta;
00934                         if (theta > 2*PI) theta -= 2*PI;
00935                         costheta = cos(theta);
00936                         sintheta = sin(theta);
00937                         update_diag_item(theta3D);
00938                     } else if (key == '>') {
00939                         theta = theta - dtheta;
00940                         if (theta < 0.0) theta += 2*PI;
00941                         costheta = cos(theta);
00942                         sintheta = sin(theta);
00943                         update_diag_item(theta3D);
00944                     }
00945                 }
00946             }
00947 
00948             //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00949 
00950             if (key == 'p' || key == 'P') {     // Modify base point size
00951 
00952                 if (key == 'p') {
00953                     if (base_point_size > 4*lmax3d/win_size)
00954                         base_point_size /= PFAC;
00955                 } else
00956                     base_point_size *= PFAC;
00957 
00958                 update_diag_item(basepointsize);
00959 
00960             } else if (key == 'n') {            // Toggle tree display
00961 
00962                 nodes = 1 - nodes;
00963                 if (nodes == 0) links = 0;
00964 
00965             } else if (key == 'l') {            // Toggle links/nodes
00966 
00967                 links = 1 - links;
00968                 if (links == 1) nodes = 1;
00969 
00970             } else if (key == 'r') {            // Show root node
00971 
00972                 root = 1 - root;
00973 
00974             } else if (key == 't') {            // Toggle tracking:
00975 
00976                 track = 1 - track;
00977                 update_diag_item(tracking);
00978 
00979             } else if (key == '3' && !graph3d) {            // Enter 3D mode
00980 
00981                 graph3d = 1;
00982                 update_diag_item(graph3dim);
00983                 lux_clear_window(win);
00984                 lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d, 
00985                                -FAC3D*lmax3d, FAC3D*lmax3d);
00986                 draw3d_axis(win, lmax3d, costheta, sintheta, cosphi, sinphi);
00987 
00988             } else if (graph3d &&
00989                        (key == '2' || key == 'x'
00990                           || key == 'y' || key == 'k')) {   // Enter 2D mode
00991 
00992                 graph3d = 0;
00993                 update_diag_item(graph3dim);
00994                 lux_clear_window(win);
00995                 lux_setup_axis(win, xmin, xmax, ymin, ymax);
00996                 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
00997 
00998             } else if (key == 'e') {            // Color by energy
00999 
01000                 cenergy = !cenergy;
01001                 update_diag_item(colorenergy);
01002                 show_color_scheme(colwin, c_energy, c_index,
01003                                   r_factor, cenergy, b_flag, 1);
01004 
01005             } else if (key == '+' || key == '=') {      // Increase delay time
01006 
01007                 delay_time += 0.05;
01008                 update_diag_item(DelayTime);
01009 
01010             } else if (key == '-') {            // Decrease delay time
01011 
01012                 delay_time -= 0.05;
01013                 if (delay_time < 0.0) delay_time = 0.0;
01014                 update_diag_item(DelayTime);
01015 
01016             } if (key == '0') {                 // Set delay time = 0
01017 
01018                 delay_time = 0.0;
01019                 update_diag_item(DelayTime);
01020 
01021                 // Flush the queue:
01022 
01023                 while(lux_check_keypress(win,'+')
01024                       || lux_check_keypress(win,'-'));
01025 
01026             } else if (key == 'z') {            // Zoom in
01027                                                 // (fixed axes and origin)
01028 
01029                 lmax3d /= ZOOM;
01030                 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01031                 base_point_size /= ZOOM;
01032 
01033                 if (graph3d) {
01034                     lux_clear_window(win);
01035                     lux_setup_axis(win,-FAC3D*lmax3d,FAC3D*lmax3d, 
01036                                    -FAC3D*lmax3d, FAC3D*lmax3d);
01037                     draw3d_axis(win, lmax3d, costheta, sintheta,
01038                                 cosphi, sinphi);
01039                 } else {
01040                     lux_clear_window(win);
01041                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01042                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01043                 }
01044 
01045                 update_diag_item(basepointsize);
01046                 update_diag_item(lmax3D);
01047                 update_diag_item(xminimum);
01048                 update_diag_item(xmaximum);
01049                 update_diag_item(yminimum);
01050                 update_diag_item(ymaximum);
01051 
01052             } else if (key == 'Z') {            // Zoom out
01053 
01054                 lmax3d *= ZOOM;
01055                 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01056                 base_point_size *= ZOOM;
01057 
01058                 if (graph3d) {
01059                     lux_clear_window(win);
01060                     lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d, 
01061                                    -FAC3D*lmax3d, FAC3D*lmax3d);
01062                     draw3d_axis(win, lmax3d, costheta, sintheta,
01063                                 cosphi, sinphi);
01064                 } else {
01065                     lux_clear_window(win);
01066                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01067                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01068                 }
01069 
01070                 update_diag_item(basepointsize);
01071                 update_diag_item(lmax3D);
01072                 update_diag_item(xminimum);
01073                 update_diag_item(xmaximum);
01074                 update_diag_item(yminimum);
01075                 update_diag_item(ymaximum);
01076 
01077             } else if (key == 'k') {            // Change projection axis to z
01078                                                 // (fixed origin, scale)
01079                 if (graph3d) {
01080 
01081                     theta = -PI/2;
01082                     phi = PI/2.0;
01083                     costheta = cos(theta);
01084                     sintheta = sin(theta);
01085                     cosphi = cos(phi);
01086                     sinphi = sin(phi);
01087 
01088                     update_diag_item(theta3D);
01089                     update_diag_item(phi3D);
01090 
01091                     while (lux_check_keypress(win,'<')
01092                            || lux_check_keypress(win,'>')
01093                            || lux_check_keypress(win,'^')
01094                            || lux_check_keypress(win,'V') );
01095 
01096                 } else {
01097 
01098                     kproj = 3;
01099                     kx = 0;
01100                     ky = 1;
01101                     set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01102                     lux_clear_window(win);
01103                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01104                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01105 
01106                     update_diag_item(view2D);
01107 
01108                 }
01109 
01110             } else if (key == 'y') {            // Change projection axis to y
01111 
01112                 if (graph3d) {
01113 
01114                     theta = -PI/2.0;
01115                     phi = 0.0;
01116                     costheta = cos(theta);
01117                     sintheta = sin(theta);
01118                     cosphi = cos(phi);
01119                     sinphi = sin(phi);
01120 
01121                     while (lux_check_keypress(win,'<')
01122                            || lux_check_keypress(win,'>')
01123                            || lux_check_keypress(win,'^')
01124                            || lux_check_keypress(win,'V') );
01125 
01126                     update_diag_item(theta3D);
01127                     update_diag_item(phi3D);
01128 
01129                 } else {
01130 
01131                     kproj = 2;
01132                     kx = 2;
01133                     ky = 0;
01134                     set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01135                     lux_clear_window(win);
01136                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01137                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01138 
01139                     update_diag_item(view2D);
01140 
01141                 }
01142 
01143             } else if (key == 'x') {            // Change projection axis to x
01144 
01145                 if (graph3d) {
01146                     theta = 0.0;
01147                     phi = 0.0;
01148                     costheta = cos(theta);
01149                     sintheta = sin(theta);
01150                     cosphi = cos(phi);
01151                     sinphi = sin(phi);
01152 
01153                     while (lux_check_keypress(win,'<')
01154                            || lux_check_keypress(win,'>')
01155                            || lux_check_keypress(win,'^')
01156                            || lux_check_keypress(win,'V') );
01157 
01158                     update_diag_item(theta3D);
01159                     update_diag_item(phi3D);
01160 
01161                 } else {
01162 
01163                     kproj = 1;
01164                     kx = 1;
01165                     ky = 2;
01166                     set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01167                     lux_clear_window(win);
01168                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01169                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01170 
01171                     update_diag_item(view2D);
01172 
01173                 }
01174             }
01175 
01176             // Select new origin: 'o' ==> point in space, 'O' ==> star
01177 
01178             if (key == 'o' && !graph3d) {
01179 
01180                 show_instructions(instr, r_factor,
01181                 " Use mouse-right to select new origin...\n",1);
01182                 float r, s;
01183                 get_mouse_position(win, &r, &s);
01184 
01185                 // Looks like r and s come back in the correct units!
01186 
01187                 origin[kx] = r;
01188                 origin[ky] = s;
01189                 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01190 
01191                 lux_clear_window(win);
01192                 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01193                 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01194 
01195                 origin_star = -1;
01196 
01197                 update_diag_item(Xorigin);
01198                 update_diag_item(Yorigin);
01199                 update_diag_item(Zorigin);
01200                 update_diag_item(xminimum);
01201                 update_diag_item(xmaximum);
01202                 update_diag_item(yminimum);
01203                 update_diag_item(ymaximum);
01204                 update_diag_item(originstar);
01205 
01206             } else if (!graph3d && key == 'O') {
01207 
01208                 show_instructions(instr, r_factor,
01209                 " Use mouse-right to select new origin star...\n",1);
01210                 float r, s;
01211                 get_mouse_position(win, &r, &s);
01212 
01213                 // Looks like r and s come back in the correct units!
01214 
01215                 // Find the star closest to the (2-D) mouse position.
01216 
01217                 origin_star = nearest_index(b, r, s, kx, ky);
01218 
01219                 if (origin_star > 0) {
01220                     for (int kk = 0; kk < 3; kk++) origin[kk] = 0;
01221                     set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01222                 }
01223 
01224                 lux_clear_window(win);
01225                 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01226                 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01227 
01228                 update_diag_item(Xorigin);
01229                 update_diag_item(Yorigin);
01230                 update_diag_item(Zorigin);
01231                 update_diag_item(xminimum);
01232                 update_diag_item(xmaximum);
01233                 update_diag_item(yminimum);
01234                 update_diag_item(ymaximum);
01235                 update_diag_item(originstar);
01236             }
01237 
01238             // -------------------------------------------------------------
01239 
01240             while(lux_check_keypress(win,'r')); // Clean up any replay garbage
01241 
01242             // Idle mode and dialog box input:
01243 
01244             int return_value = 0;
01245 
01246             if (key == 'i') {
01247 
01248                 show_instructions(instr, r_factor,
01249                   " Idle...\n  d: dialog, r: replay, c: continue: q-quit",1);
01250                 return_value = lux_getevent();
01251 
01252             } else if (key == 'd') {
01253 
01254                 show_instructions(instr, r_factor,
01255 "Dialog mode keyboard options\n\n\
01256   Dialog window:\n\
01257     o   OK, keep dialog window\n\
01258     O   OK, close dialog window\n\
01259     c   CANCEL, keep dialog window\n\
01260     C   CANCEL, close dialog window\n\n\
01261   Other windows:\n\
01262     r   replay
01263     c   continue (keep dialog window,\n\
01264                   ignore dialog changes)\n\
01265     q   quit\n\
01266 ",1);
01267                 lux_show_dialog(dia);
01268                 return_value = lux_getevent();
01269             }
01270             
01271             // Update all values if OK button was clicked (clicking
01272             // OK forces a return value of 3).
01273             
01274             if (return_value == 3) update_from_dialog(b_flag);
01275         }
01276     }
01277 }
01278 
01279 /*-----------------------------------------------------------------------------
01280  *  xstarplot.C  --  project the positions of all particles onto the screen
01281  *                   input:   pn: a pointer to a nbody system,
01282  *                              k: the number of the coordinate axis along which
01283  *                                 the projection is directed, with {k,x,y}
01284  *                                 having a right-handed orientation,
01285  *                           xmax: displayed x-axis spans [-xmax, xmax]
01286  *                           ymax: displayed y-axis spans [-ymax, ymax]
01287  *-----------------------------------------------------------------------------
01288  */
01289 
01290 void xstarplot(sdyn3* b, float scale, int k, int d, float lmax,
01291                int point_mode, float rel_point_size,
01292                float D, int ce,
01293                bool b_flag, bool f_flag, bool t_flag,
01294                int init_flag)
01295 {
01296     r_factor = scale;
01297 
01298     if (init_flag == 0) {
01299 
01300         int xorigin, yorigin;
01301 
01302         if (t_flag) nodes = links = 1;
01303 
01304         // Open windows for plotting and instructions, set up color
01305         // schemes, etc.
01306 
01307         if (init_status == 0) initialize_graphics(r_factor, b_flag,
01308                                                   win, instr, colwin,
01309                                                   c_index, c_energy,
01310                                                   win_size, xorigin, yorigin);
01311         lux_clear_window(win);
01312         lux_update_fg(win);
01313         lux_clear_window(colwin);
01314         lux_update_fg(colwin);
01315         lux_clear_window(instr);
01316         lux_update_fg(instr);
01317 
01318         // Determine which axes to plot:
01319 
01320         kproj = k;
01321         switch (kproj) {
01322             case 1:     kx = 1; ky = 2; graph3d = 0; break;
01323             case 2:     kx = 2; ky = 0; graph3d = 0; break;
01324             case 3:     kx = 0; ky = 1; graph3d = 0; break;
01325             default:    cerr << "xstarplot: k = " << k
01326                              << ": illegal value; choose from {1, 2, 3}"
01327                              << endl;
01328                         exit(0);
01329         }
01330 
01331         switch(d) {
01332             case 2:     graph3d = 0;  break;
01333             case 3:     graph3d = 1;  break;
01334             default:    cerr << "xstarplot: d = " << d
01335                              << " illegal value; choose from {2, 3)"
01336                              << endl;
01337                         exit(0);
01338         }
01339 
01340         point_scale_mode = point_mode;
01341 
01342         cenergy = ce?1:0;
01343         show_color_scheme(colwin, c_energy, c_index,
01344                           r_factor, cenergy, b_flag,1);
01345 
01346         delay_time = D;
01347 
01348         if (lmax > 0.0)
01349 
01350             lmax3d = lmax;
01351 
01352         else {
01353 
01354             lmax3d = 0;
01355 
01356             // Use all dimensions in determining the initial scale!
01357 
01358             for_all_leaves(sdyn3, b, bi)
01359                 for (int kk = 0; kk < 3; kk++)
01360                     lmax3d = max(lmax3d, abs(bi->get_pos()[kk]));
01361 
01362             // Round lmax3d up to something reasonable:
01363 
01364             lmax3d *= 1.2;
01365             if (lmax3d <= 0) lmax3d = 1;
01366 
01367             real m_log = log10(lmax3d);
01368             int i_log = (int) m_log;
01369             if (m_log - i_log > 0.699) i_log++;
01370             real scale = pow(10.0, i_log);
01371             lmax3d = ((int) (lmax3d/scale) + 1) * scale;
01372         }
01373 
01374         for (int ko = 0; ko < 3; ko++) origin[ko] = 0;
01375 
01376         set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01377         set_base_point_size(rel_point_size);
01378         
01379         if (graph3d) {
01380             lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d, 
01381                            -FAC3D*lmax3d, FAC3D*lmax3d);      
01382             draw3d_axis(win, lmax3d, costheta, sintheta, cosphi, sinphi);
01383         } else {
01384             lux_setup_axis(win, xmin, xmax, ymin, ymax);
01385             draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01386         }
01387 
01388         // Complete the initialization with the dialog box.
01389 
01390         if (init_status == 0) initialize_dialog(xorigin, yorigin);
01391 
01392         init_status = 1;
01393             
01394     } else if (init_flag < 0) {
01395 
01396         show_instructions(instr, r_factor,
01397                   "End of Data.  Idle now.\n  r: replay, (c,q): quit", 1);
01398 
01399         lux_getevent();
01400         exit(0);
01401 
01402     }
01403 
01404     // lux_getevent();
01405     // exit(1);
01406 
01407     //------------------------------------------------------------------------
01408 
01409     // End of initialization.  Start by (re)drawing axes and instructions.
01410 
01411     if (track == 0) {
01412 
01413         lux_clear_current_region(win);
01414         if (graph3d) draw3d_axis(win, lmax3d, costheta, sintheta,
01415                                  cosphi, sinphi);
01416     }
01417 
01418     show_main_instructions(instr, r_factor, graph3d, 1);
01419 
01420     //------------------------------------------------------------------------
01421 
01422     // Always express all positions and velocities relative to the root node.
01423     // (There is no requirement that the root node be at rest at the origin...)
01424 
01425     make_relative_to_root(b);
01426 
01427     // Determine local offset, if any.
01428 
01429     if (origin_star > 0) {
01430         for_all_leaves(sdyn3, b, bi)
01431             if (clean_index(bi) == origin_star) {
01432                 for (int kk = 0; kk < 3; kk++)
01433                     local_offset[kk] = bi->get_pos()[kk];
01434                 break;
01435             }
01436     } else
01437         for (int kk = 0; kk < 3; kk++) local_offset[kk] = 0;
01438 
01439     // Plot the data points (sorted by kproj-component in the 2D case):
01440 
01441     int n_stars = plot_stars(b, f_flag);
01442 
01443     // Update headers.
01444 
01445     lux_set_color(win, c_energy[default_color]);
01446 
01447     if (graph3d) {
01448 
01449         sprintf(temp_buffer, "N = %d (snapshot #%5d) max=%5.3f",
01450                 n_stars, init_flag + 1, lmax3d);
01451         lux_draw_image_string(win, 0.0, lmax3d*FAC3D, 0.5, temp_buffer, 0);
01452 
01453     } else {
01454 
01455         sprintf(temp_buffer, "N = %d  (snapshot #%5d)", n_stars, init_flag + 1);
01456         lux_draw_image_string(win, (xmin+xmax)/2.0, ymax, 0.5, temp_buffer, 0);
01457 
01458     }
01459 
01460     // Update the display.
01461 
01462     update_with_delay(win, delay_time);
01463 
01464     // Deal with user input.
01465 
01466     check_for_input(win, b, b_flag, f_flag);
01467 }
01468 
01469 /*-----------------------------------------------------------------------------
01470  *  main  --  driver to use  xstarplot()  as a tool. 
01471  *               The argument -a is interpreted as the axis along which to
01472  *            view the N-body system: the number of the coordinate axis along
01473  *            which the projection is directed, with {k,x,y} having a
01474  *            right-handend orientation.
01475  *               If an argument -l is provided, it defines the maximum
01476  *            lengths along the remaining axes.
01477  *-----------------------------------------------------------------------------
01478  */
01479 
01480 main(int argc, char** argv)
01481 {
01482     // Establish some defaults:
01483 
01484     int   k = 3;                // Note x = 1, y = 2, z = 3 here!
01485     int   d = 2;
01486     float D = 0.0;
01487     int   cenergy = 0;
01488     float lmax = -1.0;
01489     int   point_mode = 0;
01490     float rel_point_size = -1.0;
01491     float scale = 1.0;
01492 
01493     bool  b_flag = TRUE;        // if TRUE, the background is black
01494     bool  f_flag = TRUE;        // if TRUE, the star is solid
01495     bool  o_flag = FALSE;       // if TRUE, output stdin to stdout
01496     bool  t_flag = FALSE;       // if TRUE, show tree structure
01497 
01498     check_help();
01499 
01500     extern char *poptarg;
01501     char* params = "a:d:D:efl:op:P:rs:t";
01502     int   c;
01503 
01504     while ((c = pgetopt(argc, argv, params)) != -1)
01505         switch(c) {
01506 
01507             case 'a': k = atoi(poptarg);        // projection axis [z]
01508                       break;
01509             case 'd': d = atoi(poptarg);        // number of dimensions [2]
01510                       break;
01511             case 'D': D = atof(poptarg);        // delay between frames [0]
01512                       break;
01513             case 'e': cenergy = 1;              // color by energy [no]
01514                       break;
01515             case 'f': f_flag = FALSE;           // fill star points [yes]
01516                       break;
01517             case 'l': lmax = atof(poptarg);     // axes +/- lmax [get from data]
01518                       break;
01519             case 'o': o_flag = TRUE;            // output stdin to stdout [no]
01520                       break;
01521             case 'p': point_mode = atoi(poptarg);       // point scale mode [0]
01522                       break;
01523             case 'P': rel_point_size = atof(poptarg);   // point scale factor
01524                       break;
01525             case 'r': b_flag = FALSE;           // black background [yes]
01526                       break;
01527             case 's': scale = atof(poptarg);    // rescale display [1.0]
01528                       break;
01529             case 't': t_flag = TRUE;            // show tree links [no]
01530                       break;
01531             case '?': params_to_usage(cerr, argv[0], params);
01532                       get_help();
01533                       exit(0);
01534         }            
01535 
01536     // Reinterpret scaling if size reflects radius.
01537 
01538     if (point_mode == 2 && rel_point_size > 0)
01539         rel_point_size = 1.0/rel_point_size;
01540 
01541     // Store snapshots in a short circular list.
01542 
01543 #define MAX_SNAP 64
01544 
01545     sdyn3ptr b[MAX_SNAP];
01546 
01547     int gfx_counter = 0;
01548     int snap_counter = -1;
01549     int first_snap = 0;         // The usable list runs from first_snap to
01550     bool wrapped = false;       // snap_counter, wrapping if necessary.
01551 
01552     while (true) {
01553 
01554         // Get index of next location to be filled, and update bookeeping.
01555 
01556         if (++snap_counter >= MAX_SNAP) {
01557             snap_counter = 0;
01558             wrapped = true;
01559         }
01560 
01561         if (wrapped) {
01562 
01563             // Clean up the contents of the element we are about to overwrite.
01564 
01565             rmtree(b[snap_counter]);
01566             first_snap = snap_counter + 1;
01567             if (first_snap >= MAX_SNAP) first_snap = 0;
01568         }
01569 
01570         if ( (b[snap_counter] = get_sdyn3(cin)) == NULL ) break;
01571 
01572         // We have a legal snapshot.  Transform and display it.
01573 
01574         convert_relative_to_absolute(b[snap_counter]);
01575         xstarplot(b[snap_counter], scale, k, d, lmax,
01576                   point_mode, rel_point_size, D, cenergy,
01577                   b_flag, f_flag, t_flag, gfx_counter++);
01578         if (o_flag) put_node(cout, *b[snap_counter]);
01579     }
01580 
01581     if (o_flag) cout << "End of data\n" << flush;
01582 
01583     // Go into idle mode, wait to leave.
01584 
01585     if (--snap_counter < 0) snap_counter = MAX_SNAP - 1;
01586     xstarplot(b[snap_counter], scale, k, d, lmax,
01587               point_mode, rel_point_size, D, cenergy,
01588               b_flag, f_flag, t_flag, -1);
01589 }

Generated at Sun Feb 24 09:57:23 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001