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