socketwindow.h (16454B)
1 #ifndef GTKMM_SOCKETWINDOW_H 2 #define GTKMM_SOCKETWINDOW_H 3 #include <deque> 4 #include <vector> 5 #include <string> 6 #include <cmath> 7 #include <cstdlib> 8 #include <gtkmm.h> 9 #include <gtkmm/socket.h> 10 #include "gnuplot-iostream/gnuplot-iostream.h" 11 12 class SocketWindow : public Gtk::Window{ 13 double state_1[4]={-0.22,-0.2,-0.36,-0.35}; 14 double prev_state_1[4]={-0.22,-0.2,-0.36,-0.35}; 15 double state_2[4]={-0.221,-0.2,-0.36,-0.35}; 16 double prev_state_2[4]={-0.22,-0.2,-0.36,-0.35}; 17 double state_3[4]={-0.222,-0.2,-0.36,-0.35}; 18 double prev_state_3[4]={-0.22,-0.2,-0.36,-0.35}; 19 deque<pair<double, double>> pts_real_1; 20 vector<pair<double, double>> pts_map_1; 21 deque<pair<double, double>> pts_real_2; 22 vector<pair<double, double>> pts_map_2; 23 deque<pair<double, double>> pts_real_3; 24 vector<pair<double, double>> pts_map_3; 25 double closed_orbit=true; 26 int ID_real; 27 int ID_map; 28 bool timeout=false; 29 int timeout_min=50; 30 int timeout_max=1000; 31 int timeout_value=50; 32 double adjustment_min=0; 33 double adjustment_step=0.1; 34 double adjustment_max=11; 35 int steps_per_timeout=1; 36 bool line=true; 37 int n_objects=1;//1,2,3 38 unsigned int trace_length=10; 39 Gnuplot gp_real; 40 Gnuplot gp_map; 41 sigc::connection timeout_connection; 42 protected: 43 void reconnect(){ 44 if (timeout){ 45 timeout_connection.disconnect(); 46 sigc::slot<bool> slot=sigc::mem_fun(*this,&SocketWindow::on_timeout); 47 timeout_connection=Glib::signal_timeout().connect(slot,timeout_value); 48 } 49 } 50 void single_simulate(double prev_state[], double state[], deque<pair<double, double>> &pts_real, vector<pair<double, double>> &pts_map){ 51 for(int step=0;step<steps_per_timeout && closed_orbit;step++){ 52 prev_state[0]=state[0]; 53 prev_state[1]=state[1]; 54 prev_state[2]=state[2]; 55 prev_state[3]=state[3]; 56 closed_orbit=RK_step(state); 57 if ((state[0]>0 && prev_state[0]<0)||(state[0]<0 && prev_state[0]>0)){ 58 pts_map.push_back(make_pair((state[1]+prev_state[1])/2,(state[3]+prev_state[3])/2)); 59 } 60 } 61 pts_real.push_back(make_pair(state[0],state[1])); 62 } 63 void single_clean(double prev_state[], double state[], deque<pair<double, double>> &pts_real, vector<pair<double, double>> &pts_map){ 64 pts_map.clear(); 65 while (pts_real.size()>trace_length){ 66 pts_real.pop_front(); 67 } 68 if (!closed_orbit){ 69 on_button_stop_clicked(); 70 m_label_warn.set_markup("<span foreground=\"#FF0000\" size=\"x-large\" weight=\"bold\"> Simulation stopped: open orbit</span>"); 71 } 72 } 73 bool on_timeout(){ 74 switch (n_objects){ 75 case 3://simulate 3 objects 76 single_simulate(prev_state_3, state_3, pts_real_3, pts_map_3); 77 case 2://...2 78 single_simulate(prev_state_2, state_2, pts_real_2, pts_map_2); 79 case 1://...just 1 80 single_simulate(prev_state_1, state_1, pts_real_1, pts_map_1); 81 } 82 gp_reload(); 83 switch (n_objects){ 84 case 3: 85 single_clean(prev_state_3, state_3, pts_real_3, pts_map_3); 86 case 2: 87 single_clean(prev_state_2, state_2, pts_real_2, pts_map_2); 88 case 1: 89 single_clean(prev_state_1, state_1, pts_real_1, pts_map_1); 90 } 91 return true; 92 } 93 void on_n_objects_changed(){ 94 n_objects=stoi(m_combo_objects.get_active_text()); 95 } 96 void on_trace_length_changed(){ 97 try{ 98 trace_length=stoi(m_Entry_trace.get_text()); 99 } 100 catch(...){ 101 } 102 } 103 void on_checkbutton_toggled(){ 104 line=m_CheckButton_line.get_active(); 105 } 106 void on_button_random_clicked(){ 107 if (!timeout){ 108 m_Entry_q1_1.set_text(to_string(0.7*((double) rand()/RAND_MAX-0.5))); 109 m_Entry_q2_1.set_text(to_string(0.7*((double) rand()/RAND_MAX-0.5))); 110 m_Entry_p1_1.set_text(to_string(0.7*((double) rand()/RAND_MAX-0.5))); 111 m_Entry_p2_1.set_text(to_string(0.7*((double) rand()/RAND_MAX-0.5))); 112 m_Entry_q1_2.set_text(to_string(stod(m_Entry_q1_1.get_text())+0.01)); 113 m_Entry_q2_2.set_text(m_Entry_q2_1.get_text()); 114 m_Entry_p1_2.set_text(m_Entry_p1_1.get_text()); 115 m_Entry_p2_2.set_text(m_Entry_p2_1.get_text()); 116 m_Entry_q1_3.set_text(to_string(stod(m_Entry_q1_1.get_text())+0.02)); 117 m_Entry_q2_3.set_text(m_Entry_q2_1.get_text()); 118 m_Entry_p1_3.set_text(m_Entry_p1_1.get_text()); 119 m_Entry_p2_3.set_text(m_Entry_p2_1.get_text()); 120 } 121 } 122 void try_entry(double &value, Gtk::Entry &m_Entry){ 123 try{ 124 value=stod(m_Entry.get_text()); 125 } 126 catch(...){ 127 value=0; 128 m_label_warn.set_markup("<span foreground=\"#FF0000\" size=\"x-large\" weight=\"bold\"> Nieprawidłowa wartość</span>"); 129 on_button_stop_clicked(); 130 } 131 132 } 133 void sensitivity_off(){ 134 m_Entry_q1_3.set_sensitive(false); 135 m_Entry_q2_3.set_sensitive(false); 136 m_Entry_p1_3.set_sensitive(false); 137 m_Entry_p2_3.set_sensitive(false); 138 m_Entry_q1_2.set_sensitive(false); 139 m_Entry_q2_2.set_sensitive(false); 140 m_Entry_p1_2.set_sensitive(false); 141 m_Entry_p2_2.set_sensitive(false); 142 m_Entry_q1_1.set_sensitive(false); 143 m_Entry_q2_1.set_sensitive(false); 144 m_Entry_p1_1.set_sensitive(false); 145 m_Entry_p2_1.set_sensitive(false); 146 m_combo_objects.set_sensitive(false); 147 } 148 void sensitivity_on(){ 149 m_Entry_q1_3.set_sensitive(true); 150 m_Entry_q2_3.set_sensitive(true); 151 m_Entry_p1_3.set_sensitive(true); 152 m_Entry_p2_3.set_sensitive(true); 153 m_Entry_q1_2.set_sensitive(true); 154 m_Entry_q2_2.set_sensitive(true); 155 m_Entry_p1_2.set_sensitive(true); 156 m_Entry_p2_2.set_sensitive(true); 157 m_Entry_q1_1.set_sensitive(true); 158 m_Entry_q2_1.set_sensitive(true); 159 m_Entry_p1_1.set_sensitive(true); 160 m_Entry_p2_1.set_sensitive(true); 161 m_combo_objects.set_sensitive(true); 162 } 163 void on_button_start_clicked(){ 164 closed_orbit=true; 165 timeout=true; 166 m_label_warn.set_text(""); 167 pts_real_1.clear(); 168 pts_map_1.clear(); 169 pts_real_2.clear(); 170 pts_map_2.clear(); 171 pts_real_3.clear(); 172 pts_map_3.clear(); 173 sensitivity_off(); 174 switch (n_objects){ 175 case 3: 176 try_entry(state_3[0],m_Entry_q1_3); 177 try_entry(state_3[1],m_Entry_q2_3); 178 try_entry(state_3[2],m_Entry_p1_3); 179 try_entry(state_3[3],m_Entry_p2_3); 180 case 2: 181 try_entry(state_2[0],m_Entry_q1_2); 182 try_entry(state_2[1],m_Entry_q2_2); 183 try_entry(state_2[2],m_Entry_p1_2); 184 try_entry(state_2[3],m_Entry_p2_2); 185 case 1: 186 try_entry(state_1[0],m_Entry_q1_1); 187 try_entry(state_1[1],m_Entry_q2_1); 188 try_entry(state_1[2],m_Entry_p1_1); 189 try_entry(state_1[3],m_Entry_p2_1); 190 } 191 gp_reset(); 192 reconnect(); 193 } 194 void on_button_stop_clicked(){ 195 timeout=false; 196 timeout_connection.disconnect(); 197 sensitivity_on(); 198 } 199 void on_reset_view(){ 200 gp_real<<"set xrange [-0.8:0.8]\n"; 201 gp_real<<"set yrange [-0.8:0.8]\n"; 202 gp_real<<"replot\n"; 203 gp_real.flush(); 204 gp_map<<"set xrange [-0.8:0.8]\n"; 205 gp_map<<"set yrange [-0.8:0.8]\n"; 206 gp_map<<"replot\n"; 207 gp_map.flush(); 208 } 209 void on_adjustment_step(){ 210 double x=exp(m_adjustment_step->get_value()); 211 double max=exp(adjustment_max); 212 timeout_value=(timeout_max-timeout_min)*x/max+timeout_min; 213 steps_per_timeout=x*timeout_value/timeout_min; 214 reconnect(); 215 } 216 void gp_reload(){ 217 if (line){ 218 switch (n_objects){ 219 case 3: 220 gp_real<<"plot \"<echo '0 -0.8\\n0 0.8'\" w l lw 1.5 linecolor rgb 'red',"; 221 gp_real<<gp_real.binFile1d(pts_real_3, "record")<<"w l lw 1.5 linecolor rgb 'blue',"; 222 gp_real<<gp_real.binFile1d(pts_real_2, "record")<<"w l lw 1.5 linecolor rgb 'green',"; 223 gp_real<<gp_real.binFile1d(pts_real_1, "record")<<"w l lw 1.5 linecolor rgb 'black'\n"; 224 break; 225 case 2: 226 gp_real<<"plot \"<echo '0 -0.8\\n0 0.8'\" w l lw 1.5 linecolor rgb 'red',"; 227 gp_real<<gp_real.binFile1d(pts_real_2, "record")<<"w l lw 1.5 linecolor rgb 'green',"; 228 gp_real<<gp_real.binFile1d(pts_real_1, "record")<<"w l lw 1.5 linecolor rgb 'black'\n"; 229 break; 230 case 1: 231 gp_real<<"plot \"<echo '0 -0.8\\n0 0.8'\" w l lw 1.5 linecolor rgb 'red',"; 232 gp_real<<gp_real.binFile1d(pts_real_1, "record")<<"w l lw 1.5 linecolor rgb 'black'\n"; 233 } 234 } 235 else{ 236 switch (n_objects){ 237 case 3: 238 gp_real<<"plot \"<echo '0 -0.8\\n0 0.8'\" w l lw 1.5 linecolor rgb 'red',"; 239 gp_real<<gp_real.binFile1d(pts_real_3, "record")<<"w p pt 7 pointsize 1.0 linecolor rgb 'blue',"; 240 gp_real<<gp_real.binFile1d(pts_real_2, "record")<<"w p pt 7 pointsize 1.0 linecolor rgb 'green',"; 241 gp_real<<gp_real.binFile1d(pts_real_1, "record")<<"w p pt 7 pointsize 1.0 linecolor rgb 'black'\n"; 242 break; 243 case 2: 244 gp_real<<"plot \"<echo '0 -0.8\\n0 0.8'\" w l lw 1.5 linecolor rgb 'red',"; 245 gp_real<<gp_real.binFile1d(pts_real_2, "record")<<"w p pt 7 pointsize 1.0 linecolor rgb 'green',"; 246 gp_real<<gp_real.binFile1d(pts_real_1, "record")<<"w p pt 7 pointsize 1.0 linecolor rgb 'black'\n"; 247 break; 248 case 1: 249 gp_real<<"plot \"<echo '0 -0.8\\n0 0.8'\" w l lw 1.5 linecolor rgb 'red',"; 250 gp_real<<gp_real.binFile1d(pts_real_1, "record")<<"w p pt 7 pointsize 1.0 linecolor rgb 'black'\n"; 251 } 252 } 253 gp_real.flush(); 254 switch (n_objects){ 255 case 3: 256 if (!pts_map_3.empty()){ 257 gp_map<<"replot "<<gp_map.binFile1d(pts_map_3, "record")<<"w p pt 7 pointsize 1.0 linecolor rgb 'blue'\n"; 258 } 259 case 2: 260 if (!pts_map_2.empty()){ 261 gp_map<<"replot "<<gp_map.binFile1d(pts_map_2, "record")<<"w p pt 7 pointsize 1.0 linecolor rgb 'green'\n"; 262 } 263 case 1: 264 if (!pts_map_1.empty()){ 265 gp_map<<"replot "<<gp_map.binFile1d(pts_map_1, "record")<<"w p pt 7 pointsize 1.0 linecolor rgb 'black'\n"; 266 } 267 } 268 gp_map.flush(); 269 } 270 void gp_reset(){ 271 gp_real<<"set term x11 window \""<<hex<<ID_real<<"\"\n"; 272 gp_real<<"set xrange [-0.8:0.8]\n"; 273 gp_real<<"set yrange [-0.8:0.8]\n"; 274 gp_real<<"set key off\n"; 275 gp_real<<"plot \"<echo '0 -0.8\\n0 0.8'\" w l lw 1.5 linecolor rgb 'red'\n"; 276 gp_real.flush(); 277 gp_map<<"set term x11 window \""<<hex<<ID_map<<"\"\n"; 278 gp_map<<"set xrange [-0.8:0.8]\n"; 279 gp_map<<"set yrange [-0.8:0.8]\n"; 280 gp_map<<"set key off\n"; 281 gp_map<<"plot 2 with lines\n"; 282 gp_map.flush(); 283 } 284 //Child widgets: 285 Gtk::Box m_box,m_box_ui,m_box_objects; 286 Gtk::Box m_box_q1,m_box_q2,m_box_p1,m_box_p2; 287 Gtk::Box m_box_plotutil; 288 Gtk::ComboBoxText m_combo_objects; 289 Gtk::Entry m_Entry_trace; 290 Gtk::Button m_button_random; 291 Gtk::Button m_button_start,m_button_stop; 292 Gtk::Button m_button_reset_view; 293 Gtk::Label m_label_warn; 294 Gtk::CheckButton m_CheckButton_line; 295 Glib::RefPtr<Gtk::Adjustment> m_adjustment_step; 296 Gtk::Scale m_scale_step; 297 Gtk::Entry m_Entry_q1_1,m_Entry_q2_1,m_Entry_p1_1,m_Entry_p2_1, 298 m_Entry_q1_2,m_Entry_q2_2,m_Entry_p1_2,m_Entry_p2_2, 299 m_Entry_q1_3,m_Entry_q2_3,m_Entry_p1_3,m_Entry_p2_3; 300 public: 301 SocketWindow(): 302 gp_real(), 303 gp_map(), 304 m_box(Gtk::ORIENTATION_HORIZONTAL), 305 m_box_ui(Gtk::ORIENTATION_VERTICAL), 306 m_box_q1(Gtk::ORIENTATION_HORIZONTAL), 307 m_box_q2(Gtk::ORIENTATION_HORIZONTAL), 308 m_box_p1(Gtk::ORIENTATION_HORIZONTAL), 309 m_box_p2(Gtk::ORIENTATION_HORIZONTAL), 310 m_box_plotutil(Gtk::ORIENTATION_HORIZONTAL), 311 m_CheckButton_line("Connect points", 0), 312 m_adjustment_step(Gtk::Adjustment::create(0,adjustment_min,adjustment_max,adjustment_step,1,1)), 313 m_scale_step(m_adjustment_step, Gtk::ORIENTATION_HORIZONTAL) 314 { 315 set_title("Henon"); 316 add(m_box); 317 set_border_width(10); 318 m_box.set_size_request(1000,500); 319 320 auto m_socket_real_p = Gtk::manage(new Gtk::Socket()); 321 m_box.pack_start(*m_socket_real_p); 322 323 auto m_socket_map_p = Gtk::manage(new Gtk::Socket()); 324 m_box.pack_start(*m_socket_map_p); 325 326 m_box.pack_start(m_box_ui,Gtk::PACK_SHRINK); 327 328 m_box_ui.pack_start(*(new Gtk::Label{"Initial conditions:", 0}), Gtk::PACK_SHRINK); 329 330 m_box_ui.pack_start(m_box_objects, Gtk::PACK_SHRINK); 331 m_box_objects.pack_start(*(new Gtk::Label{"Number of objects:", 0}), Gtk::PACK_SHRINK); 332 m_combo_objects.append("1"); 333 m_combo_objects.append("2"); 334 m_combo_objects.append("3"); 335 m_combo_objects.set_active(0); 336 m_combo_objects.signal_changed().connect(sigc::mem_fun(*this,&SocketWindow::on_n_objects_changed)); 337 m_box_objects.pack_start(m_combo_objects, Gtk::PACK_SHRINK); 338 339 m_button_random.add_label("Randomize"); 340 m_button_random.signal_clicked().connect(sigc::mem_fun(*this,&SocketWindow::on_button_random_clicked)); 341 m_box_ui.pack_start(m_button_random,Gtk::PACK_SHRINK); 342 343 m_box_ui.pack_start(m_box_q1, Gtk::PACK_SHRINK); 344 m_box_q1.pack_start(*(new Gtk::Label{"q1:", 0}), Gtk::PACK_SHRINK); 345 m_Entry_q1_1.set_max_length(16); 346 m_Entry_q1_1.set_text(to_string(state_1[0])); 347 m_Entry_q1_1.select_region(0, m_Entry_q1_1.get_text_length()); 348 m_box_q1.pack_start(m_Entry_q1_1); 349 m_Entry_q1_2.set_max_length(16); 350 m_Entry_q1_2.set_text(to_string(state_2[0])); 351 m_Entry_q1_2.select_region(0, m_Entry_q1_2.get_text_length()); 352 m_box_q1.pack_start(m_Entry_q1_2); 353 m_Entry_q1_3.set_max_length(16); 354 m_Entry_q1_3.set_text(to_string(state_3[0])); 355 m_Entry_q1_3.select_region(0, m_Entry_q1_3.get_text_length()); 356 m_box_q1.pack_start(m_Entry_q1_3); 357 358 m_box_ui.pack_start(m_box_q2, Gtk::PACK_SHRINK); 359 m_box_q2.pack_start(*(new Gtk::Label{"q2:", 0}), Gtk::PACK_SHRINK); 360 m_Entry_q2_1.set_max_length(16); 361 m_Entry_q2_1.set_text(to_string(state_1[1])); 362 m_Entry_q2_1.select_region(0, m_Entry_q2_1.get_text_length()); 363 m_box_q2.pack_start(m_Entry_q2_1); 364 m_Entry_q2_2.set_max_length(16); 365 m_Entry_q2_2.set_text(to_string(state_2[1])); 366 m_Entry_q2_2.select_region(0, m_Entry_q2_2.get_text_length()); 367 m_box_q2.pack_start(m_Entry_q2_2); 368 m_Entry_q2_3.set_max_length(16); 369 m_Entry_q2_3.set_text(to_string(state_3[1])); 370 m_Entry_q2_3.select_region(0, m_Entry_q2_3.get_text_length()); 371 m_box_q2.pack_start(m_Entry_q2_3); 372 373 m_box_ui.pack_start(m_box_p1, Gtk::PACK_SHRINK); 374 m_box_p1.pack_start(*(new Gtk::Label{"p1:", 0}), Gtk::PACK_SHRINK); 375 m_Entry_p1_1.set_max_length(16); 376 m_Entry_p1_1.set_text(to_string(state_1[2])); 377 m_Entry_p1_1.select_region(0, m_Entry_p1_1.get_text_length()); 378 m_box_p1.pack_start(m_Entry_p1_1); 379 m_Entry_p1_2.set_max_length(16); 380 m_Entry_p1_2.set_text(to_string(state_2[2])); 381 m_Entry_p1_2.select_region(0, m_Entry_p1_2.get_text_length()); 382 m_box_p1.pack_start(m_Entry_p1_2); 383 m_Entry_p1_3.set_max_length(16); 384 m_Entry_p1_3.set_text(to_string(state_3[2])); 385 m_Entry_p1_3.select_region(0, m_Entry_p1_3.get_text_length()); 386 m_box_p1.pack_start(m_Entry_p1_3); 387 388 m_box_ui.pack_start(m_box_p2, Gtk::PACK_SHRINK); 389 m_box_p2.pack_start(*(new Gtk::Label{"p2:", 0}), Gtk::PACK_SHRINK); 390 m_Entry_p2_1.set_max_length(16); 391 m_Entry_p2_1.set_text(to_string(state_1[3])); 392 m_Entry_p2_1.select_region(0, m_Entry_p2_1.get_text_length()); 393 m_box_p2.pack_start(m_Entry_p2_1); 394 m_Entry_p2_2.set_max_length(16); 395 m_Entry_p2_2.set_text(to_string(state_2[3])); 396 m_Entry_p2_2.select_region(0, m_Entry_p2_2.get_text_length()); 397 m_box_p2.pack_start(m_Entry_p2_2); 398 m_Entry_p2_3.set_max_length(16); 399 m_Entry_p2_3.set_text(to_string(state_3[3])); 400 m_Entry_p2_3.select_region(0, m_Entry_p2_3.get_text_length()); 401 m_box_p2.pack_start(m_Entry_p2_3); 402 403 m_button_start.add_label("Start"); 404 m_button_start.signal_clicked().connect(sigc::mem_fun(*this,&SocketWindow::on_button_start_clicked)); 405 m_box_ui.pack_start(m_button_start,Gtk::PACK_SHRINK); 406 407 m_button_stop.add_label("Stop"); 408 m_button_stop.signal_clicked().connect(sigc::mem_fun(*this,&SocketWindow::on_button_stop_clicked)); 409 m_box_ui.pack_start(m_button_stop,Gtk::PACK_SHRINK); 410 411 m_box_ui.pack_start(*(new Gtk::Label{"Simulation speed:", 0}), Gtk::PACK_SHRINK); 412 m_adjustment_step->signal_value_changed().connect(sigc::mem_fun(*this,&SocketWindow::on_adjustment_step)); 413 m_box_ui.pack_start(m_scale_step,Gtk::PACK_SHRINK); 414 415 m_box_ui.pack_start(m_box_plotutil,Gtk::PACK_SHRINK); 416 417 m_CheckButton_line.set_active(); 418 m_CheckButton_line.signal_toggled().connect(sigc::mem_fun(*this,&SocketWindow::on_checkbutton_toggled)); 419 m_box_plotutil.pack_start(m_CheckButton_line,Gtk::PACK_SHRINK); 420 421 m_button_reset_view.add_label("Reset view"); 422 m_button_reset_view.signal_clicked().connect(sigc::mem_fun(*this,&SocketWindow::on_reset_view)); 423 m_box_plotutil.pack_start(m_button_reset_view,Gtk::PACK_SHRINK); 424 425 m_box_plotutil.pack_start(*(new Gtk::Label{"Trace length:", 0}), Gtk::PACK_SHRINK); 426 m_Entry_trace.set_max_length(3); 427 m_Entry_trace.set_text(to_string(trace_length)); 428 m_Entry_trace.select_region(0, m_Entry_trace.get_text_length()); 429 m_Entry_trace.signal_changed().connect(sigc::mem_fun(*this,&SocketWindow::on_trace_length_changed)); 430 m_box_plotutil.pack_start(m_Entry_trace,Gtk::PACK_SHRINK); 431 432 m_box_ui.pack_start(m_label_warn,Gtk::PACK_SHRINK); 433 434 ID_real=m_socket_real_p->get_id(); 435 ID_map=m_socket_map_p->get_id(); 436 gp_reset(); 437 show_all_children(); 438 } 439 }; 440 441 #endif