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 }