351d829fb4896a168f8b127df00dfdbfb256e1e6
[scilab.git] / scilab / modules / differential_equations / demos / flow / blackhole_interface.sci
1 //
2 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 // Copyright (C) 2008 - INRIA - Pierre MARECHAL
4 // Copyright (C) 2014 - Scilab Enterprises - Pierre-Aime Agnel
5 //
6 // This file is distributed under the same license as the Scilab package.
7 //
8
9 // =============================================================================
10 // BlackHole interface functions
11 // =============================================================================
12 // exeblackhole
13 // =============================================================================
14 function exeblackhole()
15     //initial point
16     g_r = 1.1;
17     g_t = 41;
18
19     //initial speed
20     g_V    = 1.65;
21     g_Vdir = 165;
22
23     // Figure parameters
24     surface_frame_w = 600;     // surface frame width
25     surface_frame_h = 600;     // surface frame height
26
27     control_frame_w = 600;
28     control_frame_h = 200;
29
30     margin_x = 15;      // Horizontal margin between each elements
31     margin_y = 15;      // Vertical margin between each elements
32
33     axes_figure_w = 2 * margin_x + max(surface_frame_w, control_frame_w);
34     axes_figure_h = 3 * margin_y + surface_frame_h + control_frame_h;
35
36     // Figure creation
37     my_figure_handle = createMainWindow([axes_figure_w axes_figure_h], _("Blackhole"), "main_figure");
38     my_figure_handle.immediate_drawing = "off";
39
40     //Simulation parameters
41     speed = tlist(["sim_param", "name", "unit", "range", "default", "tag"], ...
42         "speed", ...
43         "m/s", ...
44         [0 100], ...
45         1, ...
46         "speed");
47
48     direction = tlist(["sim_param", "name", "unit", "range", "default", "tag"], ...
49         "direction", ...
50         "deg", ...
51         [0 100], ...
52         50, ...
53         "dir");
54
55     r = tlist(["sim_param", "name", "unit", "range", "default", "tag"], ...
56         "r", ...
57         "m", ...
58         [4 100], ...
59         1, ...
60         "r");
61
62     theta = tlist(["sim_param", "name", "unit", "range", "default", "tag"], ...
63         "theta", ...
64         "deg", ...
65         [0 100], ...
66         1, ...
67         "theta");
68
69     //Create the controls in the window bottom
70     param_list = list(r, theta, speed, direction);
71     [plot_frame, param_frame, button_frame] = create_gui(my_figure_handle);
72     create_param_zone(param_frame, param_list);
73     create_buttons(button_frame);
74
75
76     draw_blackhole();
77     draw_initial_point(g_r, g_t, g_V, g_Vdir, %T);
78
79
80     //Set control and graphics initial values
81     change_r(g_r)
82     change_theta(g_t)
83     change_speed(g_V)
84     change_dir(g_Vdir)
85     my_figure_handle.visible = "on";
86 endfunction
87
88 // draw_surface
89 // =============================================================================
90 function draw_blackhole()
91     r    = 1;
92     orig = [0 0 0];
93     xx   = -1.85:0.1:1.85;
94     yy   = (-1.85:0.1:1.85)';
95     zt   = sqrt((ones(yy)*(xx .^ 2) + (yy .^ 2) * ones(xx)));
96     zz   = -1 * ones(zt) ./ zt;
97
98     my_handle = get("main_figure");
99
100     my_handle.immediate_drawing = "off";
101     mesh(xx, yy, zz);
102     e = gce();
103     e.color_mode = 0;
104     e.foreground = color("blue");
105     my_handle.immediate_drawing = "on";
106 endfunction
107
108 // draw_initial_point
109 // =============================================================================
110 function draw_initial_point(g_r, g_t, g_V, g_Vdir, create)
111     x = g_r * cos(g_t * %pi / 180);
112     y = g_r * sin(g_t * %pi / 180);
113     r = 0.05;
114     z = -1.0 ./ sqrt(x ^ 2 + y ^ 2) + r;
115     dx1 = g_V * cos(g_Vdir * %pi / 180);
116     dy1 = g_V * sin(g_Vdir * %pi / 180);
117     my_figure_handle = get("main_figure");
118     my_figure_handle.immediate_drawing = "off";
119
120     if create then
121         //create the graphical object used to visualize the trajectory
122         xpoly(0, 0)
123         traj_handle                        = gce();
124         traj_handle.thickness              = 2;
125         traj_handle.foreground             = 5;
126         //create the graphical object used to visualize the initial speed
127         xpoly(0, 0)
128         speed_handle                       =  gce();
129         speed_handle.thickness             =  1;
130         speed_handle.foreground            =  5;
131         speed_handle.polyline_style        =  4;
132         speed_handle.arrow_size_factor     =  2;
133         //create the graphical objects used to visualize the initial position
134         param3d([x - r x + r], [y y], [z z]);
135         e1                                 = gce();
136         e1.thickness                       = 1;
137         e1.foreground                      = 5;
138         param3d([x x], [y - r y + r], [z z]);
139         e2                                 = gce();
140         e2.thickness                       = 1;
141         e2.foreground                      = 5;
142         param3d([x x], [y y], [z - r z + r]);
143         e3                                 = gce();
144         e3.thickness                       = 1;
145         e3.foreground                      = 5;
146         glue([traj_handle speed_handle e1 e2 e3])
147     else
148         curAxe = gca();
149         initial = curAxe.children(1).children
150         initial(1).data = [x  y z - r ; x y z + r];
151         initial(2).data = [x y - r z ; x y + r z];
152         initial(3).data = [x - r y z ; x + r y z];
153     end
154     z1= -1.0 ./ sqrt((x + dx1) ^ 2 + (y + dy1) ^ 2) + r;
155     initial(4).data = [x y z ; x + dx1 y + dy1 z1];
156
157     my_figure_handle.immediate_drawing = "on";
158 endfunction
159
160 // =============================================================================
161 // The gui controls builder
162 // =============================================================================
163 function blackhole_create_gui()
164     //initial values
165     g_t     = 0;
166     g_r     = 0;
167     g_speed = 0;
168     g_Vdir  = 0;
169
170     my_figure_handle = get("main_figure");
171
172     frame_x      = 25;
173     frame_y      = 200;
174
175     slider_height   = 15;
176     slider_width    = 140;
177     value_width     = 30;
178     unit_width      = 30;
179     text_width      = 50;
180     y_margin        = 5;
181     x_margin        = 10;
182     title_width     =  text_width + slider_width + value_width + unit_width + 3 * x_margin
183
184     x_text          = frame_x
185     x_slider        = x_text + text_width + x_margin;
186     x_value         = x_slider + slider_width + x_margin;
187     x_unit          = x_value  + value_width + x_margin;
188
189     y               = frame_y - 40;
190
191     //Create the constraints for the gridbag simulation zone / position + speed frames
192     gen_c = createConstraints("border", "bottom", [600 200]);
193
194     //Create the layout options for the frame containing position and speed frames
195     //1by2 grid with 20 pixel horizontal space for minimum paddding
196     posspeed_lay_opt = createLayoutOptions("grid", [1 2], [20 0]);
197
198
199     gui_frame = uicontrol(my_figure_handle, ...
200         "style", "frame", ...
201         "backgroundcolor", [1 1 1], ...
202         "layout", "border", ...
203         "constraint", gen_c);
204
205     //Frame containing position and speed
206     gen_c.position = "center";
207     frame_posspeed = uicontrol(gui_frame, ...
208         "style", "frame", ...
209         "backgroundcolor", [1 1 1], ...
210         "layout", "grid", ...
211         "layout_options", posspeed_lay_opt, ...
212         "constraint", gen_c);
213
214     //Borders and title around position or speed
215     b_f_posspeed = createBorderFont("", 16);
216     b_l_posspeed = createBorder("line", "navy", 1);
217     b_posspeed = createBorder("titled", b_l_posspeed, "starting point", "center", "top", b_f_posspeed, "navy");
218
219     //Create the internal layout options for the position and speed frames
220     //2by1 grid with 10 pixel vertical space for minimum padding
221     grid_lay_opt = createLayoutOptions("grid", [2 1], [0 10]);
222
223     //Frame initspeed
224     //title initial speed
225     //vertical grid: speed_frame | 10 | direction_frame
226     b_posspeed.title = "initial speed";
227     frame_initspeed = uicontrol(frame_posspeed, ...
228         "style", "frame", ...
229         "backgroundcolor", [1 1 1], ...
230         "layout", "gridbag", ...
231         "border", b_posspeed);
232
233     //speed and direction in initspeed
234     c = createConstraints("gridbag", [1 1 1 1], [1 1], "horizontal", "center", [0 0], [0 20]);
235
236     speed_frame = uicontrol(frame_initspeed, ...
237         "style", "frame", ...
238         "backgroundcolor", [1 1 1], ...
239         "layout", "gridbag", ...
240         "constraints", c);
241
242     createSliderFrame(speed_frame, "speed", "speed", "(m/s)");
243
244     c.grid =  [1 2 1 1]
245     direction_frame = uicontrol(frame_initspeed, ...
246         "style", "frame", ...
247         "backgroundcolor", [1 1 1], ...
248         "layout", "gridbag", ...
249         "constraints", c);
250
251     createSliderFrame(direction_frame, "dir", "dir", "(deg)");
252     //Frame initpositiono
253     //titled starting point
254     //vertical grid: r_frame | 10 | theta_frame
255     b_posspeed.title = "initial position";
256     frame_initposition = uicontrol(frame_posspeed, ...
257         "style", "frame", ...
258         "backgroundcolor", [1 1 1], ...
259         "layout", "gridbag", ...
260         "border", b_posspeed);
261
262     c.grid = [1 1 1 1]
263     r_frame = uicontrol(frame_initposition, ...
264         "style", "frame", ...
265         "backgroundcolor", [1 1 1], ...
266         "layout", "gridbag", ...
267         "constraints", c);
268
269     createSliderFrame(r_frame, "r", "r", "(m)");
270
271     c.grid = [1 2 1 1]
272     theta_frame = uicontrol(frame_initposition, ...
273         "style", "frame", ...
274         "backgroundcolor", [1 1 1], ...
275         "layout", "gridbag", ...
276         "constraints", c);
277
278     createSliderFrame(theta_frame, "theta", "theta", "(deg)");
279
280     //Button frame 
281     //esthetic | button 1 | est | button2 | est | button 3 | est
282     gen_c.position = "bottom"
283     gen_c.preferredsize = [0 30];
284     button_frame = uicontrol(gui_frame, ...
285         "style", "frame", ...
286         "backgroundcolor", [1 1 1], ...
287         "layout", "gridbag", ...
288         "constraints", gen_c);
289
290     // Buttons
291     // est | buttons | est
292     // =========================================================================
293     btn_width = 100;
294     btn_margin = 50;
295     btn_height = 20;
296     x = frame_x + 80
297
298     c_button = createConstraints("gridbag", [1 1 1 1], [0 0], "none", "left", [0 0], [100 0]);
299
300     //Esthetic Empty panel
301     est_panel = uicontrol(button_frame, ...
302         "style", "frame", ...
303         "backgroundcolor", [1 1 1], ...
304         "constraints", c_button);
305
306     //Buttons 
307     buttonBorder = createBorder("line", "darkgrey", 3);
308     c_button = createConstraints("gridbag", [2 1 1 1], [0 0], "both", "left", [0 0])
309     //Button Start
310     c_button.anchor = "left"
311     start_button = uicontrol(button_frame, ...
312         "Style", "pushbutton", ...
313         "String", "Start", ...
314         "Fontsize", 14, ...
315         "BackgroundColor", [0.9 0.9 0.9], ...
316         "callback", "start_simu()", ...
317         "border", buttonBorder, ...
318         "tag", "start_button", ...
319         "constraints", c_button);
320
321     //Empty panel
322     c_button = createConstraints("gridbag", [3 1 1 1], [0 0], "none", "center", [0 0], [20 0])
323     est_panel = uicontrol(button_frame, ...
324         "style", "frame", ...
325         "backgroundcolor", [1 1 1], ...
326         "constraints", c_button);
327
328     //Button Stop
329     c_button = createConstraints("gridbag", [4 1 1 1], [0 0], "both", "center", [0 0])
330     stop_button = uicontrol(button_frame, ...
331         "Style", "pushbutton", ...
332         "String", "Stop", ...
333         "Fontsize", 14, ...
334         "BackgroundColor", [0.9 0.9 0.9], ...
335         "border", buttonBorder, ...
336         "callback", "stop_simu", ...
337         "tag", "stop_button", ...
338         "constraints", c_button);
339
340     //Empty panel    
341     c_button = createConstraints("gridbag", [5 1 1 1], [0 0], "none", "center", [0 0], [20 0])
342     est_panel = uicontrol(button_frame, ...
343         "style", "frame", ...
344         "backgroundcolor", [1 1 1], ...
345         "constraints", c_button);
346
347     //Button Clear
348     c_button = createConstraints("gridbag", [6 1 1 1], [0 0], "both", "center", [0 0])
349     clear_button = uicontrol(button_frame, ...
350         "Style", "pushbutton", ...
351         "String", "Clear", ...
352         "Fontsize", 14, ...
353         "BackgroundColor", [0.9 0.9 0.9], ...
354         "callback", "clear_simu", ...
355         "border", buttonBorder, ...
356         "tag", "clear_button", ...
357         "constraints", c_button);
358
359     //Empty panel
360     c_button = createConstraints("gridbag", [7 1 1 1], [0 0], "none", "right", [100 0]);
361     est_panel = uicontrol(button_frame, ...
362         "style", "frame", ...
363         "backgroundcolor", [1 1 1], ...
364         "constraints", c_button);
365
366     return
367 endfunction
368
369 // =============================================================================
370 // The callbacks
371 // =============================================================================
372 function change_r(r)
373     //r slider callback
374     // r is in [0.08 2]
375     slider_r     = get("slider_r");
376     slider_theta = get("slider_theta");
377     slider_speed = get("slider_speed");
378     slider_dir   = get("slider_dir");
379     slider_r     = get("slider_r");
380
381     value_r       = get("value_r");
382     if argn(2)==1 then
383         slider_r.Value=(r-0.007)/(2-0.08)*100;
384     else
385         r=slider_r.Value
386         r=0.007+r*(2-0.08)/100
387     end
388         value_r.String=msprintf("%.3f", r)
389         draw_initial_point(0.007+slider_r.Value*(2-0.08)/100, slider_theta.value*360/100, ...
390             slider_speed.Value*3/100, slider_dir.value*360/100, %F);
391 endfunction
392
393
394 function change_theta(theta)
395     //theta slider callback
396     //theta is in [0 360]
397     slider_r     = get("slider_r");
398     slider_theta = get("slider_theta");
399     slider_speed = get("slider_speed");
400     slider_dir   = get("slider_dir");
401     slider_r     = get("slider_r");
402
403     value_theta   = get("value_theta");
404     if argn(2)==1 then
405         slider_theta.Value=(theta)*100/360;
406     else
407         theta=slider_theta.Value
408         theta=theta*360/100
409     end
410         value_theta.String=msprintf("%.0f", theta)
411         draw_initial_point(0.007+slider_r.Value*(2-0.08)/100, slider_theta.value*360/100, ..
412         slider_speed.Value*3/100, slider_dir.value*360/100, %F);
413 endfunction
414
415 function change_speed(speed)
416     //speed slider callback
417     //speed is in [0 3]
418     slider_r     = get("slider_r");
419     slider_theta = get("slider_theta");
420     slider_speed = get("slider_speed");
421     slider_dir   = get("slider_dir");
422
423     value_speed  = get("value_speed");
424     if argn(2)==1 then
425         slider_speed.Value=(speed)*100/3;
426     else
427         speed=slider_speed.Value
428         speed=speed*3/100
429     end
430     value_speed.String=msprintf("%.0f", speed)
431     draw_initial_point(0.007+slider_r.Value*(2-0.08)/100, slider_theta.value*360/100, ..
432     slider_speed.Value*3/100, slider_dir.value*360/100, %F);
433 endfunction
434
435 function change_dir(dir)
436     //direction slider callback
437     //dir is in [0 360]
438     slider_r        = get("slider_r");
439     slider_theta    = get("slider_theta");
440     slider_speed    = get("slider_speed");
441     slider_dir      = get("slider_dir");
442     value_dir       = get("value_dir");
443
444     if argn(2) == 1 then
445         slider_dir.Value = dir * 100 / 360;
446     else
447         dir = slider_dir.Value
448         dir = dir * 360 / 100
449     end
450
451     value_dir.String = msprintf("%.0f", dir)
452     draw_initial_point(0.007 + slider_r.Value * (2 - 0.08) / 100, slider_theta.value * 360 / 100, ...
453         slider_speed.Value * 3 / 100, slider_dir.value * 360 / 100, %F);
454 endfunction
455
456 function start_simu()
457     //start button callback
458     my_figure_handle = get("main_figure");
459     fin=my_figure_handle.user_data
460     my_figure_handle.user_data=%f
461     slider_r     = get("slider_r");
462     slider_theta = get("slider_theta");
463     slider_speed = get("slider_speed");
464     slider_dir   = get("slider_dir");
465     t     = 0:0.02:15;
466     Y = calculate_traj(0.007 + slider_r.Value * (2 - 0.08) / 100, slider_theta.value * 360 / 100, ...
467         slider_speed.Value * 3 / 100, slider_dir.value * 360 / 100, t)
468     x = Y(1, :)
469     y = Y(3, :)
470     r = 0.1; //bias to have the curve above the surface
471     z = -1.0 ./ sqrt(x .^ 2 + y .^ 2) + r;
472     curAxe = gca();
473     traj_handle = curAxe.children(1).children(5);
474     traj_handle.data = [x(1) y(1) z(1)];
475
476     for k=2:size(x, "*")
477         sleep(10)
478         if is_handle_valid(my_figure_handle) then
479             if execstr("fin = my_figure_handle.user_data", "errcatch") <> 0 | fin then break, end
480             if is_handle_valid(traj_handle) then
481                 traj_handle.data = [traj_handle.data ; [x(k) y(k) z(k)]];
482             else
483                 break;
484             end
485         else
486             break;
487         end
488     end
489
490     if is_handle_valid(my_figure_handle) then
491         my_figure_handle.user_data = %t;
492     end
493 endfunction
494
495 function stop_simu()
496     //stop button callback
497     my_figure_handle = get("main_figure");
498     fin = %T;
499     my_figure_handle.user_data = fin
500 endfunction
501
502 function clear_simu()
503     //clear button callback
504     my_figure_handle = get("main_figure");
505     fin = my_figure_handle.user_data
506     if fin then
507         curAxe = gca();
508         traj_handle = curAxe.children(1).children(5);
509         traj_handle.data = [0 0 0];
510     end
511 endfunction