00001
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "sdyn3.h"
00046 #include "xstarplot.h"
00047 #include "dyn_util.h"
00048
00049
00050
00051
00052
00053 unsigned long win, dia, instr, colwin;
00054 unsigned long c_energy[10], c_index[N_COLORS+1];
00055 int init_status = 0;
00056
00057
00058
00059
00060 float xmin, xmax, ymin, ymax, base_point_size, lmax3d, origin[3];
00061
00062 int win_size;
00063 int point_scale_mode = 0;
00064 int kx = 1, ky = 2, kproj = 3;
00065 int origin_star = -1;
00066 int nodes = 0, links = 0, root = 0;
00067 float theta = 0.33, costheta = cos(0.33), sintheta = sin(0.33), dtheta = 0.03;
00068 float phi = 0.33, cosphi = cos(0.33), sinphi = sin(0.33);
00069 real local_offset[3];
00070 float delay_time;
00071 float r_factor = 1.0;
00072
00073 char graph3d = 1, track = 0, cenergy = 0;
00074
00075 char temp_buffer[255];
00076
00077
00078
00079
00080
00081
00082 local void set_base_point_size(float rel_point_size)
00083 {
00084 base_point_size = 2 * SMALL_DOT_SIZE;
00085 if (rel_point_size > 0.0) base_point_size *= rel_point_size;
00086 }
00087
00088 local float get_point_size(sdyn3* bi)
00089 {
00090
00091
00092
00093 if (point_scale_mode == 1)
00094 return max(SMALL_DOT_SIZE, base_point_size * sqrt(bi->get_mass()));
00095 else if (point_scale_mode == 2)
00096 return max(SMALL_DOT_SIZE, base_point_size * bi->get_radius());
00097 else
00098 return base_point_size;
00099 }
00100
00101 local void draw_star_point(unsigned long win, float r, float s,
00102 float actual_point_size, bool f_flag)
00103
00104
00105
00106
00107 {
00108 if (f_flag)
00109 lux_fill_arcf(win, r - actual_point_size/2, s - actual_point_size/2,
00110 actual_point_size, actual_point_size, 0.0, 360.0);
00111 else
00112 lux_draw_arcf(win, r - actual_point_size/2, s - actual_point_size/2,
00113 actual_point_size, actual_point_size, 0.0, 360.0);
00114 }
00115
00116 local void draw_links_2d(sdyn3* b, float r, float s)
00117 {
00118 for_all_daughters(sdyn3, b, bb) {
00119
00120 float rr = bb->get_pos()[kx]-local_offset[kx];
00121 float ss = bb->get_pos()[ky]-local_offset[ky];
00122 float stemp;
00123
00124
00125
00126
00127 if (rr < xmin) {
00128
00129 if (ss < ymin) {
00130 float stemp = interp_to_x(r, s, rr, ss, xmin);
00131 if (stemp >= ymin)
00132 rr = xmin, ss = stemp;
00133 else
00134 rr = interp_to_y(r, s, rr, ss, ymin), ss = ymin;
00135 } else if (ss > ymax) {
00136 if ((stemp = interp_to_x(r, s, rr, ss, xmin)) <= ymax)
00137 rr = xmin, ss = stemp;
00138 else
00139 rr = interp_to_y(r, s, rr, ss, ymax), ss = ymax;
00140 } else
00141 ss = interp_to_x(r, s, rr, ss, xmin), rr = xmin;
00142
00143 } else if (rr > xmax) {
00144
00145 if (ss < ymin) {
00146 if ((stemp = interp_to_x(r, s, rr, ss, xmax)) >= ymin)
00147 rr = xmax, ss = stemp;
00148 else
00149 rr = interp_to_y(r, s, rr, ss, ymin), ss = ymin;
00150 } else if (ss > ymax) {
00151 if ((stemp = interp_to_x(r, s, rr, ss, xmax)) <= ymax)
00152 rr = xmax, ss = stemp;
00153 else
00154 rr = interp_to_y(r, s, rr, ss, ymax), ss = ymax;
00155 } else
00156 ss = interp_to_x(r, s, rr, ss, xmax), rr = xmax;
00157
00158 } else {
00159
00160 if (ss < ymin)
00161 rr = interp_to_y(r, s, rr, ss, ymin), ss = ymin;
00162 else if (ss > ymax)
00163 rr = interp_to_y(r, s, rr, ss, ymax), ss = ymax;
00164
00165 }
00166 lux_draw_linef(win, r, s, rr, ss);
00167 }
00168 }
00169
00170 local void draw_links_3d(sdyn3* b, float r, float s)
00171 {
00172 for_all_daughters(sdyn3, b, bb) {
00173
00174 float X = (float)bb->get_pos()[0] - local_offset[0] - origin[0];
00175 float Y = (float)bb->get_pos()[1] - local_offset[1] - origin[1];
00176 float Z = (float)bb->get_pos()[2] - local_offset[2] - origin[2];
00177
00178
00179
00180
00181 float rr, ss;
00182 project3d(X, Y, Z, rr, ss, costheta, sintheta, cosphi, sinphi);
00183 lux_draw_linef(win, r, s, rr, ss);
00184 }
00185 }
00186
00187 local int clean_index(sdyn3* b)
00188 {
00189 int clean_name = 0;
00190
00191 if (b->get_index() > 0)
00192 clean_name = b->get_index();
00193 else if (b->get_name()) {
00194 int i = 0;
00195 if (sscanf(b->get_name(), "%d", &i)) clean_name = i;
00196 }
00197
00198
00199
00200 return clean_name;
00201 }
00202
00203 local int plot_stars(sdyn3* b, int f_flag)
00204 {
00205 int n_stars = b->n_leaves();
00206 if (b->get_oldest_daughter() == NULL) n_stars = 0;
00207
00208 int n_nodes = count_nodes(b);
00209 float r, s;
00210
00211 if (graph3d) {
00212
00213 for_all_nodes(sdyn3, b, bi) if (root || bi->get_parent()) {
00214 if (nodes || (bi->get_oldest_daughter() == NULL)) {
00215
00216 float X = (float)bi->get_pos()[0] - local_offset[0] - origin[0];
00217 float Y = (float)bi->get_pos()[1] - local_offset[1] - origin[1];
00218 float Z = (float)bi->get_pos()[2] - local_offset[2] - origin[2];
00219 float actual_point_size = get_point_size(bi);
00220
00221
00222 if ( (X > (-lmax3d + actual_point_size))
00223 && (X < ( lmax3d - actual_point_size))
00224 && (Y > (-lmax3d + actual_point_size))
00225 && (Y < ( lmax3d - actual_point_size))
00226 && (Z > (-lmax3d + actual_point_size))
00227 && (Z < ( lmax3d - actual_point_size))) {
00228
00229
00230
00231 project3d(X, Y, Z, r, s, costheta, sintheta,
00232 cosphi, sinphi);
00233
00234
00235
00236 bool temp_flag = f_flag;
00237 if (bi->get_oldest_daughter()) {
00238 lux_set_color(win, lux_lookup_color(win, "grey"));
00239 temp_flag = 1 - f_flag;
00240 } else {
00241 if (cenergy) {
00242
00243 char c;
00244
00245 compute_energies(b, bi, c);
00246 lux_set_color(win, c_energy[c]);
00247
00248 } else if (clean_index(bi) > 0) {
00249
00250
00251
00252 int ii = clean_index(bi);
00253 while (ii > N_COLORS) ii -= N_COLORS;
00254
00255 lux_set_color(win,c_index[ii]);
00256 }
00257 }
00258
00259 if (track)
00260 lux_draw_pointf(win, r, s);
00261 else
00262 draw_star_point(win, r, s, actual_point_size, f_flag);
00263
00264 if (links && bi->get_oldest_daughter())
00265 draw_links_3d(bi, r, s);
00266 }
00267 }
00268 }
00269
00270 } else {
00271
00272
00273
00274
00275 sdyn3ptr* p = new sdyn3ptr[n_nodes+root];
00276
00277 int ip = 0;
00278 for_all_nodes(sdyn3, b, bi) if (root || bi != b) p[ip++] = bi;
00279 if (ip != n_nodes+root) {
00280 cerr << "plot_stars: n_nodes = " << n_nodes+root
00281 << " counted " << ip << endl;
00282 exit(1);
00283 }
00284
00285
00286
00287 for (ip = 0; ip < n_nodes+root; ip++)
00288 for (int jp = ip+1; jp < n_nodes+root; jp++)
00289 if (p[jp]->get_pos()[kproj-1] < p[ip]->get_pos()[kproj-1]) {
00290 sdyn3ptr bb = p[jp];
00291 p[jp] = p[ip];
00292 p[ip] = bb;
00293 }
00294
00295
00296
00297 for (ip = 0; ip < n_nodes+root; ip++) {
00298 sdyn3 * bi = p[ip];
00299 if ( (root || bi != b)
00300 && (nodes || bi->get_oldest_daughter() == NULL)) {
00301
00302 r = (float)bi->get_pos()[kx] - local_offset[kx];
00303 s = (float)bi->get_pos()[ky] - local_offset[ky];
00304 float actual_point_size = get_point_size(bi);
00305
00306 if ( (r > (xmin + actual_point_size))
00307 && (r < (xmax - actual_point_size))
00308 && (s > (ymin + actual_point_size))
00309 && (s < (ymax - actual_point_size)) ) {
00310
00311
00312
00313 bool temp_flag = f_flag;
00314 if (bi->get_oldest_daughter()) {
00315 lux_set_color(win, lux_lookup_color(win, "grey"));
00316 temp_flag = 1 - f_flag;
00317 } else {
00318 if (cenergy) {
00319
00320 char c;
00321
00322 compute_energies(b, bi, c);
00323 lux_set_color(win, c_energy[c]);
00324
00325 } else if (clean_index(bi) > 0) {
00326
00327
00328
00329 int ii = clean_index(bi);
00330 while (ii > N_COLORS) ii -= N_COLORS;
00331
00332 lux_set_color(win,c_index[ii]);
00333 }
00334 }
00335
00336 if (track)
00337 lux_draw_pointf(win, r, s);
00338 else
00339 draw_star_point(win, r, s,
00340 actual_point_size, temp_flag);
00341
00342 if (links && bi->get_oldest_daughter())
00343 draw_links_2d(bi, r, s);
00344 }
00345 }
00346 }
00347 delete p;
00348 }
00349 return n_stars;
00350 }
00351
00352 local int type(int which)
00353 {
00354 if (which == tracking || which == graph3dim || which == colorenergy)
00355 return BUTTON_WINDOW;
00356 else
00357 return INPUT_WINDOW;
00358 }
00359
00360 local int subtype(int which)
00361 {
00362 if (which == tracking || which == graph3dim || which == colorenergy)
00363 return CHECK_BUTTON;
00364 else
00365 return NO_TYPE;
00366 }
00367
00368 local void set_temp_buffer(int which)
00369 {
00370
00371
00372 char c = -1;
00373 int i = -1;
00374 float f = VERY_LARGE_NUMBER;
00375
00376 switch (which) {
00377 case colorenergy: c = cenergy; break;
00378 case tracking: c = track; break;
00379 case graph3dim: c = graph3d; break;
00380 case xminimum: f = xmin; break;
00381 case xmaximum: f = xmax; break;
00382 case yminimum: f = ymin; break;
00383 case ymaximum: f = ymax; break;
00384 case basepointsize: f = base_point_size; break;
00385 case pointscalemode: i = point_scale_mode; break;
00386 case lmax3D: f = 2*lmax3d; break;
00387 case theta3D: f = theta; break;
00388 case phi3D: f = phi; break;
00389 case DelayTime: f = delay_time; break;
00390 case dtheta3D: f = dtheta; break;
00391 case Xorigin: f = origin[0]; break;
00392 case Yorigin: f = origin[0]; break;
00393 case Zorigin: f = origin[0]; break;
00394 case view2D: i = kproj; break;
00395 case originstar: i = origin_star; break;
00396 default: cerr << "xstarplot: diag error...\n";
00397 }
00398
00399 if (f < VERY_LARGE_NUMBER)
00400 sprintf(temp_buffer, "%f", f);
00401 else if (c == -1)
00402 sprintf(temp_buffer, " %d ", i);
00403 else
00404 temp_buffer[0] = c;
00405 }
00406
00407 local void set_diag_item(int which, char* id, int label_on_left,
00408 int x1, int x2, int y)
00409 {
00410 set_temp_buffer(which);
00411
00412 if (label_on_left) {
00413
00414 lux_set_item(dia, which, TEXT_WINDOW, NO_TYPE,
00415 _R_(x1), _R_(y), strlen(id), id);
00416 lux_set_item(dia, which, INPUT_WINDOW, NO_TYPE,
00417 _R_(x2), _R_(y), 10, temp_buffer);
00418
00419 } else {
00420
00421 if (type(which) == INPUT_WINDOW) {
00422
00423 lux_set_item(dia, which, INPUT_WINDOW, NO_TYPE,
00424 _R_(x1), _R_(y), 3, temp_buffer);
00425 lux_set_item(dia, which, TEXT_WINDOW, NO_TYPE,
00426 _R_(x2), _R_(y), strlen(id), id);
00427
00428 } else {
00429
00430 lux_set_item(dia, which, BUTTON_WINDOW, CHECK_BUTTON,
00431 _R_(x1), _R_(y), 1, temp_buffer);
00432 lux_set_item(dia, which, TEXT_WINDOW, CHECK_BUTTON,
00433 _R_(x2), _R_(y), strlen(id), id);
00434 }
00435 }
00436 }
00437
00438 local void initialize_dialog(int xorigin, int yorigin)
00439 {
00440
00441
00442 float save = r_factor;
00443 if (r_factor > 1) r_factor = 1;
00444
00445 int xsize = 550;
00446 int ysize = 550;
00447 if (r_factor <= 0.6) xsize = (int) (xsize / (r_factor/0.6));
00448 dia = lux_open_dialog(xorigin, yorigin, _R_(xsize), _R_(ysize));
00449
00450
00451
00452 lux_set_item(dia, Origin, TEXT_WINDOW, NO_TYPE,
00453 _R_(70), _R_(500), 6, "origin");
00454
00455 sprintf(temp_buffer, "%f", origin[0]);
00456 lux_set_item(dia, Xorigin, INPUT_WINDOW, NO_TYPE,
00457 _R_(160), _R_(500), 10, temp_buffer);
00458
00459 sprintf(temp_buffer, "%f", origin[1]);
00460 lux_set_item(dia, Yorigin, INPUT_WINDOW, NO_TYPE,
00461 _R_(280), _R_(500), 10, temp_buffer);
00462
00463 sprintf(temp_buffer, "%f", origin[2]);
00464 lux_set_item(dia, Zorigin, INPUT_WINDOW, NO_TYPE,
00465 _R_(400), _R_(500), 10, temp_buffer);
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 set_diag_item(xminimum, "xmin", 1, 70, 160, 460);
00484 set_diag_item(xmaximum, "xmax", 1, 70, 160, 420);
00485 set_diag_item(yminimum, "ymin", 1, 70, 160, 380);
00486 set_diag_item(ymaximum, "ymax", 1, 70, 160, 340);
00487
00488
00489
00490 set_diag_item(lmax3D, "cube size", 1, 70, 180, 300);
00491
00492
00493
00494 set_diag_item(theta3D, "theta", 1, 70, 180, 260);
00495 set_diag_item(phi3D, "phi", 1, 70, 180, 220);
00496 set_diag_item(dtheta3D, "dtheta", 1, 70, 180, 180);
00497
00498
00499
00500 set_diag_item(basepointsize, "point scale", 1, 70, 180, 140);
00501
00502
00503
00504 set_diag_item(DelayTime, "delay time", 1, 70, 180, 100);
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 set_diag_item(originstar, "Origin Star", 0, 320, 360, 460);
00520
00521
00522
00523 set_diag_item(view2D, "2-D view axis", 0, 320, 360, 420);
00524
00525
00526
00527 set_diag_item(graph3dim, "3-D graph", 0, 320, 350, 380);
00528
00529
00530
00531 set_diag_item(pointscalemode, "point display mode", 0, 320, 360, 300);
00532
00533
00534
00535 set_diag_item(colorenergy, "color by energy", 0, 320, 350, 260);
00536
00537
00538
00539 set_diag_item(tracking, "track particles", 0, 320, 350, 220);
00540
00541
00542
00543
00544
00545 lux_set_item(dia, ok, BUTTON_WINDOW, OK_BUTTON,
00546 _R_(100), _R_(25), 9, "OK, CLEAR");
00547 lux_set_item(dia, ok_keep, BUTTON_WINDOW, OK_KEEP_BUTTON,
00548 _R_(250), _R_(25), 8, "OK, KEEP");
00549 lux_set_item(dia, cancel, BUTTON_WINDOW, CANCEL_BUTTON,
00550 _R_(400), _R_(25), 6, "CANCEL");
00551
00552 r_factor = save;
00553 }
00554
00555 local void make_relative_to_root(sdyn3* b)
00556 {
00557 vector root_pos = b->get_pos();
00558 vector root_vel = b->get_vel();
00559 for_all_nodes(sdyn3, b, bi) {
00560 bi->inc_pos(-root_pos);
00561 bi->inc_vel(-root_vel);
00562 }
00563 }
00564
00565 local void update_diag_item(int which)
00566 {
00567 set_temp_buffer(which);
00568 lux_update_itemvalue(dia, which, type(which), subtype(which),
00569 temp_buffer);
00570 }
00571
00572 local void get_diag_string(int which) {
00573 }
00574
00575
00576
00577 local void read_diag_item(int which, float& f)
00578 {
00579 lux_get_itemvalue(dia, which, type(which), subtype(which),
00580 temp_buffer);
00581 sscanf(temp_buffer, "%f", &f);
00582 }
00583
00584 local void read_diag_item(int which, int& i)
00585 {
00586 lux_get_itemvalue(dia, which, type(which), subtype(which),
00587 temp_buffer);
00588 sscanf(temp_buffer, "%d", &i);
00589 }
00590
00591 local void read_diag_item(int which, char& c)
00592 {
00593 lux_get_itemvalue(dia, which, type(which), subtype(which),
00594 temp_buffer);
00595 c = temp_buffer[0];
00596 }
00597
00598 local void update_from_dialog(bool b_flag)
00599 {
00600
00601
00602
00603
00604
00605 read_diag_item(view2D, kproj);
00606 if (kproj == 1)
00607 kx = 1, ky = 2;
00608 else if (kproj == 2)
00609 kx = 2, ky = 0;
00610 else
00611 kx = 0, ky = 1;
00612
00613 read_diag_item(originstar, origin_star);
00614
00615 read_diag_item(Xorigin, origin[0]);
00616 read_diag_item(Yorigin, origin[1]);
00617 read_diag_item(Zorigin, origin[2]);
00618
00619 read_diag_item(lmax3D, lmax3d);
00620 lmax3d /= 2;
00621
00622
00623
00624
00625
00626
00627 read_diag_item(xminimum, xmin);
00628 read_diag_item(xmaximum, xmax);
00629 read_diag_item(yminimum, ymin);
00630 read_diag_item(ymaximum, ymax);
00631
00632 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
00633
00634
00635
00636 update_diag_item(xminimum);
00637 update_diag_item(xmaximum);
00638 update_diag_item(yminimum);
00639 update_diag_item(ymaximum);
00640
00641
00642
00643 read_diag_item(basepointsize,base_point_size);
00644
00645 read_diag_item(theta3D, theta);
00646 costheta = cos(theta);
00647 sintheta = sin(theta);
00648
00649 read_diag_item(phi3D, phi);
00650 cosphi = cos(phi);
00651 sinphi = sin(phi);
00652
00653 read_diag_item(dtheta3D, dtheta);
00654
00655 read_diag_item(DelayTime, delay_time);
00656
00657 read_diag_item(colorenergy, cenergy);
00658 show_color_scheme(colwin, c_energy, c_index,
00659 r_factor, cenergy, b_flag, 1);
00660
00661 read_diag_item(tracking, track);
00662 read_diag_item(graph3dim, graph3d);
00663
00664 lux_clear_window(win);
00665
00666 if (graph3d) {
00667 lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d,
00668 -FAC3D*lmax3d, FAC3D*lmax3d);
00669 draw3d_axis(win, lmax3d, costheta, sintheta,
00670 cosphi, sinphi);
00671 } else {
00672 lux_setup_axis(win, xmin, xmax, ymin, ymax);
00673 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
00674 }
00675
00676 read_diag_item(pointscalemode, point_scale_mode);
00677 }
00678
00679 local void show_static_rotation(sdyn3* b, bool f_flag)
00680 {
00681
00682
00683 show_instructions(instr, r_factor,
00684 "Pause...\n r: rotate, (p,c): continue ",
00685 1);
00686
00687 char rotate = 0;
00688 do {
00689 if (lux_check_keypress(win,'r')) {
00690 show_instructions(instr, r_factor,
00691 "Rotate... p: pause, c: continue, c: exit rotation ",
00692 0);
00693 rotate = 1;
00694
00695 do {
00696 theta += dtheta;
00697 if (theta < 0.0)
00698 theta += 2*PI;
00699 else if (theta > PI*2)
00700 theta -= 2*PI;
00701 costheta = cos(theta);
00702 sintheta = sin(theta);
00703 update_diag_item(theta3D);
00704
00705 lux_clear_current_region(win);
00706 draw3d_axis(win, lmax3d, costheta, sintheta,
00707 cosphi, sinphi);
00708
00709 for_all_leaves(sdyn3, b, bi) {
00710 float X, Y, Z;
00711 X = (float)bi->get_pos()[0] - origin[0];
00712 Y = (float)bi->get_pos()[1] - origin[1];
00713 Z = (float)bi->get_pos()[2] - origin[2];
00714 float actual_point_size
00715 = get_point_size(bi);
00716
00717 if ( (X > (-lmax3d + actual_point_size))
00718 && (X < ( lmax3d - actual_point_size))
00719 && (Y > (-lmax3d + actual_point_size))
00720 && (Y < ( lmax3d - actual_point_size))
00721 && (Z > (-lmax3d + actual_point_size))
00722 && (Z < ( lmax3d - actual_point_size))){
00723
00724 float r, s;
00725 project3d(X, Y, Z, r, s,
00726 costheta, sintheta,
00727 cosphi, sinphi);
00728
00729 if (cenergy) {
00730 char c;
00731 compute_energies(b, bi, c);
00732 lux_set_color(win,c_energy[c]);
00733 } else if (clean_index(bi)>0) {
00734 if (clean_index(bi) <= N_COLORS)
00735 lux_set_color(win,
00736 c_index[clean_index(bi)]);
00737 else
00738 lux_set_color(win,c_index[1]);
00739 }
00740
00741 if (track)
00742 lux_draw_pointf(win,r,s);
00743 else
00744 if (f_flag)
00745 lux_fill_arcf(win,
00746 r - actual_point_size/2,
00747 s - actual_point_size/2,
00748 actual_point_size,
00749 actual_point_size,
00750 0.0, 360.0);
00751 else
00752 lux_draw_arcf(win,
00753 r - actual_point_size/2,
00754 s - actual_point_size/2,
00755 actual_point_size,
00756 actual_point_size,
00757 0.0, 360.0);
00758 }
00759 }
00760 update_with_delay(win, delay_time);
00761
00762 if (lux_check_keypress(win,'p'))
00763 while(!lux_check_keypress(win,'c'));
00764
00765 } while(!lux_check_keypress(win,'c'));
00766
00767
00768
00769 while(lux_check_keypress(win,'c'));
00770 }
00771
00772 } while(!lux_check_keypress(win,'p')
00773 && !lux_check_keypress(win,'c') && !rotate);
00774
00775 rotate = 0;
00776 lux_set_color(win,c_energy[default_color]);
00777 }
00778
00779 local void check_for_input(unsigned long win, sdyn3* b,
00780 bool b_flag, bool f_flag)
00781 {
00782
00783
00784
00785
00786
00787 char key, string[20], shift, control;
00788
00789 while (lux_next_keypress(win, &key, string, &shift, &control)) {
00790
00791
00792
00793 if (key == 0
00794
00795 || key == 'h'
00796 || key == 'a') {
00797
00798
00799
00800 int change = 0;
00801
00802 if (key == 'h')
00803 change = 4;
00804 else if (key == 'a')
00805 change = 5;
00806
00807 else if (strcmp(string, "Up") == 0) {
00808 change = ky + 1;
00809 origin[ky] += lmax3d/2;
00810 } else if (strcmp(string, "Down") == 0) {
00811 change = ky + 1;
00812 origin[ky] -= lmax3d/2;
00813 } else if (strcmp(string, "Right") == 0) {
00814 change = kx + 1;
00815 origin[kx] += lmax3d/2;
00816 } else if (strcmp(string, "Left") == 0) {
00817 change = kx + 1;
00818 origin[kx] -= lmax3d/2;
00819 } else if (strcmp(string, "PgUp") == 0) {
00820 change = kproj;
00821 origin[kproj-1] += lmax3d/2;
00822 } else if (strcmp(string, "PgDn") == 0) {
00823 change = kproj;
00824 origin[kproj-1] -= lmax3d/2;
00825 } else if (strcmp(string, "Home") == 0)
00826 change = 4;
00827 else if (strcmp(string, "R11") == 0)
00828 change = 5;
00829
00830 if (change) {
00831
00832 if (change == 4) {
00833 origin[kx] = origin[ky] = origin[kproj-1] = 0;
00834 } else if (change == 5) {
00835
00836 real save = lmax3d;
00837 lmax3d = 0;
00838
00839
00840
00841 for_all_leaves(sdyn3, b, bi)
00842 for (int kk = 0; kk < 3; kk++)
00843 lmax3d = max(lmax3d, abs(bi->get_pos()[kk]
00844 - local_offset[kk]));
00845
00846
00847
00848 lmax3d *= 1.2;
00849 if (lmax3d <= 0) lmax3d = 1;
00850
00851 real m_log = log10(lmax3d);
00852 int i_log = (int) m_log;
00853 if (m_log - i_log > 0.699) i_log++;
00854 real scale = pow(10.0, i_log);
00855 lmax3d = ((int) (lmax3d/scale) + 1) * scale;
00856
00857 origin[kx] = origin[ky] = origin[kproj-1] = 0;
00858 base_point_size *= lmax3d/save;
00859 }
00860
00861 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
00862
00863
00864
00865 update_diag_item(xminimum);
00866 update_diag_item(xmaximum);
00867 update_diag_item(yminimum);
00868 update_diag_item(ymaximum);
00869
00870 if (change == 1 || change >= 4) update_diag_item(Xorigin);
00871 if (change == 2 || change >= 4) update_diag_item(Yorigin);
00872 if (change == 3 || change >= 4) update_diag_item(Zorigin);
00873
00874 if (change == 5) {
00875 update_diag_item(basepointsize);
00876 update_diag_item(lmax3D);
00877 }
00878
00879
00880
00881 if (!graph3d) {
00882 lux_clear_window(win);
00883 lux_setup_axis(win, xmin, xmax, ymin, ymax);
00884 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
00885 } else if (change == 5) {
00886 lux_clear_window(win);
00887 lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d,
00888 -FAC3D*lmax3d, FAC3D*lmax3d);
00889 draw3d_axis(win, lmax3d, costheta, sintheta,
00890 cosphi, sinphi);
00891 }
00892 }
00893
00894 } else {
00895
00896
00897
00898 if (key == 'q') {
00899 show_instructions(instr, r_factor,
00900 "\n Quitting... ",
00901 1);
00902 lux_exit();
00903 }
00904
00905
00906
00907 if (graph3d && !track) {
00908 int button;
00909
00910
00911
00912 if (key== 'R') {
00913
00914 show_static_rotation(b, f_flag);
00915
00916 } else {
00917
00918 button = lux_check_buttonpress(win);
00919
00920 if (key == '^') {
00921 phi = phi - dtheta;
00922 if (phi < -PI) phi = phi + 2.0*PI;
00923 cosphi = cos(phi);
00924 sinphi = sin(phi);
00925 update_diag_item(phi3D);
00926 } else if (key == 'V') {
00927 phi = phi + dtheta;
00928 if (phi > PI) phi = phi - 2.0*PI;
00929 cosphi = cos(phi);
00930 sinphi = sin(phi);
00931 update_diag_item(phi3D);
00932 } else if (key == '<') {
00933 theta = theta + dtheta;
00934 if (theta > 2*PI) theta -= 2*PI;
00935 costheta = cos(theta);
00936 sintheta = sin(theta);
00937 update_diag_item(theta3D);
00938 } else if (key == '>') {
00939 theta = theta - dtheta;
00940 if (theta < 0.0) theta += 2*PI;
00941 costheta = cos(theta);
00942 sintheta = sin(theta);
00943 update_diag_item(theta3D);
00944 }
00945 }
00946 }
00947
00948
00949
00950 if (key == 'p' || key == 'P') {
00951
00952 if (key == 'p') {
00953 if (base_point_size > 4*lmax3d/win_size)
00954 base_point_size /= PFAC;
00955 } else
00956 base_point_size *= PFAC;
00957
00958 update_diag_item(basepointsize);
00959
00960 } else if (key == 'n') {
00961
00962 nodes = 1 - nodes;
00963 if (nodes == 0) links = 0;
00964
00965 } else if (key == 'l') {
00966
00967 links = 1 - links;
00968 if (links == 1) nodes = 1;
00969
00970 } else if (key == 'r') {
00971
00972 root = 1 - root;
00973
00974 } else if (key == 't') {
00975
00976 track = 1 - track;
00977 update_diag_item(tracking);
00978
00979 } else if (key == '3' && !graph3d) {
00980
00981 graph3d = 1;
00982 update_diag_item(graph3dim);
00983 lux_clear_window(win);
00984 lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d,
00985 -FAC3D*lmax3d, FAC3D*lmax3d);
00986 draw3d_axis(win, lmax3d, costheta, sintheta, cosphi, sinphi);
00987
00988 } else if (graph3d &&
00989 (key == '2' || key == 'x'
00990 || key == 'y' || key == 'k')) {
00991
00992 graph3d = 0;
00993 update_diag_item(graph3dim);
00994 lux_clear_window(win);
00995 lux_setup_axis(win, xmin, xmax, ymin, ymax);
00996 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
00997
00998 } else if (key == 'e') {
00999
01000 cenergy = !cenergy;
01001 update_diag_item(colorenergy);
01002 show_color_scheme(colwin, c_energy, c_index,
01003 r_factor, cenergy, b_flag, 1);
01004
01005 } else if (key == '+' || key == '=') {
01006
01007 delay_time += 0.05;
01008 update_diag_item(DelayTime);
01009
01010 } else if (key == '-') {
01011
01012 delay_time -= 0.05;
01013 if (delay_time < 0.0) delay_time = 0.0;
01014 update_diag_item(DelayTime);
01015
01016 } if (key == '0') {
01017
01018 delay_time = 0.0;
01019 update_diag_item(DelayTime);
01020
01021
01022
01023 while(lux_check_keypress(win,'+')
01024 || lux_check_keypress(win,'-'));
01025
01026 } else if (key == 'z') {
01027
01028
01029 lmax3d /= ZOOM;
01030 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01031 base_point_size /= ZOOM;
01032
01033 if (graph3d) {
01034 lux_clear_window(win);
01035 lux_setup_axis(win,-FAC3D*lmax3d,FAC3D*lmax3d,
01036 -FAC3D*lmax3d, FAC3D*lmax3d);
01037 draw3d_axis(win, lmax3d, costheta, sintheta,
01038 cosphi, sinphi);
01039 } else {
01040 lux_clear_window(win);
01041 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01042 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01043 }
01044
01045 update_diag_item(basepointsize);
01046 update_diag_item(lmax3D);
01047 update_diag_item(xminimum);
01048 update_diag_item(xmaximum);
01049 update_diag_item(yminimum);
01050 update_diag_item(ymaximum);
01051
01052 } else if (key == 'Z') {
01053
01054 lmax3d *= ZOOM;
01055 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01056 base_point_size *= ZOOM;
01057
01058 if (graph3d) {
01059 lux_clear_window(win);
01060 lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d,
01061 -FAC3D*lmax3d, FAC3D*lmax3d);
01062 draw3d_axis(win, lmax3d, costheta, sintheta,
01063 cosphi, sinphi);
01064 } else {
01065 lux_clear_window(win);
01066 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01067 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01068 }
01069
01070 update_diag_item(basepointsize);
01071 update_diag_item(lmax3D);
01072 update_diag_item(xminimum);
01073 update_diag_item(xmaximum);
01074 update_diag_item(yminimum);
01075 update_diag_item(ymaximum);
01076
01077 } else if (key == 'k') {
01078
01079 if (graph3d) {
01080
01081 theta = -PI/2;
01082 phi = PI/2.0;
01083 costheta = cos(theta);
01084 sintheta = sin(theta);
01085 cosphi = cos(phi);
01086 sinphi = sin(phi);
01087
01088 update_diag_item(theta3D);
01089 update_diag_item(phi3D);
01090
01091 while (lux_check_keypress(win,'<')
01092 || lux_check_keypress(win,'>')
01093 || lux_check_keypress(win,'^')
01094 || lux_check_keypress(win,'V') );
01095
01096 } else {
01097
01098 kproj = 3;
01099 kx = 0;
01100 ky = 1;
01101 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01102 lux_clear_window(win);
01103 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01104 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01105
01106 update_diag_item(view2D);
01107
01108 }
01109
01110 } else if (key == 'y') {
01111
01112 if (graph3d) {
01113
01114 theta = -PI/2.0;
01115 phi = 0.0;
01116 costheta = cos(theta);
01117 sintheta = sin(theta);
01118 cosphi = cos(phi);
01119 sinphi = sin(phi);
01120
01121 while (lux_check_keypress(win,'<')
01122 || lux_check_keypress(win,'>')
01123 || lux_check_keypress(win,'^')
01124 || lux_check_keypress(win,'V') );
01125
01126 update_diag_item(theta3D);
01127 update_diag_item(phi3D);
01128
01129 } else {
01130
01131 kproj = 2;
01132 kx = 2;
01133 ky = 0;
01134 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01135 lux_clear_window(win);
01136 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01137 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01138
01139 update_diag_item(view2D);
01140
01141 }
01142
01143 } else if (key == 'x') {
01144
01145 if (graph3d) {
01146 theta = 0.0;
01147 phi = 0.0;
01148 costheta = cos(theta);
01149 sintheta = sin(theta);
01150 cosphi = cos(phi);
01151 sinphi = sin(phi);
01152
01153 while (lux_check_keypress(win,'<')
01154 || lux_check_keypress(win,'>')
01155 || lux_check_keypress(win,'^')
01156 || lux_check_keypress(win,'V') );
01157
01158 update_diag_item(theta3D);
01159 update_diag_item(phi3D);
01160
01161 } else {
01162
01163 kproj = 1;
01164 kx = 1;
01165 ky = 2;
01166 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01167 lux_clear_window(win);
01168 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01169 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01170
01171 update_diag_item(view2D);
01172
01173 }
01174 }
01175
01176
01177
01178 if (key == 'o' && !graph3d) {
01179
01180 show_instructions(instr, r_factor,
01181 " Use mouse-right to select new origin...\n",1);
01182 float r, s;
01183 get_mouse_position(win, &r, &s);
01184
01185
01186
01187 origin[kx] = r;
01188 origin[ky] = s;
01189 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01190
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 origin_star = -1;
01196
01197 update_diag_item(Xorigin);
01198 update_diag_item(Yorigin);
01199 update_diag_item(Zorigin);
01200 update_diag_item(xminimum);
01201 update_diag_item(xmaximum);
01202 update_diag_item(yminimum);
01203 update_diag_item(ymaximum);
01204 update_diag_item(originstar);
01205
01206 } else if (!graph3d && key == 'O') {
01207
01208 show_instructions(instr, r_factor,
01209 " Use mouse-right to select new origin star...\n",1);
01210 float r, s;
01211 get_mouse_position(win, &r, &s);
01212
01213
01214
01215
01216
01217 origin_star = nearest_index(b, r, s, kx, ky);
01218
01219 if (origin_star > 0) {
01220 for (int kk = 0; kk < 3; kk++) origin[kk] = 0;
01221 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01222 }
01223
01224 lux_clear_window(win);
01225 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01226 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01227
01228 update_diag_item(Xorigin);
01229 update_diag_item(Yorigin);
01230 update_diag_item(Zorigin);
01231 update_diag_item(xminimum);
01232 update_diag_item(xmaximum);
01233 update_diag_item(yminimum);
01234 update_diag_item(ymaximum);
01235 update_diag_item(originstar);
01236 }
01237
01238
01239
01240 while(lux_check_keypress(win,'r'));
01241
01242
01243
01244 int return_value = 0;
01245
01246 if (key == 'i') {
01247
01248 show_instructions(instr, r_factor,
01249 " Idle...\n d: dialog, r: replay, c: continue: q-quit",1);
01250 return_value = lux_getevent();
01251
01252 } else if (key == 'd') {
01253
01254 show_instructions(instr, r_factor,
01255 "Dialog mode keyboard options\n\n\
01256 Dialog window:\n\
01257 o OK, keep dialog window\n\
01258 O OK, close dialog window\n\
01259 c CANCEL, keep dialog window\n\
01260 C CANCEL, close dialog window\n\n\
01261 Other windows:\n\
01262 r replay
01263 c continue (keep dialog window,\n\
01264 ignore dialog changes)\n\
01265 q quit\n\
01266 ",1);
01267 lux_show_dialog(dia);
01268 return_value = lux_getevent();
01269 }
01270
01271
01272
01273
01274 if (return_value == 3) update_from_dialog(b_flag);
01275 }
01276 }
01277 }
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290 void xstarplot(sdyn3* b, float scale, int k, int d, float lmax,
01291 int point_mode, float rel_point_size,
01292 float D, int ce,
01293 bool b_flag, bool f_flag, bool t_flag,
01294 int init_flag)
01295 {
01296 r_factor = scale;
01297
01298 if (init_flag == 0) {
01299
01300 int xorigin, yorigin;
01301
01302 if (t_flag) nodes = links = 1;
01303
01304
01305
01306
01307 if (init_status == 0) initialize_graphics(r_factor, b_flag,
01308 win, instr, colwin,
01309 c_index, c_energy,
01310 win_size, xorigin, yorigin);
01311 lux_clear_window(win);
01312 lux_update_fg(win);
01313 lux_clear_window(colwin);
01314 lux_update_fg(colwin);
01315 lux_clear_window(instr);
01316 lux_update_fg(instr);
01317
01318
01319
01320 kproj = k;
01321 switch (kproj) {
01322 case 1: kx = 1; ky = 2; graph3d = 0; break;
01323 case 2: kx = 2; ky = 0; graph3d = 0; break;
01324 case 3: kx = 0; ky = 1; graph3d = 0; break;
01325 default: cerr << "xstarplot: k = " << k
01326 << ": illegal value; choose from {1, 2, 3}"
01327 << endl;
01328 exit(0);
01329 }
01330
01331 switch(d) {
01332 case 2: graph3d = 0; break;
01333 case 3: graph3d = 1; break;
01334 default: cerr << "xstarplot: d = " << d
01335 << " illegal value; choose from {2, 3)"
01336 << endl;
01337 exit(0);
01338 }
01339
01340 point_scale_mode = point_mode;
01341
01342 cenergy = ce?1:0;
01343 show_color_scheme(colwin, c_energy, c_index,
01344 r_factor, cenergy, b_flag,1);
01345
01346 delay_time = D;
01347
01348 if (lmax > 0.0)
01349
01350 lmax3d = lmax;
01351
01352 else {
01353
01354 lmax3d = 0;
01355
01356
01357
01358 for_all_leaves(sdyn3, b, bi)
01359 for (int kk = 0; kk < 3; kk++)
01360 lmax3d = max(lmax3d, abs(bi->get_pos()[kk]));
01361
01362
01363
01364 lmax3d *= 1.2;
01365 if (lmax3d <= 0) lmax3d = 1;
01366
01367 real m_log = log10(lmax3d);
01368 int i_log = (int) m_log;
01369 if (m_log - i_log > 0.699) i_log++;
01370 real scale = pow(10.0, i_log);
01371 lmax3d = ((int) (lmax3d/scale) + 1) * scale;
01372 }
01373
01374 for (int ko = 0; ko < 3; ko++) origin[ko] = 0;
01375
01376 set_limits(origin, lmax3d, kx, xmin, xmax, ky, ymin, ymax);
01377 set_base_point_size(rel_point_size);
01378
01379 if (graph3d) {
01380 lux_setup_axis(win, -FAC3D*lmax3d, FAC3D*lmax3d,
01381 -FAC3D*lmax3d, FAC3D*lmax3d);
01382 draw3d_axis(win, lmax3d, costheta, sintheta, cosphi, sinphi);
01383 } else {
01384 lux_setup_axis(win, xmin, xmax, ymin, ymax);
01385 draw2d_axis(win, xmin, xmax, ymin, ymax, kproj);
01386 }
01387
01388
01389
01390 if (init_status == 0) initialize_dialog(xorigin, yorigin);
01391
01392 init_status = 1;
01393
01394 } else if (init_flag < 0) {
01395
01396 show_instructions(instr, r_factor,
01397 "End of Data. Idle now.\n r: replay, (c,q): quit", 1);
01398
01399 lux_getevent();
01400 exit(0);
01401
01402 }
01403
01404
01405
01406
01407
01408
01409
01410
01411 if (track == 0) {
01412
01413 lux_clear_current_region(win);
01414 if (graph3d) draw3d_axis(win, lmax3d, costheta, sintheta,
01415 cosphi, sinphi);
01416 }
01417
01418 show_main_instructions(instr, r_factor, graph3d, 1);
01419
01420
01421
01422
01423
01424
01425 make_relative_to_root(b);
01426
01427
01428
01429 if (origin_star > 0) {
01430 for_all_leaves(sdyn3, b, bi)
01431 if (clean_index(bi) == origin_star) {
01432 for (int kk = 0; kk < 3; kk++)
01433 local_offset[kk] = bi->get_pos()[kk];
01434 break;
01435 }
01436 } else
01437 for (int kk = 0; kk < 3; kk++) local_offset[kk] = 0;
01438
01439
01440
01441 int n_stars = plot_stars(b, f_flag);
01442
01443
01444
01445 lux_set_color(win, c_energy[default_color]);
01446
01447 if (graph3d) {
01448
01449 sprintf(temp_buffer, "N = %d (snapshot #%5d) max=%5.3f",
01450 n_stars, init_flag + 1, lmax3d);
01451 lux_draw_image_string(win, 0.0, lmax3d*FAC3D, 0.5, temp_buffer, 0);
01452
01453 } else {
01454
01455 sprintf(temp_buffer, "N = %d (snapshot #%5d)", n_stars, init_flag + 1);
01456 lux_draw_image_string(win, (xmin+xmax)/2.0, ymax, 0.5, temp_buffer, 0);
01457
01458 }
01459
01460
01461
01462 update_with_delay(win, delay_time);
01463
01464
01465
01466 check_for_input(win, b, b_flag, f_flag);
01467 }
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480 main(int argc, char** argv)
01481 {
01482
01483
01484 int k = 3;
01485 int d = 2;
01486 float D = 0.0;
01487 int cenergy = 0;
01488 float lmax = -1.0;
01489 int point_mode = 0;
01490 float rel_point_size = -1.0;
01491 float scale = 1.0;
01492
01493 bool b_flag = TRUE;
01494 bool f_flag = TRUE;
01495 bool o_flag = FALSE;
01496 bool t_flag = FALSE;
01497
01498 check_help();
01499
01500 extern char *poptarg;
01501 char* params = "a:d:D:efl:op:P:rs:t";
01502 int c;
01503
01504 while ((c = pgetopt(argc, argv, params)) != -1)
01505 switch(c) {
01506
01507 case 'a': k = atoi(poptarg);
01508 break;
01509 case 'd': d = atoi(poptarg);
01510 break;
01511 case 'D': D = atof(poptarg);
01512 break;
01513 case 'e': cenergy = 1;
01514 break;
01515 case 'f': f_flag = FALSE;
01516 break;
01517 case 'l': lmax = atof(poptarg);
01518 break;
01519 case 'o': o_flag = TRUE;
01520 break;
01521 case 'p': point_mode = atoi(poptarg);
01522 break;
01523 case 'P': rel_point_size = atof(poptarg);
01524 break;
01525 case 'r': b_flag = FALSE;
01526 break;
01527 case 's': scale = atof(poptarg);
01528 break;
01529 case 't': t_flag = TRUE;
01530 break;
01531 case '?': params_to_usage(cerr, argv[0], params);
01532 get_help();
01533 exit(0);
01534 }
01535
01536
01537
01538 if (point_mode == 2 && rel_point_size > 0)
01539 rel_point_size = 1.0/rel_point_size;
01540
01541
01542
01543 #define MAX_SNAP 64
01544
01545 sdyn3ptr b[MAX_SNAP];
01546
01547 int gfx_counter = 0;
01548 int snap_counter = -1;
01549 int first_snap = 0;
01550 bool wrapped = false;
01551
01552 while (true) {
01553
01554
01555
01556 if (++snap_counter >= MAX_SNAP) {
01557 snap_counter = 0;
01558 wrapped = true;
01559 }
01560
01561 if (wrapped) {
01562
01563
01564
01565 rmtree(b[snap_counter]);
01566 first_snap = snap_counter + 1;
01567 if (first_snap >= MAX_SNAP) first_snap = 0;
01568 }
01569
01570 if ( (b[snap_counter] = get_sdyn3(cin)) == NULL ) break;
01571
01572
01573
01574 convert_relative_to_absolute(b[snap_counter]);
01575 xstarplot(b[snap_counter], scale, k, d, lmax,
01576 point_mode, rel_point_size, D, cenergy,
01577 b_flag, f_flag, t_flag, gfx_counter++);
01578 if (o_flag) put_node(cout, *b[snap_counter]);
01579 }
01580
01581 if (o_flag) cout << "End of data\n" << flush;
01582
01583
01584
01585 if (--snap_counter < 0) snap_counter = MAX_SNAP - 1;
01586 xstarplot(b[snap_counter], scale, k, d, lmax,
01587 point_mode, rel_point_size, D, cenergy,
01588 b_flag, f_flag, t_flag, -1);
01589 }