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 }