Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

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

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