Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

xhrdplot.C

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

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