00001 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 #include "worldline.h"
00064 #include "xstarplot.h"
00065 #include "dyn_util.h"
00066 
00067 
00068 
00069 
00070 #define DYN pdyn
00071 #define DYNPTR pdynptr
00072 
00073 
00074 
00075 
00076 
00077 
00078 unsigned long  win, dia, instr, colwin;
00079 unsigned long c_energy[10], c_index[N_COLORS+1];
00080 int      init_status = 0;
00081 
00082 
00083 
00084 
00085 float  xmin, xmax, ymin, ymax, base_point_size, lmax3d, origin[3];
00086 
00087 int   win_size;
00088 int   point_scale_mode = 0;
00089 int   kx = 1, ky = 2, kproj = 3;
00090 int   origin_star = -1;
00091 int   nodes = 0, links = 0, root = 0, multiples = 0, unperturbed = 0;
00092 float theta = 0.33, costheta = cos(0.33), sintheta = sin(0.33), dtheta = 0.03;
00093 float phi = 0.33, cosphi = cos(0.33), sinphi = sin(0.33);
00094 real  local_offset[3];
00095 
00096 #define MIN_DELAY  1.0
00097 float delay_time = MIN_DELAY;
00098 
00099 float r_factor = 1.0;
00100 
00101 char  graph3d = 1, track = 0, cenergy = 0; 
00102 
00103 char   temp_buffer[255];        
00104 
00105 
00106 
00107 
00108 
00109 
00110 local void set_base_point_size(DYN* b, float rel_point_size)
00111 {
00112     base_point_size = 2 * SMALL_DOT_SIZE;       
00113 
00114     if (point_scale_mode == 1) {
00115 
00116         
00117 
00118         real m_tot = 0;
00119         real n_tot = 0;
00120         for_all_leaves(DYN, b, bi) {
00121             n_tot++;
00122             m_tot += bi->get_mass();
00123         }
00124 
00125         if (n_tot > 0) base_point_size /= sqrt(m_tot/n_tot);    
00126 
00127     } else if (point_scale_mode == 2 || point_scale_mode == 3) {
00128 
00129         
00130         
00131 
00132         if (point_scale_mode == 2 && rel_point_size < 0) {
00133 
00134             base_point_size = 1;
00135 
00136         } else {
00137 
00138             
00139 
00140             real r_tot = 0;
00141             real n_tot = 0;
00142             for_all_leaves(DYN, b, bi) {
00143                 n_tot++;
00144                 r_tot += bi->get_radius();
00145             }
00146 
00147             if (n_tot > 0) {
00148                 if (point_scale_mode == 2)
00149                     base_point_size /= r_tot/n_tot;
00150                 else
00151                     base_point_size /= sqrt(r_tot/n_tot);
00152             }
00153         }
00154     }
00155 
00156     
00157 
00158     if (rel_point_size > 0.0)  base_point_size *= rel_point_size;
00159 }
00160 
00161 local float get_point_size(DYN* bi)
00162 {
00163     
00164     
00165 
00166     
00167     
00168 
00169     if (point_scale_mode == 1)
00170         return max(SMALL_DOT_SIZE,
00171                    base_point_size * sqrt(bi->get_mass()));
00172     else if (point_scale_mode == 2)
00173         return max(SMALL_DOT_SIZE,
00174                    base_point_size * min(20., bi->get_radius()));
00175     else if (point_scale_mode == 3)
00176         return max(SMALL_DOT_SIZE,
00177                    base_point_size * min(20., sqrt(bi->get_radius())));
00178     else
00179         return base_point_size;
00180 }
00181 
00182 local void draw_star_point(unsigned long win, float r, float s,
00183                            float actual_point_size, bool f_flag)
00184 
00185 
00186 
00187 
00188 {
00189     
00190     
00191 
00192     if (f_flag) {
00193         lux_fill_arcf(win, r - actual_point_size/2, s - actual_point_size/2,
00194                       actual_point_size, actual_point_size, 0.0, 360.0);
00195         if (actual_point_size < 12*lmax3d/win_size) return;
00196         actual_point_size *= 0.8;
00197     }
00198     lux_draw_arcf(win, r - actual_point_size/2, s - actual_point_size/2, 
00199                   actual_point_size, actual_point_size, 0.0, 360.0);
00200 }
00201 
00202 local void draw_links_2d(DYN* b, float r, float s)
00203 {
00204     for_all_daughters(DYN, b, bb) {
00205 
00206         float rr = bb->get_pos()[kx]-local_offset[kx];
00207         float ss = bb->get_pos()[ky]-local_offset[ky];
00208         float stemp;
00209 
00210         
00211         
00212 
00213         if (rr < xmin) {
00214 
00215             if (ss < ymin) {
00216                 float stemp = interp_to_x(r, s, rr, ss, xmin);
00217                 if (stemp >= ymin)
00218                     rr = xmin, ss = stemp;
00219                 else
00220                     rr = interp_to_y(r, s, rr, ss, ymin), ss = ymin;
00221             } else if (ss > ymax) {
00222                 if ((stemp = interp_to_x(r, s, rr, ss, xmin)) <= ymax)
00223                     rr = xmin, ss = stemp;
00224                 else
00225                     rr = interp_to_y(r, s, rr, ss, ymax), ss = ymax;
00226             } else
00227                 ss = interp_to_x(r, s, rr, ss, xmin), rr = xmin;
00228 
00229         } else if (rr > xmax) {
00230 
00231             if (ss < ymin) {
00232                 if ((stemp = interp_to_x(r, s, rr, ss, xmax)) >= ymin)
00233                     rr = xmax, ss = stemp;
00234                 else
00235                     rr = interp_to_y(r, s, rr, ss, ymin), ss = ymin;
00236             } else if (ss > ymax) {
00237                 if ((stemp = interp_to_x(r, s, rr, ss, xmax)) <= ymax)
00238                     rr = xmax, ss = stemp;
00239                 else
00240                     rr = interp_to_y(r, s, rr, ss, ymax), ss = ymax;
00241             } else
00242                 ss = interp_to_x(r, s, rr, ss, xmax), rr = xmax;
00243 
00244         } else {
00245 
00246             if (ss < ymin)
00247                 rr = interp_to_y(r, s, rr, ss, ymin), ss = ymin;
00248             else if (ss > ymax)
00249                 rr = interp_to_y(r, s, rr, ss, ymax), ss = ymax;
00250 
00251         }
00252         lux_draw_linef(win, r, s, rr, ss);
00253     }
00254 }                                          
00255 
00256 local void draw_links_3d(DYN* b, float r, float s)
00257 {
00258     for_all_daughters(DYN, b, bb) {
00259 
00260         float X = (float)bb->get_pos()[0] - local_offset[0] - origin[0];
00261         float Y = (float)bb->get_pos()[1] - local_offset[1] - origin[1];
00262         float Z = (float)bb->get_pos()[2] - local_offset[2] - origin[2];
00263 
00264         
00265         
00266 
00267         float rr, ss;
00268         project3d(X, Y, Z, rr, ss, costheta, sintheta, cosphi, sinphi);
00269         lux_draw_linef(win, r, s, rr, ss);
00270     }
00271 }                                          
00272 
00273 local int clean_index(DYN* b)
00274 {
00275     int clean_name = 0;
00276 
00277     if (b->get_index() > 0) 
00278         clean_name = b->get_index();
00279     else if (b->get_name()) {
00280         int i = 0;
00281         if (sscanf(b->get_name(), "%d", &i)) clean_name = i;
00282     }
00283 
00284     return clean_name;
00285 }
00286 
00287 static real max_cm = 2;
00288 
00289 local void plot_star(DYN *bi, float r, float s,
00290                      float actual_point_size, int f_flag)
00291 {
00292     
00293     
00294     
00295 
00296     
00297 
00298     bool temp_flag = f_flag;
00299     if (bi->get_oldest_daughter()) {
00300 
00301         lux_set_color(win, lux_lookup_color(win, "grey"));
00302         temp_flag =  1 - f_flag;
00303 
00304     } else {
00305 
00306         if (cenergy) {
00307 
00308             char c;
00309 
00310             compute_energies(bi->get_root(), bi, c);
00311             lux_set_color(win, c_energy[c]);
00312 
00313         } else if (clean_index(bi) > 0) {
00314 
00315             
00316 
00317             int ii = clean_index(bi);
00318             while (ii > N_COLORS) ii -= N_COLORS;
00319 
00320             lux_set_color(win,c_index[ii]);
00321         }
00322     }
00323 
00324     if (track)
00325 
00326         lux_draw_pointf(win, r, s);
00327 
00328     else {
00329 
00330         real scale = 1.0;
00331         real reset_grey = false;
00332 
00333         
00334         
00335         
00336         
00337         
00338         
00339         
00340         
00341         
00342         
00343 
00344         DYN *od = bi->get_oldest_daughter();
00345 
00346         if (multiples && od && bi->is_top_level_node()) {
00347 
00348             if (bi->n_leaves() == 2) {
00349 
00350                 
00351 
00352                 if (od->get_kepler() == (kepler*)2) {
00353 
00354                     
00355 
00356                     scale = 2.0;
00357                     lux_set_color(win, lux_lookup_color(win, "purple"));
00358                     reset_grey = true;
00359 
00360                 } else if (!od->get_kepler()) {
00361 
00362                     
00363 
00364                     scale = 2.0;
00365                     lux_set_color(win, lux_lookup_color(win, "lightblue"));
00366                     reset_grey = true;
00367                 }
00368 
00369             } else {
00370 
00371                 
00372 
00373                 scale = 4.0;
00374                 if (bi->n_leaves() == 3)
00375                     lux_set_color(win, lux_lookup_color(win, "yellow"));
00376                 else if (bi->n_leaves() == 4)
00377                     lux_set_color(win, lux_lookup_color(win, "orange"));
00378                 else
00379                     lux_set_color(win, lux_lookup_color(win, "red"));
00380 
00381                 reset_grey = true;
00382             }
00383         }
00384 
00385         if (unperturbed && od
00386             && od->get_kepler() && od->get_kepler() != (kepler*)2) {
00387 
00388             
00389 
00390             scale = 2.0;
00391             lux_set_color(win, lux_lookup_color(win, "blue"));
00392             reset_grey = true;
00393         }
00394 
00395         
00396 
00397         real psize = scale*actual_point_size;
00398 
00399         if (scale > 1.0) {
00400 
00401             
00402             
00403             
00404             
00405 
00406             real dr = abs(od->get_pos()
00407                            - od->get_younger_sister()->get_pos());
00408             real dv2 = square(od->get_vel()
00409                                - od->get_younger_sister()->get_vel());
00410 
00411             real sma2 = 1 / (1/dr - 0.5*dv2/bi->get_mass());    
00412 
00413             
00414 
00415             if (sma2 <= 0) {
00416                 sma2 = -sma2;
00417                 if (scale == 2.0)
00418                     lux_set_color(win, lux_lookup_color(win, "green"));
00419             }
00420 
00421             
00422 
00423             if (sma2 > max_cm) sma2 = max(dr, max_cm);
00424 
00425             psize = max(psize, 1.2*sma2);
00426             
00427         }
00428 
00429         draw_star_point(win, r, s, psize, temp_flag);
00430 
00431         if (bi->get_oldest_daughter()
00432             && psize > 3*actual_point_size) {
00433             lux_set_color(win, lux_lookup_color(win, "grey"));
00434             draw_star_point(win, r, s, actual_point_size, temp_flag);
00435         }
00436 
00437         if (links && reset_grey)
00438             lux_set_color(win, lux_lookup_color(win, "grey"));
00439     }
00440 }
00441 
00442 local int plot_all_stars(DYN* b, int f_flag)
00443 {
00444     int  n_stars = b->n_leaves();
00445     if (b->get_oldest_daughter() == NULL) n_stars = 0;
00446 
00447     int  n_nodes = count_nodes(b);
00448     float r, s;
00449 
00450     if (graph3d) {
00451 
00452         for_all_nodes(DYN, b, bi) if (root || bi->get_parent()) {
00453             if (nodes
00454                 || (multiples && bi->is_top_level_node())
00455                 || (unperturbed && bi->get_oldest_daughter())
00456                 || (bi->get_oldest_daughter() == NULL)) {
00457                 
00458                 float X = (float)bi->get_pos()[0] - local_offset[0] - origin[0];
00459                 float Y = (float)bi->get_pos()[1] - local_offset[1] - origin[1];
00460                 float Z = (float)bi->get_pos()[2] - local_offset[2] - origin[2];
00461 
00462                 float actual_point_size = get_point_size(bi);
00463 
00464                 if (   (X > (-lmax3d + actual_point_size))
00465                     && (X < ( lmax3d - actual_point_size)) 
00466                     && (Y > (-lmax3d + actual_point_size))
00467                     && (Y < ( lmax3d - actual_point_size)) 
00468                     && (Z > (-lmax3d + actual_point_size))
00469                     && (Z < ( lmax3d - actual_point_size))) {
00470 
00471                     
00472 
00473                     project3d(X, Y, Z, r, s,
00474                               costheta, sintheta,
00475                               cosphi, sinphi);
00476 
00477                     plot_star(bi, r, s, actual_point_size, f_flag);
00478 
00479                     if (links && bi->get_oldest_daughter())
00480                         draw_links_3d(bi, r, s);
00481                 }
00482             }
00483         }
00484 
00485     } else {
00486 
00487         
00488         
00489 
00490         DYNPTR* p = new DYNPTR[n_nodes+root];
00491 
00492         int ip = 0;
00493         for_all_nodes(DYN, b, bi) if (root || bi != b) p[ip++] = bi;
00494         if (ip != n_nodes+root) {
00495             cerr << "plot_all_stars: n_nodes = " << n_nodes+root
00496                 << " counted " << ip << endl;
00497             exit(1);
00498         }
00499 
00500         
00501 
00502         for (ip = 0; ip < n_nodes+root; ip++)
00503             for (int jp = ip+1; jp < n_nodes+root; jp++)
00504                 if (p[jp]->get_pos()[kproj-1] < p[ip]->get_pos()[kproj-1]) {
00505                     DYNPTR bb = p[jp];
00506                     p[jp] = p[ip];
00507                     p[ip] = bb;
00508                 }
00509 
00510         
00511 
00512         for (ip = 0; ip < n_nodes+root; ip++) {
00513             DYN * bi = p[ip];
00514             if ( (root || bi != b)
00515                 && (nodes
00516                     || (multiples && bi->is_top_level_node())
00517                     || (unperturbed && bi->get_oldest_daughter())
00518                     || (bi->get_oldest_daughter() == NULL))) {
00519 
00520                 r = (float)bi->get_pos()[kx] - local_offset[kx];
00521                 s = (float)bi->get_pos()[ky] - local_offset[ky];
00522 
00523                 float actual_point_size = get_point_size(bi);
00524 
00525                 if (   (r > (xmin + actual_point_size))
00526                     && (r < (xmax - actual_point_size)) 
00527                     && (s > (ymin + actual_point_size))
00528                     && (s < (ymax - actual_point_size)) ) {
00529 
00530                     if (bi->get_index() != -42)
00531                         plot_star(bi, r, s, actual_point_size, f_flag);
00532 
00533                     if (links && bi->get_oldest_daughter())
00534                         draw_links_2d(bi, r, s);
00535                 }
00536             }
00537         }
00538         delete [] p;
00539     }
00540     return n_stars;
00541 }
00542 
00543 local int type(int which)
00544 {
00545     if (which == tracking || which == graph3dim || which == colorenergy)
00546         return BUTTON_WINDOW;
00547     else
00548         return INPUT_WINDOW;
00549 }
00550 
00551 local int subtype(int which)
00552 {
00553     if (which == tracking || which == graph3dim || which == colorenergy)
00554         return CHECK_BUTTON;
00555     else
00556         return NO_TYPE;
00557 }
00558 
00559 local void set_temp_buffer(int which)
00560 {
00561     
00562 
00563     char c = -1;
00564     int i = -1;
00565     float f = 1.e30;    
00566 
00567     switch (which) {
00568         case colorenergy:       c = cenergy; break;
00569         case tracking:          c = track;   break;
00570         case graph3dim:         c = graph3d; break;
00571         case xminimum:          f = xmin; break;
00572         case xmaximum:          f = xmax; break;
00573         case yminimum:          f = ymin; break;
00574         case ymaximum:          f = ymax; break;
00575         case basepointsize:     f = base_point_size; break;
00576         case pointscalemode:    i = point_scale_mode; break;
00577         case lmax3D:            f = 2*lmax3d; break;
00578         case theta3D:           f = theta; break;
00579         case phi3D:             f = phi; break;
00580         case DelayTime:         f = delay_time; break;
00581         case dtheta3D:          f = dtheta; break;
00582         case Xorigin:           f = origin[0]; break;
00583         case Yorigin:           f = origin[0]; break;
00584         case Zorigin:           f = origin[0]; break;
00585         case view2D:            i = kproj; break;
00586         case originstar:        i = origin_star; break;
00587         default:                cerr << "xstarplot22: diag error...\n";
00588     }
00589 
00590     if (f < 1.e30)
00591         sprintf(temp_buffer, "%f", f);
00592     else if (c == -1)
00593         sprintf(temp_buffer, " %d ", i);
00594     else
00595         temp_buffer[0] = c;
00596 }
00597 
00598 local void set_diag_item(int which, char* id, int label_on_left,
00599                          int x1, int x2, int y)
00600 {
00601     set_temp_buffer(which);
00602 
00603     if (label_on_left) {        
00604 
00605         lux_set_item(dia, which, TEXT_WINDOW, NO_TYPE,
00606                      _R_(x1), _R_(y), strlen(id), id);
00607         lux_set_item(dia, which, INPUT_WINDOW, NO_TYPE,
00608                      _R_(x2), _R_(y), 10, temp_buffer);
00609 
00610     } else {                    
00611 
00612         if (type(which) == INPUT_WINDOW) {
00613 
00614             lux_set_item(dia, which, INPUT_WINDOW, NO_TYPE,
00615                          _R_(x1), _R_(y), 3, temp_buffer);
00616             lux_set_item(dia, which, TEXT_WINDOW, NO_TYPE,
00617                          _R_(x2), _R_(y), strlen(id), id);
00618 
00619         } else {
00620 
00621             lux_set_item(dia, which, BUTTON_WINDOW, CHECK_BUTTON,
00622                          _R_(x1), _R_(y), 1, temp_buffer);
00623             lux_set_item(dia, which, TEXT_WINDOW, CHECK_BUTTON,
00624                          _R_(x2), _R_(y), strlen(id), id);
00625         }
00626     }
00627 }
00628 
00629 local void initialize_dialog(int xorigin, int yorigin)
00630 {
00631     
00632 
00633     float save = r_factor;
00634     if (r_factor > 1) r_factor = 1;
00635 
00636     int xsize = 550;
00637     int ysize = 550;
00638     if (r_factor <= 0.6) xsize = (int) (xsize / (r_factor/0.6));
00639     dia = lux_open_dialog(xorigin, yorigin, _R_(xsize), _R_(ysize));
00640 
00641     
00642 
00643      lux_set_item(dia, Origin, TEXT_WINDOW, NO_TYPE,
00644                  _R_(70), _R_(500), 6, "origin");
00645 
00646     sprintf(temp_buffer, "%f", origin[0]);
00647     lux_set_item(dia, Xorigin, INPUT_WINDOW, NO_TYPE,
00648                  _R_(160), _R_(500), 10, temp_buffer);
00649 
00650     sprintf(temp_buffer, "%f", origin[1]);
00651     lux_set_item(dia, Yorigin, INPUT_WINDOW, NO_TYPE,
00652                  _R_(280), _R_(500), 10, temp_buffer);
00653 
00654     sprintf(temp_buffer, "%f", origin[2]);
00655     lux_set_item(dia, Zorigin, INPUT_WINDOW, NO_TYPE,
00656                  _R_(400), _R_(500), 10, temp_buffer);
00657 
00658 
00659     
00660 
00661     
00662     
00663     
00664     
00665     
00666     
00667     
00668     
00669     
00670     
00671 
00672     
00673 
00674     set_diag_item(xminimum, "xmin", 1, 70, 160, 460);
00675     set_diag_item(xmaximum, "xmax", 1, 70, 160, 420);
00676     set_diag_item(yminimum, "ymin", 1, 70, 160, 380);
00677     set_diag_item(ymaximum, "ymax", 1, 70, 160, 340);
00678 
00679     
00680 
00681     set_diag_item(lmax3D, "cube size", 1, 70, 180, 300);
00682 
00683     
00684 
00685     set_diag_item(theta3D,  "theta",  1, 70, 180, 260);
00686     set_diag_item(phi3D,    "phi",    1, 70, 180, 220);
00687     set_diag_item(dtheta3D, "dtheta", 1, 70, 180, 180);
00688 
00689     
00690 
00691     set_diag_item(basepointsize, "point scale", 1, 70, 180, 140);
00692 
00693     
00694 
00695     set_diag_item(DelayTime, "delay time", 1, 70, 180, 100);
00696 
00697 
00698     
00699 
00700     
00701     
00702     
00703 
00704     
00705     
00706     
00707 
00708     
00709 
00710     set_diag_item(originstar, "Origin Star", 0, 320, 360, 460);
00711 
00712     
00713 
00714     set_diag_item(view2D, "2-D view axis", 0, 320, 360, 420);
00715 
00716     
00717 
00718     set_diag_item(graph3dim, "3-D graph", 0, 320, 350, 380);
00719 
00720     
00721 
00722     set_diag_item(pointscalemode, "point display mode", 0, 320, 360, 300);
00723 
00724     
00725 
00726     set_diag_item(colorenergy, "color by energy", 0, 320, 350, 260);
00727 
00728     
00729 
00730     set_diag_item(tracking, "track particles", 0, 320, 350, 220);
00731 
00732     
00733 
00734     
00735 
00736     lux_set_item(dia, ok, BUTTON_WINDOW, OK_BUTTON,
00737                  _R_(100), _R_(25), 9, "OK, CLEAR");
00738     lux_set_item(dia, ok_keep, BUTTON_WINDOW, OK_KEEP_BUTTON,
00739                  _R_(250), _R_(25), 8, "OK, KEEP");
00740     lux_set_item(dia, cancel, BUTTON_WINDOW, CANCEL_BUTTON,
00741                  _R_(400), _R_(25), 6, "CANCEL");
00742 
00743     r_factor = save;
00744 }
00745 
00746 local void make_relative_to_root(DYN* b)
00747 {
00748     vector root_pos = b->get_pos();
00749     vector root_vel = b->get_vel();
00750     for_all_nodes(DYN, b, bi) {
00751         bi->inc_pos(-root_pos);
00752         bi->inc_vel(-root_vel);
00753     }
00754 }
00755 
00756 local void update_diag_item(int which)
00757 {
00758     set_temp_buffer(which);
00759     lux_update_itemvalue(dia, which, type(which), subtype(which),
00760                          temp_buffer);
00761 }
00762 
00763 local void get_diag_string(int which) {
00764 }
00765 
00766 
00767 
00768 local void read_diag_item(int which, float& f)
00769 {
00770     lux_get_itemvalue(dia, which, type(which), subtype(which),
00771                       temp_buffer);
00772     sscanf(temp_buffer, "%f", &f);
00773 }
00774 
00775 local void read_diag_item(int which, int& i)
00776 {
00777     lux_get_itemvalue(dia, which, type(which), subtype(which),
00778                       temp_buffer);
00779     sscanf(temp_buffer, "%d", &i);
00780 }
00781 
00782 local void read_diag_item(int which, char& c)
00783 {
00784     lux_get_itemvalue(dia, which, type(which), subtype(which),
00785                       temp_buffer);
00786     c = temp_buffer[0];
00787 }
00788 
00789 local void update_from_dialog(bool r_flag)
00790 {
00791     
00792     
00793     
00794     
00795 
00796     read_diag_item(view2D, kproj);
00797     if (kproj == 1)
00798         kx = 1, ky = 2;
00799     else if (kproj == 2)
00800         kx = 2, ky = 0;
00801     else
00802         kx = 0, ky = 1;
00803 
00804     read_diag_item(originstar, origin_star);
00805 
00806     read_diag_item(Xorigin, origin[0]);
00807     read_diag_item(Yorigin, origin[1]);
00808     read_diag_item(Zorigin, origin[2]);
00809 
00810     read_diag_item(lmax3D, lmax3d);
00811     lmax3d /= 2;                        
00812 
00813     
00814 
00815     
00816     
00817 
00818     read_diag_item(xminimum, xmin);
00819     read_diag_item(xmaximum, xmax);
00820     read_diag_item(yminimum, ymin);
00821     read_diag_item(ymaximum, ymax);
00822 
00823     set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
00824 
00825     
00826 
00827     update_diag_item(xminimum);
00828     update_diag_item(xmaximum);
00829     update_diag_item(yminimum);
00830     update_diag_item(ymaximum);
00831 
00832     
00833 
00834     read_diag_item(basepointsize,base_point_size);
00835 
00836     read_diag_item(theta3D, theta);
00837     costheta = cos(theta);
00838     sintheta = sin(theta);
00839 
00840     read_diag_item(phi3D, phi);
00841     cosphi = cos(phi);
00842     sinphi = sin(phi);
00843 
00844     read_diag_item(dtheta3D, dtheta);
00845 
00846     read_diag_item(DelayTime, delay_time);
00847     if (delay_time < MIN_DELAY) delay_time = MIN_DELAY;
00848 
00849     read_diag_item(colorenergy, cenergy);
00850     show_color_scheme(colwin, c_energy, c_index,
00851                       r_factor, cenergy, r_flag, 1);
00852 
00853     read_diag_item(tracking, track);
00854     read_diag_item(graph3dim, graph3d);
00855 
00856     lux_clear_window(win);
00857 
00858     if (graph3d) {
00859         lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d, 
00860                             -FAC3D*lmax3d, FAC3D*lmax3d);
00861         draw3d_axis(win, lmax3d, costheta, sintheta,
00862                     cosphi, sinphi);
00863     } else {
00864         lux_setup_axis(win, xmin, xmax, ymin, ymax);
00865         draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
00866     }
00867 
00868     read_diag_item(pointscalemode, point_scale_mode);
00869 }
00870 
00871 local void show_static_rotation(DYN* b, bool f_flag)
00872 {
00873     
00874 
00875     show_instructions(instr, r_factor,
00876                       "Pause...\n  r: rotate, (p,c): continue                ",
00877                       1);
00878 
00879     char rotate = 0;
00880     do {
00881         if (lux_check_keypress(win,'r')) {
00882             show_instructions(instr, r_factor,
00883                       "Rotate... p: pause, c: continue, c: exit rotation     ",
00884                               0);
00885             rotate = 1;
00886 
00887             do {
00888                 theta += dtheta;
00889                 if (theta < 0.0)
00890                     theta += 2*PI;
00891                 else if (theta > PI*2)
00892                     theta -= 2*PI;
00893                 costheta = cos(theta);
00894                 sintheta = sin(theta);
00895                 update_diag_item(theta3D);
00896 
00897                 lux_clear_current_region(win);
00898                 draw3d_axis(win, lmax3d, costheta, sintheta,
00899                             cosphi, sinphi);
00900 
00901                 for_all_leaves(DYN, b, bi) {
00902 
00903                     float X = (float)bi->get_pos()[0] - origin[0];
00904                     float Y = (float)bi->get_pos()[1] - origin[1];
00905                     float Z = (float)bi->get_pos()[2] - origin[2];
00906 
00907                     float actual_point_size = get_point_size(bi);
00908 
00909                     if (   (X > (-lmax3d + actual_point_size))
00910                         && (X < ( lmax3d - actual_point_size)) 
00911                         && (Y > (-lmax3d + actual_point_size))
00912                         && (Y < ( lmax3d - actual_point_size)) 
00913                         && (Z > (-lmax3d + actual_point_size))
00914                         && (Z < ( lmax3d - actual_point_size))){
00915 
00916                         float r, s;
00917                         project3d(X, Y, Z, r, s,
00918                                   costheta, sintheta,
00919                                   cosphi, sinphi);
00920 
00921                         if (cenergy) {
00922                             char c;
00923                             compute_energies(b, bi, c);
00924                             lux_set_color(win,c_energy[c]);
00925                         } else if (clean_index(bi)>0) {
00926                             if (clean_index(bi) <= N_COLORS)
00927                                 lux_set_color(win,
00928                                               c_index[clean_index(bi)]);
00929                             else
00930                                 lux_set_color(win,c_index[1]);
00931                         }
00932 
00933                         if (track) 
00934                             lux_draw_pointf(win,r,s);
00935                         else
00936                             if (f_flag)
00937                                 lux_fill_arcf(win,
00938                                               r - actual_point_size/2,
00939                                               s - actual_point_size/2, 
00940                                               actual_point_size,
00941                                               actual_point_size,
00942                                               0.0, 360.0);
00943                             else
00944                                 lux_draw_arcf(win,
00945                                               r - actual_point_size/2,
00946                                               s - actual_point_size/2, 
00947                                               actual_point_size,
00948                                               actual_point_size,
00949                                               0.0, 360.0);
00950                     }
00951                 }
00952                 update_with_delay(win, max(MIN_DELAY, delay_time));
00953 
00954                 if (lux_check_keypress(win,'p')) 
00955                     while(!lux_check_keypress(win,'c'));
00956 
00957             } while(!lux_check_keypress(win,'c'));
00958 
00959             
00960 
00961             while(lux_check_keypress(win,'c'));
00962         }
00963 
00964     } while(!lux_check_keypress(win,'p')
00965             && !lux_check_keypress(win,'c') && !rotate);
00966 
00967     rotate = 0;
00968     lux_set_color(win,c_energy[default_color]);
00969 }
00970 
00971 local char check_for_input(unsigned long win, DYN* b,
00972                            real &t, real &dt, bool &E_flag,
00973                            bool r_flag, bool f_flag, bool eod)
00974 {
00975     
00976     
00977 
00978     
00979 
00980     char key, string[20], shift, control;
00981     bool key_pressed = false;
00982 
00983     while (lux_next_keypress(win, &key, string, &shift, &control)) {
00984 
00985         
00986 
00987         key_pressed = true;
00988 
00989         if (key == 0                    
00990                                         
00991             || key == 'h'
00992             || key == 'a') {
00993 
00994             
00995 
00996             int change = 0;
00997 
00998             if (key == 'h')             
00999                 change = 4;             
01000             else if (key == 'a')
01001                 change = 5;
01002 
01003             else if (strcmp(string, "Up") == 0) {
01004                 change = ky + 1;
01005                 origin[ky] += lmax3d/2;
01006             } else if (strcmp(string, "Down") == 0) {
01007                 change = ky + 1;
01008                 origin[ky] -= lmax3d/2;
01009             } else if (strcmp(string, "Right") == 0) {
01010                 change = kx + 1;
01011                 origin[kx] += lmax3d/2;
01012             } else if (strcmp(string, "Left") == 0) {
01013                 change = kx + 1;
01014                 origin[kx] -= lmax3d/2;
01015             } else if (strcmp(string, "PgUp") == 0) {
01016                 change = kproj;
01017                 origin[kproj-1] += lmax3d/2;
01018             } else if (strcmp(string, "PgDn") == 0) {
01019                 change = kproj;
01020                 origin[kproj-1] -= lmax3d/2;
01021             } else if (strcmp(string, "Home") == 0)
01022                 change = 4;
01023             else if (strcmp(string, "R11") == 0)
01024                 change = 5;
01025 
01026             if (change) {
01027 
01028                 if (change == 4) {
01029                     origin[kx] = origin[ky] = origin[kproj-1] = 0;
01030                 } else if (change == 5) {
01031 
01032                     real save = lmax3d;
01033                     lmax3d = 0;
01034 
01035                     
01036 
01037                     for_all_leaves(DYN, b, bi)
01038                         for (int kk = 0; kk < 3; kk++)
01039                             lmax3d = max(lmax3d, abs(bi->get_pos()[kk]
01040                                                      - local_offset[kk]));
01041                 
01042                     
01043                 
01044                     lmax3d *= 1.2;
01045                     if (lmax3d <= 0) lmax3d = 1;
01046                 
01047                     real m_log = log10(lmax3d);
01048                     int i_log = (int) m_log;
01049                     if (m_log - i_log > 0.699) i_log++;
01050                     real scale = pow(10.0, i_log);
01051                     lmax3d = ((int) (lmax3d/scale) + 1) * scale;
01052 
01053                     origin[kx] = origin[ky] = origin[kproj-1] = 0;              
01054                     base_point_size *= lmax3d/save;
01055                 }
01056 
01057                 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01058 
01059                 
01060 
01061                 update_diag_item(xminimum);
01062                 update_diag_item(xmaximum);
01063                 update_diag_item(yminimum);
01064                 update_diag_item(ymaximum);
01065 
01066                 if (change == 1 || change >= 4) update_diag_item(Xorigin);
01067                 if (change == 2 || change >= 4) update_diag_item(Yorigin);
01068                 if (change == 3 || change >= 4) update_diag_item(Zorigin);
01069 
01070                 if (change == 5) {
01071                     update_diag_item(basepointsize);
01072                     update_diag_item(lmax3D);
01073                 }
01074 
01075                 
01076                 
01077                 if (!graph3d) {
01078                     lux_clear_window(win);
01079                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01080                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01081                 } else if (change == 5) {
01082                     lux_clear_window(win);
01083                     lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d, 
01084                                    -FAC3D*lmax3d, FAC3D*lmax3d);
01085                     draw3d_axis(win, lmax3d, costheta, sintheta,
01086                                 cosphi, sinphi);
01087                 }
01088             }
01089 
01090         } else {                        
01091 
01092             
01093 
01094             if (key == 'q') {
01095                 show_instructions(instr, r_factor,
01096                     "\n   Quitting...                                        ",
01097                                   1);
01098                 lux_exit();             
01099             }
01100 
01101             
01102 
01103             if (graph3d && !track) {
01104                 int button;
01105 
01106                 
01107 
01108                 if (key== 'R') {
01109 
01110                     show_static_rotation(b, f_flag);
01111 
01112                 } else {
01113 
01114                     button = lux_check_buttonpress(win);
01115 
01116                     if (key == '^') {
01117                         phi = phi - dtheta;
01118                         if (phi < -PI) phi = phi + 2.0*PI;
01119                         cosphi = cos(phi);
01120                         sinphi = sin(phi);
01121                         update_diag_item(phi3D);
01122                     } else if (key == 'V') {
01123                         phi = phi + dtheta;
01124                         if (phi > PI) phi = phi - 2.0*PI;
01125                         cosphi = cos(phi);
01126                         sinphi = sin(phi);
01127                         update_diag_item(phi3D);
01128                     } else if (key == '<') {
01129                         theta = theta + dtheta;
01130                         if (theta > 2*PI) theta -= 2*PI;
01131                         costheta = cos(theta);
01132                         sintheta = sin(theta);
01133                         update_diag_item(theta3D);
01134                     } else if (key == '>') {
01135                         theta = theta - dtheta;
01136                         if (theta < 0.0) theta += 2*PI;
01137                         costheta = cos(theta);
01138                         sintheta = sin(theta);
01139                         update_diag_item(theta3D);
01140                     }
01141                 }
01142             }
01143 
01144             
01145 
01146             if (key == 'p' || key == 'P') {     
01147 
01148                 if (key == 'p') {
01149                     if (base_point_size > 4*lmax3d/win_size)
01150                         base_point_size /= PFAC;
01151                 } else
01152                     base_point_size *= PFAC;
01153 
01154                 update_diag_item(basepointsize);
01155 
01156             } else if (key == 'm') {            
01157 
01158                 multiples = 1 - multiples;
01159                 if (multiples == 1) nodes = 1;
01160 
01161             } else if (key == 'n') {            
01162 
01163                 nodes = 1 - nodes;
01164                 if (nodes == 0) links = 0;
01165 
01166             } else if (key == 'l') {            
01167 
01168                 links = 1 - links;
01169                 if (links == 1) nodes = 1;
01170 
01171             } else if (key == 'r') {            
01172 
01173                 root = 1 - root;
01174 
01175             } else if (key == 't') {            
01176 
01177                 track = 1 - track;
01178                 update_diag_item(tracking);
01179 
01180             } else if (key == 'u') {            
01181 
01182                 unperturbed = 1 - unperturbed;
01183 
01184             } else if (key == '3' && !graph3d) {    
01185 
01186                 graph3d = 1;
01187                 update_diag_item(graph3dim);
01188                 lux_clear_window(win);
01189                 lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d, 
01190                                -FAC3D*lmax3d, FAC3D*lmax3d);
01191                 draw3d_axis(win, lmax3d, costheta, sintheta, cosphi, sinphi);
01192 
01193                 
01194 
01195 
01196 
01197 
01198             } else if (graph3d &&
01199                        (key == '2' || key == 'x'
01200                           || key == 'y' || key == 'k')) {   
01201 
01202                 graph3d = 0;
01203                 update_diag_item(graph3dim);
01204                 lux_clear_window(win);
01205                 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01206                 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01207 
01208                 
01209 
01210 
01211 
01212 
01213             } else if (key == 'E') {            
01214 
01215                 E_flag = !E_flag;
01216 
01217             } else if (key == 'e') {            
01218 
01219                 cenergy = !cenergy;
01220                 update_diag_item(colorenergy);
01221                 show_color_scheme(colwin, c_energy, c_index,
01222                                   r_factor, cenergy, r_flag, 1);
01223 
01224             } else if (key == '*') {            
01225 
01226 
01227 #define DTFAC   1.41421356237309514547          // square root of 2
01228 
01229                 dt *= DTFAC;
01230 
01231             } else if (key == '/') {            
01232 
01233                 dt /= DTFAC;
01234 
01235             } else if (key == '\\') {           
01236 
01237                 dt = -dt;
01238 
01239             } else if (key == 'j') {
01240 
01241                 cerr << "jump to time: " << flush;
01242                 cin >> t;
01243                 t -= dt;
01244                 return 'j';
01245 
01246             } else if (key == 'J') {
01247 
01248                 cerr << "time, dt: " << flush;
01249                 cin >> t >> dt;
01250                 t -= dt;
01251                 return 'J';
01252 
01253             } else if (key == '>') {
01254 
01255                 max_cm *= 2;
01256 
01257             } else if (key == '<') {
01258 
01259                 max_cm /= 2;
01260 
01261             } else if (key == '+' || key == '=') {    
01262 
01263                 delay_time *= 2;
01264                 update_diag_item(DelayTime);
01265 
01266             } else if (key == '-') {            
01267 
01268                 delay_time /= 2;
01269                 if (delay_time < MIN_DELAY) delay_time = MIN_DELAY;
01270                 update_diag_item(DelayTime);
01271 
01272             } else if (key == '0') {            
01273 
01274                 delay_time = MIN_DELAY;
01275                 update_diag_item(DelayTime);
01276 
01277                 
01278 
01279                 while(lux_check_keypress(win,'+')
01280                       || lux_check_keypress(win,'-'));
01281 
01282             } else if (key == 'R') {            
01283 
01284                 show_color_scheme(colwin, c_energy, c_index,
01285                                   r_factor, cenergy, r_flag, 1);
01286 
01287             } else if (key == 'z') {            
01288                                                 
01289 
01290                 lmax3d /= ZOOM;
01291                 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01292                 base_point_size /= ZOOM;
01293 
01294                 if (graph3d) {
01295                     lux_clear_window(win);
01296                     lux_setup_axis(win,-FAC3D*lmax3d,FAC3D*lmax3d, 
01297                                    -FAC3D*lmax3d, FAC3D*lmax3d);
01298                     draw3d_axis(win, lmax3d, costheta, sintheta,
01299                                 cosphi, sinphi);
01300                 } else {
01301                     lux_clear_window(win);
01302                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01303                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01304                 }
01305 
01306                 update_diag_item(basepointsize);
01307                 update_diag_item(lmax3D);
01308                 update_diag_item(xminimum);
01309                 update_diag_item(xmaximum);
01310                 update_diag_item(yminimum);
01311                 update_diag_item(ymaximum);
01312 
01313             } else if (key == 'Z') {            
01314 
01315                 lmax3d *= ZOOM;
01316                 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01317                 base_point_size *= ZOOM;
01318 
01319                 if (graph3d) {
01320                     lux_clear_window(win);
01321                     lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d, 
01322                                    -FAC3D*lmax3d, FAC3D*lmax3d);
01323                     draw3d_axis(win, lmax3d, costheta, sintheta,
01324                                 cosphi, sinphi);
01325                 } else {
01326                     lux_clear_window(win);
01327                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01328                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01329                 }
01330 
01331                 update_diag_item(basepointsize);
01332                 update_diag_item(lmax3D);
01333                 update_diag_item(xminimum);
01334                 update_diag_item(xmaximum);
01335                 update_diag_item(yminimum);
01336                 update_diag_item(ymaximum);
01337 
01338             } else if (key == 'k') {            
01339                                                 
01340                 if (graph3d) {
01341 
01342                     theta = -PI/2;
01343                     phi = PI/2.0;
01344                     costheta = cos(theta);
01345                     sintheta = sin(theta);
01346                     cosphi = cos(phi);
01347                     sinphi = sin(phi);
01348 
01349                     update_diag_item(theta3D);
01350                     update_diag_item(phi3D);
01351 
01352                     while (lux_check_keypress(win,'<')
01353                            || lux_check_keypress(win,'>')
01354                            || lux_check_keypress(win,'^')
01355                            || lux_check_keypress(win,'V') );
01356 
01357                 } else {
01358 
01359                     kproj = 3;
01360                     kx = 0;
01361                     ky = 1;
01362                     set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01363                     lux_clear_window(win);
01364                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01365                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01366 
01367                     update_diag_item(view2D);
01368 
01369                 }
01370 
01371             } else if (key == 'y') {            
01372 
01373                 if (graph3d) {
01374 
01375                     theta = -PI/2.0;
01376                     phi = 0.0;
01377                     costheta = cos(theta);
01378                     sintheta = sin(theta);
01379                     cosphi = cos(phi);
01380                     sinphi = sin(phi);
01381 
01382                     while (lux_check_keypress(win,'<')
01383                            || lux_check_keypress(win,'>')
01384                            || lux_check_keypress(win,'^')
01385                            || lux_check_keypress(win,'V') );
01386 
01387                     update_diag_item(theta3D);
01388                     update_diag_item(phi3D);
01389 
01390                 } else {
01391 
01392                     kproj = 2;
01393                     kx = 2;
01394                     ky = 0;
01395                     set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01396                     lux_clear_window(win);
01397                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01398                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01399 
01400                     update_diag_item(view2D);
01401 
01402                 }
01403 
01404             } else if (key == 'x') {            
01405 
01406                 if (graph3d) {
01407                     theta = 0.0;
01408                     phi = 0.0;
01409                     costheta = cos(theta);
01410                     sintheta = sin(theta);
01411                     cosphi = cos(phi);
01412                     sinphi = sin(phi);
01413 
01414                     while (lux_check_keypress(win,'<')
01415                            || lux_check_keypress(win,'>')
01416                            || lux_check_keypress(win,'^')
01417                            || lux_check_keypress(win,'V') );
01418 
01419                     update_diag_item(theta3D);
01420                     update_diag_item(phi3D);
01421 
01422                 } else {
01423 
01424                     kproj = 1;
01425                     kx = 1;
01426                     ky = 2;
01427                     set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01428                     lux_clear_window(win);
01429                     lux_setup_axis(win, xmin, xmax, ymin, ymax);
01430                     draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01431 
01432                     update_diag_item(view2D);
01433 
01434                 }
01435             }
01436 
01437             
01438 
01439             if (key == 'o' && !graph3d) {
01440 
01441                 show_instructions(instr, r_factor,
01442                 " Use mouse-right to select new origin...\n",1);
01443                 float r, s;
01444                 get_mouse_position(win, &r, &s);
01445 
01446                 
01447 
01448                 origin[kx] = r;
01449                 origin[ky] = s;
01450                 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01451 
01452                 lux_clear_window(win);
01453                 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01454                 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01455 
01456                 origin_star = -1;
01457 
01458                 update_diag_item(Xorigin);
01459                 update_diag_item(Yorigin);
01460                 update_diag_item(Zorigin);
01461                 update_diag_item(xminimum);
01462                 update_diag_item(xmaximum);
01463                 update_diag_item(yminimum);
01464                 update_diag_item(ymaximum);
01465                 update_diag_item(originstar);
01466 
01467             } else if (!graph3d && key == 'O') {
01468 
01469                 show_instructions(instr, r_factor,
01470                 " Use mouse-right to select new origin star...\n",1);
01471                 float r, s;
01472                 get_mouse_position(win, &r, &s);
01473 
01474                 
01475 
01476                 
01477 
01478                 origin_star = nearest_index(b, r, s, kx, ky);
01479 
01480                 if (origin_star > 0) {
01481                     for (int kk = 0; kk < 3; kk++) origin[kk] = 0;
01482                     set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01483                 }
01484 
01485                 lux_clear_window(win);
01486                 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01487                 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01488 
01489                 update_diag_item(Xorigin);
01490                 update_diag_item(Yorigin);
01491                 update_diag_item(Zorigin);
01492                 update_diag_item(xminimum);
01493                 update_diag_item(xmaximum);
01494                 update_diag_item(yminimum);
01495                 update_diag_item(ymaximum);
01496                 update_diag_item(originstar);
01497 
01498             } else if (key == 'b' || key == 'B') {
01499 
01500                 return 'b';
01501 
01502             } else if (key == 'c' || key == 'C') {
01503 
01504                 return 'c';
01505 
01506             } else if (key == 'f' || key == 'F' || key == 's' || key == 'S') {
01507 
01508                 return 'f';
01509 
01510             }
01511 
01512             
01513 
01514             while(lux_check_keypress(win,'r'));  
01515 
01516             
01517 
01518             int return_value = 0;
01519 
01520             if (key == 'i') {
01521 
01522                 show_instructions(instr, r_factor,
01523                   " Idle...\n  d: dialog, r: replay, c: continue, q: quit",1);
01524                 return_value = lux_getevent();
01525 
01526             } else if (key == 'd') {
01527 
01528                 show_instructions(instr, r_factor,
01529 "Dialog mode keyboard options\n\n\
01530   Dialog window:\n\
01531     o   OK, keep dialog window\n\
01532     O   OK, close dialog window\n\
01533     c   CANCEL, keep dialog window\n\
01534     C   CANCEL, close dialog window\n\n\
01535   Other windows:\n\
01536     r   replay\n\
01537     c   continue (keep dialog window,\n\
01538                   ignore dialog changes)\n\
01539     q   quit\n\
01540 ",1);
01541                 lux_show_dialog(dia);
01542                 return_value = lux_getevent();
01543             }
01544             
01545             
01546             
01547             
01548             if (return_value == 3) update_from_dialog(r_flag);
01549 
01550         }
01551     }
01552 
01553     if (key_pressed) {
01554 
01555         
01556         
01557 
01558         show_main_instructions(instr, r_factor, graph3d, 1, eod,
01559                                nodes, links, multiples, unperturbed, root);
01560         show_color_scheme(colwin, c_energy, c_index,
01561                           r_factor, cenergy, r_flag, 1);
01562 
01563         return ' ';
01564     }
01565 
01566     return 0;
01567 }
01568 
01569 
01570 
01571 
01572 
01573 
01574 
01575 
01576 
01577 
01578 
01579 
01580 #define INSTR_FREQ_MAX 32
01581 #define INSTR_FREQ_FAC 64
01582 static int instr_freq = INSTR_FREQ_MAX;
01583 static int count_instr = 0;
01584 
01585 void xstarplot22(DYN* b, float scale, int k, int d, float lmax,
01586                 int point_mode, float rel_point_size,
01587                 real &t, real &dt, float D, int ce,
01588                 bool &E_flag, bool r_flag, bool f_flag, bool t_flag,
01589                 int init_flag, int& step_mode, bool eod)
01590 {
01591     if (!b) return;
01592 
01593     r_factor = scale;
01594 
01595     if (!eod && init_flag == 0) {
01596 
01597         int xorigin, yorigin;
01598 
01599         if (t_flag) nodes = links = 1;
01600 
01601         
01602         
01603 
01604         if (init_status == 0) initialize_graphics(r_factor, r_flag,
01605                                                   win, instr, colwin,
01606                                                   c_index, c_energy,
01607                                                   win_size, xorigin, yorigin);
01608         lux_clear_window(win);
01609         lux_update_fg(win);
01610         lux_clear_window(colwin);
01611         lux_update_fg(colwin);
01612         lux_clear_window(instr);
01613         lux_update_fg(instr);
01614 
01615         
01616 
01617         kproj = k;
01618         switch (kproj) {
01619             case 1:     kx = 1; ky = 2; graph3d = 0; break;
01620             case 2:     kx = 2; ky = 0; graph3d = 0; break;
01621             case 3:     kx = 0; ky = 1; graph3d = 0; break;
01622             default:    cerr << "xstarplot22: k = " << k
01623                              << ": illegal value; choose from {1, 2, 3}"
01624                              << endl;
01625                         exit(0);
01626         }
01627 
01628         switch(d) {
01629             case 2:     graph3d = 0;  break;
01630             case 3:     graph3d = 1;  break;
01631             default:    cerr << "xstarplot22: d = " << d
01632                              << " illegal value; choose from {2, 3)"
01633                              << endl;
01634                         exit(0);
01635         }
01636 
01637         point_scale_mode = point_mode;
01638 
01639         cenergy = ce?1:0;
01640         show_color_scheme(colwin, c_energy, c_index,
01641                           r_factor, cenergy, r_flag, 1);
01642 
01643         delay_time = D;
01644 
01645         if (lmax > 0.0)
01646 
01647             lmax3d = lmax;
01648 
01649         else {
01650 
01651             lmax3d = 0;
01652 
01653             
01654 
01655             for_all_leaves(DYN, b, bi)
01656                 for (int kk = 0; kk < 3; kk++)
01657                     lmax3d = max(lmax3d, abs(bi->get_pos()[kk]));
01658 
01659             
01660 
01661             lmax3d *= 1.2;
01662 
01663             
01664 
01665             lmax3d /= 2;
01666 
01667             if (lmax3d <= 0) lmax3d = 1;
01668 
01669             real m_log = log10(lmax3d);
01670             int i_log = (int) m_log;
01671             if (m_log - i_log > 0.699) i_log++;
01672             real scale = pow(10.0, i_log);
01673             lmax3d = ((int) (lmax3d/scale) + 1) * scale;
01674         }
01675 
01676         for (int ko = 0; ko < 3; ko++)
01677             origin[ko] = 0;
01678 
01679         set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01680         set_base_point_size(b, rel_point_size);
01681         
01682         if (graph3d) {
01683             lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d, 
01684                            -FAC3D*lmax3d, FAC3D*lmax3d);      
01685             draw3d_axis(win, lmax3d, costheta, sintheta, cosphi, sinphi);
01686         } else {
01687             lux_setup_axis(win, xmin, xmax, ymin, ymax);
01688             draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01689         }
01690 
01691         
01692 
01693         if (init_status == 0)
01694             initialize_dialog(xorigin, yorigin);
01695 
01696         init_status = 1;
01697             
01698     }
01699 
01700     
01701 
01702     
01703     
01704 
01705     if (track == 0) {
01706         lux_clear_current_region(win);
01707         if (graph3d) draw3d_axis(win, lmax3d, costheta, sintheta,
01708                                  cosphi, sinphi);
01709     }
01710 
01711     if (!eod) {
01712 
01713         
01714         
01715         
01716         
01717         
01718         
01719 
01720         instr_freq = INSTR_FREQ_FAC / b->n_leaves();
01721         if (instr_freq > INSTR_FREQ_MAX) instr_freq = INSTR_FREQ_MAX;
01722         if (instr_freq < 1) instr_freq = 1;
01723 
01724         if (count_instr++%instr_freq == 0)
01725             show_main_instructions(instr, r_factor, graph3d, 1, eod,
01726                                    nodes, links, multiples, unperturbed, root);
01727     }
01728 
01729     
01730 
01731     
01732     
01733 
01734     make_relative_to_root(b);
01735 
01736     
01737 
01738     if (origin_star > 0) {
01739         for_all_leaves(DYN, b, bi)
01740             if (clean_index(bi) == origin_star) {
01741                 for (int kk = 0; kk < 3; kk++)
01742                     local_offset[kk] = bi->get_pos()[kk];
01743                 break;
01744             }
01745     } else
01746         for (int kk = 0; kk < 3; kk++)
01747             local_offset[kk] = 0;
01748 
01749     
01750 
01751     int n_stars = plot_all_stars(b, f_flag);
01752 
01753     
01754 
01755     lux_set_color(win, c_energy[default_color]);
01756 
01757     if (graph3d) {
01758 
01759         
01760         
01761         sprintf(temp_buffer, "   N = %d (t = %.6f) max=%5.3f   ",
01762                 n_stars, b->get_real_system_time(), lmax3d);
01763         lux_draw_image_string(win, 0.0, lmax3d*FAC3D, 0.5, temp_buffer, 0);
01764 
01765     } else {
01766 
01767         
01768         
01769         sprintf(temp_buffer, "   N = %d  (t = %.6f)   ",
01770                 n_stars, b->get_real_system_time());
01771         lux_draw_image_string(win, (xmin+xmax)/2.0, ymax, 0.5, temp_buffer, 0);
01772 
01773     }
01774 
01775     
01776 
01777     update_with_delay(win, max(MIN_DELAY, delay_time));
01778 
01779     
01780     
01781 
01782     while (true) {
01783 
01784         char c = check_for_input(win, b, t, dt, E_flag, r_flag, f_flag, eod);
01785 
01786         
01787 
01788         if (c == 'b' || c == 'f') {             
01789 
01790             step_mode = (c == 'b' ? -1 : 1);
01791             return;
01792 
01793         } else if (c == 'c') {                  
01794 
01795             if (eod)
01796                 step_mode = 1;
01797             else
01798                 step_mode = 0;
01799 
01800             return;
01801 
01802         } else if (c == 'j' || c == 'J') {
01803 
01804             step_mode = 1;
01805             return;
01806         }
01807 
01808         
01809         
01810         
01811 
01812         if (eod && c != 0) {
01813             step_mode = 0;
01814             return;
01815         }
01816         if (!eod && step_mode == 0) return;
01817 
01818         
01819 
01820         lux_pause(10000);
01821     }
01822 
01823 }
01824 
01825 
01826 
01827 local void print_worldlines(worldbundleptr wh[], int nh)
01828 {
01829     for (int ih = 0; ih < nh; ih++) {
01830         cerr << "worldbundle " << ih << ":" << endl;
01831         wh[ih]->dump(4);
01832     }
01833 }
01834 
01835 local void print_escapes(worldbundleptr wh[], int nh)
01836 {
01837     DYN *b = create_interpolated_tree2(wh[0], 0);
01838     for_all_daughters(DYN, b, bb) {
01839 
01840         PRL(bb->format_label());
01841 
01842         
01843 
01844         for (int ih = 0; ih < nh; ih++) {
01845 
01846             worldline *w = wh[ih]->find_worldline(bb);
01847             if (w->get_start_esc_flag() || w->get_end_esc_flag()) {
01848                 PRC(ih); PRL(w->get_t_esc());
01849             }
01850         }
01851     }
01852 }
01853 
01854 
01855 
01856 
01857 
01858 
01859 
01860 
01861 
01862 
01863 
01864 
01865 main(int argc, char** argv)
01866 {
01867     
01868 
01869     int   k = 3;                
01870     int   d = 2;
01871     float D = 16*MIN_DELAY;
01872     real dt = 0.015625;         
01873     int   cenergy = 0;
01874     float lmax = -1.0;
01875     int   point_mode = 0;
01876     float rel_point_size = 0.5;
01877     float scale = 1.0;
01878 
01879     char infile[128];
01880     strcpy(infile, "run.out");
01881 
01882     bool f_flag = TRUE;         
01883     bool o_flag = FALSE;        
01884     bool r_flag = TRUE;         
01885     bool t_flag = FALSE;        
01886     bool E_flag = true;         
01887 
01888     int verbose = 0;
01889 
01890     check_help();
01891 
01892     extern char *poptarg;
01893     char* params = "a:bd:D:eEfF:lL:mop:P:rs:tuv.";
01894     int   c;
01895 
01896     while ((c = pgetopt(argc, argv, params)) != -1)
01897         switch(c) {
01898 
01899             case 'a': k = atoi(poptarg);        
01900                       break;
01901             case 'd': d = atoi(poptarg);        
01902                       break;
01903             case 'D': dt = atof(poptarg);       
01904                       if (dt < 0)               
01905                           dt = pow(2.0, dt);
01906                       break;
01907             case 'e': cenergy = 1;              
01908                       break;
01909             case 'E': E_flag = !E_flag;
01910                       break;
01911             case 'f': f_flag = FALSE;           
01912                       break;
01913             case 'F': strcpy(infile, poptarg);
01914                       break;
01915             case 'k': max_cm = atoi(poptarg);   
01916                       break;
01917             case 'L': lmax = atof(poptarg);     
01918                       break;
01919             case 'l': links = 1 - links;
01920                       nodes = links;
01921                       break;
01922             case 'm': multiples = 1 - multiples;
01923                       break;
01924             case 'o': o_flag = TRUE;            
01925                       break;
01926             case 'p': point_mode = atoi(poptarg);       
01927                       break;
01928             case 'P': rel_point_size = atof(poptarg);   
01929                       if (rel_point_size < 0.5)
01930                           rel_point_size = 0.5;
01931                       break;
01932             case 'r': r_flag = FALSE;           
01933                       break;
01934             case 's': scale = atof(poptarg);    
01935                       break;
01936             case 't': t_flag = TRUE;            
01937                       break;
01938             case 'u': unperturbed = 1 - unperturbed;
01939                       break;
01940             case 'v': if (poptarg)
01941                           verbose = atoi(poptarg);
01942                       else
01943                           verbose = true;
01944                       break;
01945             case '?': params_to_usage(cerr, argv[0], params);
01946                       get_help();
01947                       exit(0);
01948         }
01949 
01950     ifstream s(infile);
01951     if (!s) {
01952         cerr << "Data file " << infile << " not found." << endl;
01953         exit(1);
01954     }
01955 
01956     
01957     
01958     
01959     
01960     
01961 
01962     worldbundleptr wb, wh[1024];
01963 
01964     int nh = 0;
01965     while (nh < 1024 && (wb = read_bundle(s, verbose))) wh[nh++] = wb;
01966 
01967     
01968 
01969     cerr << endl << "statistics on " << nh << " worldbundle";
01970     if (nh != 1) cerr << "s";
01971     cerr << ":" << endl;
01972 
01973     int nwtot = 0, nstot = 0, netot = 0;
01974     for (int ih = 0; ih < nh; ih++) {
01975         wb = wh[ih];
01976         real t = wb->get_t_min();
01977         int nw = wb->get_nw(), ns = count_segments(wb), ne = count_events(wb);
01978         cerr << "worldbundle " << ih << ": "
01979              << nw << " worldlines, "
01980              << ns << " segments, "
01981              << ne << " events, t = "
01982              << wb->get_t_min() << " to " << wb->get_t_max()
01983              << endl;
01984         nwtot += nw;
01985         nstot += ns;
01986         netot += ne;
01987     }
01988     cerr << "totals: " << nwtot << " worldlines, "
01989          << nstot << " segments, " << netot << " events"
01990          << endl << endl;
01991 
01992     
01993     
01994 
01995     set_center(wh, nh, 1, true);
01996     PRC(get_center()); PRL(get_center_id());
01997 
01998     
01999 
02000     bool eod = false;
02001     int step_mode = 0;
02002     int init = 0;
02003 
02004     int ih = 0;
02005     wb = wh[ih];
02006     real t = wb->get_t_min();
02007 
02008     bool max_cm_set = false;
02009 
02010     while (1) {
02011 
02012         DYN *root = create_interpolated_tree2(wb, t);
02013 
02014         if (!E_flag) {
02015 
02016             
02017 
02018             int n_mem = 0;
02019             for_all_nodes(DYN, root, bb)
02020                 if (bb != root) {
02021                     if (is_member(wb, bb))
02022                         n_mem++;
02023                     else
02024                         bb->set_index(-42);             
02025                 }
02026             
02027         }
02028 
02029         if (!max_cm_set) {
02030             max_cm /= root->n_daughters();
02031             max_cm_set = true;
02032         }
02033 
02034         if (root) {
02035             convert_relative_to_absolute(root);
02036 
02037             real dts = dt;
02038             xstarplot22(root, scale, k, d, lmax,
02039                        point_mode, rel_point_size,
02040                        t, dt, D, cenergy,
02041                        E_flag, r_flag, f_flag, t_flag, init++,
02042                        step_mode, eod);
02043             if (dt != dts) PRL(dt);
02044             
02045         }
02046 
02047         t += dt;
02048 
02049         
02050 
02051 #define EPS 1.e-12
02052 
02053         if (dt > 0 && t > wb->get_t_max() + EPS) {
02054             if (++ih >= nh) {
02055                 ih = 0;
02056                 wb = wh[ih];
02057                 t = wb->get_t_min();
02058             } else
02059                 wb = wh[ih];
02060         }
02061 
02062         
02063 
02064         if (dt < 0 && t < wb->get_t_min() - EPS) {
02065             if (--ih < 0) {
02066                 ih = nh-1;
02067                 wb = wh[ih];
02068                 t = wb->get_t_max();
02069             } else
02070                 wb = wh[ih];
02071         }
02072 
02073     }
02074 }