* Bug #14731 fixed: Demos Graphics=>complex: Re+Im rotations synchronized
[scilab.git] / scilab / modules / graphics / demos / cmplxfunc / demo_custom.dem.sce
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2008 - DIGITEO
3 // Copyright (C) 2014 - Scilab Enterprises - Paul Bignier
4 //
5 // This file is released under the 3-clause BSD license. See COPYING-BSD.
6
7 prot = funcprot();
8 funcprot(0);
9
10 function demo_custom()
11
12     // Parameters
13     // =========================================================================
14
15     frame_w      = 300;     // Frame width
16     frame_h      = 765;     // Frame height
17
18     plot_w       = 500;     // Plot width
19     plot_h       = frame_h; // Plot height
20
21     margin_x     = 15;      // Horizontal margin between each elements
22     margin_y     = 15;      // Vertical margin between each elements
23
24     defaultfont  = "arial"; // Default Font
25
26     // Figure creation
27     // =========================================================================
28
29     axes_w       = 3*margin_x + frame_w + plot_w; // axes width
30     axes_h       = 2*margin_y + frame_h;          // axes height (100 => toolbar height)
31
32     fig_handle = figure( ...
33     "infobar_visible", "off", ...
34     "menubar", "none", ...
35     "toolbar", "none", ...
36     "default_axes", "on", ...
37     "layout", "gridbag", ...
38     "visible", "off", ...
39     "background", -2, ...
40     "figure_position", [0 0], ...
41     "axes_size", [axes_w axes_h], ...
42     "rotation_style", "multiple", ...
43     "figure_name", _("Customize your complex function"));
44
45     // The plot will be in the right 2/3 of the figure
46     a = gca();
47     a.axes_bounds = [1/3 1 2/3 1];
48     a.tight_limits = "on";
49
50     c = createConstraints("gridbag", [2 1 2 1], [1 1], "vertical", "right");
51     // Create an empty panel on the right to occupy the 3/4 of the screen (figure plot)
52     empty_frame = uicontrol(fig_handle, "style", "frame","constraints", c);
53
54     c = createConstraints("gridbag", [1 1 1 5], [0.25 1], "both", "left", [0 0], [150 0]);
55     u = uicontrol(fig_handle, ...
56     "style", "frame", ...
57     "backgroundcolor", [1 1 1], ...
58     "layout", "border", ...
59     "constraints", c);
60
61     // Add top and bottom empty panels to pad the upcoming control panel
62     c = createConstraints("border", "top", [0 20]);
63     top = uicontrol(u, "style", "frame", "backgroundcolor", [1 1 1], "constraints", c);
64     c = createConstraints("border", "bottom", [0 20]);
65     bottom = uicontrol(u, "style", "frame", "backgroundcolor", [1 1 1], "constraints", c);
66
67     // Border for the control parameters frame
68     b_f_controlParams = createBorderFont("", 18);
69     b_l_controlParams = createBorder("line", "navy", 2);
70     b_controlParams   = createBorder("titled", b_l_controlParams, _("Control panel"), "center", "top", b_f_controlParams, "navy");
71
72     control_frame = uicontrol(u, ...
73     "style", "frame", ...
74     "backgroundcolor", [1 1 1], ...
75     "border", b_controlParams, ...
76     "layout", "gridbag", ...
77     "tag", "control_frame");
78
79     demo_viewCode("demo_custom.dem.sce");
80
81     fig_handle.color_map = jetcolormap(128);
82
83     // Frames creation [Control Panel]
84     // =========================================================================
85
86     // Explanatory text
87     // =========================================================================
88
89     my_exptext_string = "";
90
91     my_exptext_string = my_exptext_string + "<html>";
92
93     my_exptext_string = my_exptext_string + "<center>";
94     my_exptext_string = my_exptext_string + "<img src=""file:///"+SCI+"/modules/graphics/demos/cmplxfunc/warning.png"+""">";
95     my_exptext_string = my_exptext_string + "BE CAREFUL, NOTHING IS PROTECTED";
96     my_exptext_string = my_exptext_string + "</center>";
97
98     my_exptext_string = my_exptext_string + "<hr><br />";
99
100     my_exptext_string = my_exptext_string + " To draw your own complex  function :";
101
102     my_exptext_string = my_exptext_string + "<div style=''text-align:justify; margin-top:5px; width:260;''>";
103
104     my_exptext_string = my_exptext_string + "1. define the  function by a correct ";
105     my_exptext_string = my_exptext_string + "string where the complex var must ";
106     my_exptext_string = my_exptext_string + "be z. Also, as the function will ";
107     my_exptext_string = my_exptext_string + "be evaluated on a matrix, don''t forget ";
108     my_exptext_string = my_exptext_string + "the . to operate elementwise. Examples: ";
109
110     my_exptext_string = my_exptext_string + "</div>";
111
112
113     my_exptext_string = my_exptext_string + "<pre>    z.^2       (z+1).*(z-1)     (1)./(z+2)</pre>";
114     my_exptext_string = my_exptext_string + "<pre>    sqrt(z)    (z+%i).*(z-%i)   1+2*z+z.^2</pre>";
115
116     my_exptext_string = my_exptext_string + "<div style=''text-align:justify; margin-top:5px; width:260;''>";
117     my_exptext_string = my_exptext_string + "2. define the type of the domain: Square or Disk,";
118     my_exptext_string = my_exptext_string + "</div>";
119
120
121     my_exptext_string = my_exptext_string + "<div style=''text-align:justify; margin-top:5px; width:260;''>";
122     my_exptext_string = my_exptext_string + "3. define the ""radius"" R of the domain,"+ "<br />";
123     my_exptext_string = my_exptext_string + "</div>";
124
125
126     my_exptext_string = my_exptext_string + "<div style=''text-align:justify; margin-top:5px; width:260;''>";
127     my_exptext_string = my_exptext_string + "4. should your function have some kind of ";
128     my_exptext_string = my_exptext_string + "discontinuity on Ox or Oy => check ";
129     my_exptext_string = my_exptext_string + "Ox or Oy. Otherwise check No.";
130     my_exptext_string = my_exptext_string + "</div>";
131
132     my_exptext_string = my_exptext_string + "</html>";
133
134
135     // Explanatory text : frame
136
137     b_f_expTxt = createBorderFont("", 12);
138     b_l_expTxt = createBorder("line", "navy", 1);
139     b_expTxt   = createBorder("titled", b_l_expTxt, "", "center", "top", b_f_expTxt, "navy");
140
141     // Border for the explanatory text frame
142     c = createConstraints("gridbag", [1 1 1 1], [1 1], "both", "upper");
143     my_exptext_frame = uicontrol( ...
144     "parent"              , control_frame,...
145     "style"               , "frame",...
146     "layout"              , "gridbag", ...
147     "border"              , b_expTxt, ...
148     "units"               , "pixels",...
149     "background"          , [1 1 1], ...
150     "constraint"          , c, ...
151     "tag"                 , "my_exptext_frame" ...
152     );
153
154     // Explanatory text : actual text
155
156     c = createConstraints("gridbag", [1 1 1 1], [1 1], "both", "upper");
157     my_exptext_box = uicontrol( ...
158     "parent"              , my_exptext_frame,...
159     "style"               , "text",...
160     "units"               , "pixels",...
161     "string"              , my_exptext_string,...
162     "fontname"            , defaultfont,...
163     "fontunits"           , "points",...
164     "fontsize"            , 9,...
165     "background"          , [1 1 1], ...
166     "constraint"          , c, ...
167     "tag"                 , "my_exptext_box" ...
168     );
169
170
171     // Function definition
172     // =========================================================================
173
174     // Function definition : frame
175
176     // Border for the function definition frame
177     b_f_funDef = createBorderFont("", 12);
178     b_l_funDef = createBorder("line", "navy", 1);
179     b_funDef   = createBorder("titled", b_l_funDef, _("Function definition"), "center", "top", b_f_funDef, "navy");
180
181     c = createConstraints("gridbag", [1 2 1 1], [1 1], "both", "upper");
182     my_fundef_frame = uicontrol( ...
183     "parent"              , control_frame,...
184     "style"               , "frame",...
185     "layout"              , "gridbag", ...
186     "border"              , b_funDef, ...
187     "units"               , "pixels",...
188     "fontname"            , defaultfont,...
189     "fontunits"           , "points",...
190     "fontsize"            , 13,...
191     "fontweight"          , "bold", ...
192     "background"          , [1 1 1], ...
193     "constraints"         , c, ...
194     "tag"                 , "my_fundef_frame" ...
195     );
196
197     // Function definition : Text "f(z) = "
198
199     c = createConstraints("gridbag", [1 1 1 1], [1/12 1], "both", "upper");
200     my_fundef_editbox = uicontrol( ...
201     "parent"             , my_fundef_frame,...
202     "style"              , "text",...
203     "string"              , "f(z) = ", ...
204     "fontname"           , defaultfont,...
205     "fontunits"          , "points",...
206     "fontsize"           , 11,...
207     "background"         , [1 1 1], ...
208     "constraint"         , c, ...
209     "tag"                , "my_fundef_editbox");
210
211     // Function definition : Edit box
212
213     c = createConstraints("gridbag", [2 1 1 1], [12 1], "both", "upper");
214     my_fundef_editbox = uicontrol( ...
215     "parent"             , my_fundef_frame,...
216     "style"              , "edit",...
217     "fontname"           , defaultfont,...
218     "fontunits"          , "points",...
219     "fontsize"           , 11,...
220     "string"             , "(1)./((z+2).*(2-z))", ...
221     "callback"           , "update_fundef()",...
222     "constraint"         , c, ...
223     "tag"                , "my_fundef_editbox");
224
225     // Function definition : message bar
226
227     c = createConstraints("gridbag", [1 2 2 1], [1 1], "both", "upper");
228     my_exptext_bar = uicontrol( ...
229     "parent"              , my_fundef_frame,...
230     "style"               , "text",...
231     "string"              , " ", ...
232     "units"               , "pixels",...
233     "fontname"            , defaultfont,...
234     "fontunits"           , "points",...
235     "fontsize"            , 11,...
236     "background"          , [1 1 1], ...
237     "constraint"          , c, ...
238     "tag"                 , "my_funDef_bar" ...
239     );
240
241
242     // Domain type
243     // =========================================================================
244
245     // Domain type : frame
246
247     // Border for the domain type frame
248     b_f_domain = createBorderFont("", 12);
249     b_l_domain = createBorder("line", "navy", 1);
250     b_domain   = createBorder("titled", b_l_domain, _("Domain type"), "center", "top", b_f_domain, "navy");
251
252     c = createConstraints("gridbag", [1 3 1 1], [1 1], "both", "upper");
253     my_dt_frame = uicontrol( ...
254     "parent"              , control_frame,...
255     "style"               , "frame",...
256     "layout"              , "gridbag", ...
257     "border"              , b_domain, ...
258     "units"               , "pixels",...
259     "fontname"            , defaultfont,...
260     "fontunits"           , "points",...
261     "fontsize"            , 13,...
262     "fontweight"          , "bold", ...
263     "background"          , [1 1 1], ...
264     "constraint"          , c, ...
265     "tag"                 , "my_dt_frame" ...
266     );
267
268     // Domain type : square
269
270     c = createConstraints("gridbag", [1 1 1 1], [1 1], "both", "upper");
271     square_radio = uicontrol( ...
272     "parent"             , my_dt_frame,...
273     "style"              , "radiobutton",...
274     "string"             , "Square",...
275     "fontname"           , defaultfont,...
276     "fontunits"          , "points",...
277     "fontsize"           , 11,...
278     "value"              , 0, ...
279     "background"         , [1 1 1], ...
280     "callback"           , "update_domain_type();",...
281     "constraints"        , c, ...
282     "tag"                , "square_radio");
283
284     // Domain type : Disk
285
286     c = createConstraints("gridbag", [2 1 1 1], [1 1], "both", "upper");
287     disk_radio = uicontrol( ...
288     "parent"             , my_dt_frame,...
289     "style"              , "radiobutton",...
290     "string"             , "Disk",...
291     "fontname"           , defaultfont,...
292     "fontunits"          , "points",...
293     "fontsize"           , 11,...
294     "value"              , 1, ...
295     "background"          , [1 1 1], ...
296     "callback"           , "update_domain_type();",...
297     "constraints"        , c, ...
298     "tag"                , "disk_radio");
299
300
301     // Radius of the domain
302     // =========================================================================
303
304     // Radius of the domain : frame
305
306     // Border for the radius frame
307     b_f_radius = createBorderFont("", 12);
308     b_l_radius = createBorder("line", "navy", 1);
309     b_radius   = createBorder("titled", b_l_radius, _("Radius of the domain"), "center", "top", b_f_radius, "navy");
310
311     c = createConstraints("gridbag", [1 4 1 1], [1 1], "both", "upper");
312     my_radius_frame = uicontrol( ...
313     "parent"              , control_frame,...
314     "style"               , "frame",...
315     "layout"              , "gridbag", ...
316     "border"              , b_radius, ...
317     "units"               , "pixels",...
318     "fontname"            , defaultfont,...
319     "fontunits"           , "points",...
320     "fontsize"            , 13,...
321     "fontweight"          , "bold", ...
322     "background"          , [1 1 1], ...
323     "constraint"          , c, ...
324     "tag"                 , "my_radius_frame" ...
325     );
326
327     // Radius of the domain : Edit box
328
329     c = createConstraints("gridbag", [1 1 1 1], [1 1], "both", "upper");
330     my_radius_editbox = uicontrol( ...
331     "parent"             , my_radius_frame,...
332     "style"              , "edit",...
333     "fontname"           , defaultfont,...
334     "fontunits"          , "points",...
335     "fontsize"           , 11,...
336     "string"             , "1.9", ...
337     "callback"           , "update_radius()",...
338     "constraint"         , c, ...
339     "tag"                , "my_radius_editbox");
340
341     // Radius of the domain : message bar
342
343     c = createConstraints("gridbag", [1 2 1 1], [1 1], "both", "upper");
344     my_exptext_bar = uicontrol( ...
345     "parent"              , my_radius_frame,...
346     "style"               , "text",...
347     "string"              , " ", ...
348     "units"               , "pixels",...
349     "fontname"            , defaultfont,...
350     "fontunits"           , "points",...
351     "fontsize"            , 11,...
352     "background"          , [1 1 1], ...
353     "constraint"          , c, ...
354     "tag"                 , "my_radius_bar" ...
355     );
356
357
358     // Cut on axes
359     // =========================================================================
360
361     // Cut on axes : frame
362
363     // Border for the cut on axes frame
364     b_f_cut = createBorderFont("", 12);
365     b_l_cut = createBorder("line", "navy", 1);
366     b_cut   = createBorder("titled", b_l_cut, _("Cut on axes"), "center", "top", b_f_cut, "navy");
367
368     c = createConstraints("gridbag", [1 5 1 1], [1 1], "both", "upper");
369     my_coa_frame = uicontrol( ...
370     "parent"              , control_frame,...
371     "style"               , "frame",...
372     "layout"              , "gridbag", ...
373     "border"              , b_cut, ...
374     "units"               , "pixels",...
375     "fontname"            , defaultfont,...
376     "fontunits"           , "points",...
377     "fontsize"            , 13,...
378     "fontweight"          , "bold", ...
379     "background"          , [1 1 1], ...
380     "constraint"          , c, ...
381     "tag"                 , "my_coa_frame" ...
382     );
383
384     // Cut on axes : Ox
385
386     c = createConstraints("gridbag", [1 1 1 1], [1 1], "both", "upper");
387     ox_radio = uicontrol( ...
388     "parent"             , my_coa_frame,...
389     "style"              , "radiobutton",...
390     "string"             , "Ox",...
391     "fontname"           , defaultfont,...
392     "fontunits"          , "points",...
393     "fontsize"           , 11,...
394     "value"              , 0, ...
395     "background"         , [1 1 1], ...
396     "callback"           , "update_cao();",...
397     "constraint"         , c, ...
398     "tag"                , "ox_radio");
399
400     // Cut on axes : Oy
401
402     c = createConstraints("gridbag", [2 1 1 1], [1 1], "both", "upper");
403     oy_radio = uicontrol( ...
404     "parent"             , my_coa_frame,...
405     "style"              , "radiobutton",...
406     "string"             , "Oy",...
407     "fontname"           , defaultfont,...
408     "fontunits"          , "points",...
409     "fontsize"           , 11,...
410     "value"              , 0, ...
411     "background"         , [1 1 1], ...
412     "callback"           , "update_cao();",...
413     "constraint"          , c, ...
414     "tag"                , "oy_radio");
415
416     // Cut on axes : No
417
418     c = createConstraints("gridbag", [3 1 1 1], [1 1], "both", "upper");
419     no_radio = uicontrol( ...
420     "parent"             , my_coa_frame,...
421     "style"              , "radiobutton",...
422     "string"             , "No",...
423     "fontname"           , defaultfont,...
424     "fontunits"          , "points",...
425     "fontsize"           , 11,...
426     "value"              , 1, ...
427     "background"         , [1 1 1], ...
428     "callback"           , "update_cao();",...
429     "constraint"          , c, ...
430     "tag"                , "no_radio");
431
432     // Default Values
433     // =========================================================================
434
435     global my_fundef_val;
436     global my_dt_val;
437     global my_radius;
438     global my_typeCut;
439     global my_e;
440
441
442     my_fundef_val = "(1)./((z+2).*(2-z))";
443     my_dt_val     = "Disk";
444     my_radius     = 1.9;
445     my_typeCut    = "No";
446
447     my_e          = 0.001;
448     theta         = -110;
449     alpha         = 75;
450
451     deff("Z=f(z)","Z="+my_fundef_val);
452
453     PlotCmplxFunc(my_radius,my_e,my_dt_val,my_typeCut,[40 20],"f",theta,alpha,[0;0]);
454     fig_handle.visible = "on";
455
456 endfunction
457
458 function update_fundef()
459
460     global my_fundef_val;
461     global my_dt_val;
462     global my_radius;
463     global my_typeCut;
464     global my_e;
465
466     my_fundef_val_tmp = get(gcbo,"string");
467
468     if strchr(my_fundef_val_tmp, "z") == "" then
469         updateStatusBar("my_funDef_bar", _("Function should contain ""z"""), [1 0 0]);
470         return
471     end
472
473     try // Try f(z) on a simple matrix
474         ieeeMode = ieee();
475         ieee(2);
476         execstr(strsubst(my_fundef_val_tmp, "z", "[1 2 3; 1 2 3]"));
477         ieee(ieeeMode);
478     catch
479         updateStatusBar("my_funDef_bar", _("Wrong definition of f(z)"), [1 0 0]);
480         return
481     end
482
483     my_fundef_val = my_fundef_val_tmp;
484
485     // Delete the old plots
486
487     demo_fig = gcf();
488     demo_fig.immediate_drawing = "off";
489
490     a = gca(); delete(a);
491     a = gca(); delete(a);
492     a = gca(); delete(a);
493
494     theta = -110;
495     alpha = 75;
496
497     deff("Z=f(z)","Z="+my_fundef_val);
498
499     if my_dt_val == "Square" then
500         PlotCmplxFunc(my_radius,my_e,my_dt_val,my_typeCut,41,"f",theta,alpha,[0;0]);
501     elseif my_dt_val == "Disk" then
502         PlotCmplxFunc(my_radius,my_e,my_dt_val,my_typeCut,[40 20],"f",theta,alpha,[0;0]);
503     end
504
505     demo_fig.immediate_drawing = "on";
506
507 endfunction
508
509 function update_domain_type()
510
511     global my_fundef_val;
512     global my_dt_val;
513     global my_radius;
514     global my_typeCut;
515     global my_e;
516
517     // Update the radio elements
518     set(findobj("tag", "square_radio") , "value", 0);
519     set(findobj("tag", "disk_radio")   , "value", 0);
520     set(gcbo, "value", 1);
521
522     // Delete the old plots
523
524     demo_fig = gcf();
525     demo_fig.immediate_drawing = "off";
526
527     a = gca(); delete(a);
528     a = gca(); delete(a);
529     a = gca(); delete(a);
530
531     theta = -110;
532     alpha = 75;
533
534     deff("Z=f(z)","Z="+my_fundef_val);
535
536     if get(gcbo, "tag") == "square_radio" then
537         my_dt_val = "Square";
538     elseif get(gcbo, "tag") == "disk_radio" then
539         my_dt_val = "Disk";
540     end
541
542     if my_dt_val == "Square" then
543         PlotCmplxFunc(my_radius,my_e,my_dt_val,my_typeCut,41,"f",theta,alpha,[0;0]);
544     elseif my_dt_val == "Disk" then
545         PlotCmplxFunc(my_radius,my_e,my_dt_val,my_typeCut,[40 20],"f",theta,alpha,[0;0]);
546     end
547
548     demo_fig.immediate_drawing = "on";
549
550 endfunction
551
552 function update_radius()
553
554     global my_fundef_val;
555     global my_dt_val;
556     global my_radius;
557     global my_typeCut;
558     global my_e;
559
560     try
561         my_radius_tmp = evstr(get(gcbo,"string"));
562     catch
563         updateStatusBar("my_radius_bar", _("Radius should be real and finite"), [1 0 0]);
564         return
565     end
566
567     if ~isscalar(my_radius_tmp) | and(type(my_radius_tmp) <> [1 8]) | ~isreal(my_radius_tmp) | isinf(my_radius_tmp) then
568         updateStatusBar(_("Radius should be real and finite"), [1 0 0]);
569         return
570     else
571         my_radius = my_radius_tmp;
572     end
573
574     // Delete the old plots
575
576     demo_fig = gcf();
577     demo_fig.immediate_drawing = "off";
578
579     a = gca(); delete(a);
580     a = gca(); delete(a);
581     a = gca(); delete(a);
582
583     theta = -110;
584     alpha = 75;
585
586     deff("Z=f(z)","Z="+my_fundef_val);
587
588     if my_dt_val == "Square" then
589         PlotCmplxFunc(my_radius,my_e,my_dt_val,my_typeCut,41,"f",theta,alpha,[0;0]);
590     elseif my_dt_val == "Disk" then
591         PlotCmplxFunc(my_radius,my_e,my_dt_val,my_typeCut,[40 20],"f",theta,alpha,[0;0]);
592     end
593
594     demo_fig.immediate_drawing = "on";
595
596 endfunction
597
598 function update_cao()
599
600     global my_fundef_val;
601     global my_dt_val;
602     global my_radius;
603     global my_typeCut;
604     global my_e;
605
606     // Update the radio elements
607     set(findobj("tag", "ox_radio") , "value", 0);
608     set(findobj("tag", "oy_radio") , "value", 0);
609     set(findobj("tag", "no_radio") , "value", 0);
610     set(gcbo, "value", 1);
611
612     // Delete the old plots
613
614     demo_fig = gcf();
615     demo_fig.immediate_drawing = "off";
616
617     a = gca(); delete(a);
618     a = gca(); delete(a);
619     a = gca(); delete(a);
620
621     theta = -110;
622     alpha = 75;
623
624     deff("Z=f(z)","Z="+my_fundef_val);
625
626     if get(gcbo, "tag")     == "ox_radio" then
627         my_typeCut = "Ox";
628     elseif get(gcbo, "tag") == "oy_radio" then
629         my_typeCut = "Oy";
630     elseif get(gcbo, "tag") == "no_radio" then
631         my_typeCut = "No";
632     end
633
634     if my_dt_val == "Square" then
635         PlotCmplxFunc(my_radius,my_e,my_dt_val,my_typeCut,41,"f",theta,alpha,[0;0]);
636     elseif my_dt_val == "Disk" then
637         PlotCmplxFunc(my_radius,my_e,my_dt_val,my_typeCut,[40 20],"f",theta,alpha,[0;0]);
638     end
639
640     demo_fig.immediate_drawing = "on";
641
642 endfunction
643
644 function []=PlotCmplxFunc(R,e,TypeDomain,TypeCut,n,StrFunc,theta,alpha,DomReal)
645
646     //  A function to draw on a square or a disk a complex function
647     //  with branch(es) cut(s) on Ox or Oy
648     //
649     //  TypeDomain : "Square" or "Disk"
650     //     TypeCut : "Ox" or "Oy"
651     //           R : length of half a side of the square or radius of the disk
652     //           e : thin layer to avoid the branch(es) cut(s)
653     //           n : a scalar (for Square) or a 2-vector = [ntheta, nr]
654     //               (for Disk) for discretization
655     //     StrFunc : the string which names the complex function (this is
656     //               because primitive don't pass as function argument)
657     // theta,alpha : usual parameters for plot3d
658     //     DomReal : interval for which the real restriction is drawn
659
660     // computes the facets
661
662     [xr,yr,zr,xi,yi,zi] = CmplxFacets(R,e,TypeDomain,TypeCut,n,StrFunc);
663
664     // draw
665     // ============================================
666
667     // Title
668     // ============================================
669
670     my_title_axes             = newaxes();
671     my_title_axes.axes_bounds = [1/3,0,2/3,1];
672
673     // make axes transparent
674     my_title_axes.filled = "off";
675
676     Rs = string(R);
677
678     if TypeDomain == "Square" then
679         end_title = " function on [-"+Rs+","+Rs+"]x[-"+Rs+","+Rs+"]"
680     else
681         end_title = " function on D(0,R="+Rs+")"
682     end
683
684     if StrFunc == "f" then
685         the_title = "Your custom (named f) complex" + end_title;
686     else
687         the_title = "The complex " + StrFunc + end_title;
688     end
689
690     xtitle(the_title);
691
692     my_title_axes.title.text       = the_title;
693     my_title_axes.title.font_size  = 3;
694     my_title_axes.margins     = [ 0.15 0.08 0.08 0.08 ]
695
696     // plot Im(z)
697     // ============================================
698
699     subplot(211)
700     plot3d(xi,yi,zi,theta,alpha,"Re(z)@Im(z)@",[2 6 4]);
701
702     my_IM_axes = gca();
703     my_IM_axes.axes_bounds = [0.16, 0.05, 1, 0.5];
704     my_IM_plot             = my_IM_axes.children;
705     my_IM_plot.color_flag  = 1;
706
707     xtitle("Im("+StrFunc+"(z))");
708     my_IM_axes.margins      = [0.2, 0.2, 0.2, 0.2];
709     my_IM_axes.cube_scaling = "on";
710
711     // plot Re(z) + the real restriction
712     // ============================================
713
714     subplot(212)
715     plot3d(xr,yr,zr,theta,alpha,"Re(z)@Im(z)@",[2 6 4]);
716
717     my_RE_axes = gca();
718     my_RE_axes.axes_bounds = [0.16, 0.5, 1, 0.5];
719     my_RE_plot             = my_RE_axes.children;
720     my_RE_plot.color_flag  = 1;
721
722     xtitle("Re("+StrFunc+"(z))");
723     my_RE_axes.margins      = [0.2, 0.2, 0.2, 0.2];
724     my_RE_axes.cube_scaling = "on";
725
726     // real function in yellow
727     // ============================================
728
729     if DomReal(2) > DomReal(1) then
730         xstring(0.1,-0.15," In yellow : the real "+StrFunc+" function")
731     end
732
733     if DomReal(2) > DomReal(1) then
734         xx = linspace(DomReal(1),DomReal(2),40)';
735         yy = zeros(xx);
736         zz = evstr(StrFunc+"(xx)");
737         param3d1(xx,yy,list(zz,32),theta,alpha,flag=[0,0]);
738         yellow_line = get("hdl");
739         yellow_line.thickness = 3;
740     end
741
742 endfunction
743
744 function [xr,yr,zr,xi,yi,zi] = CmplxFacets(R,e,TypeDomain,TypeCut,n,StrFunc)
745
746     //  A function to compute the facets for drawing a complex function
747     //  on a square or a disk with branch(es) cut(s) on Ox or Oy
748     //
749     //  TypeDomain : "Square" or "Disk"
750     //     TypeCut : "Ox" or "Oy"
751     //           R : length of half a side of the square or radius of the disk
752     //           e : thin layer to avoid the branch(es) cut(s)
753     //           n : a scalar (for Square) or a 2-vector = [ntheta, nr]
754     //               (for Disk) for discretization
755     //     StrFunc : the string which names the complex function (this is
756     //               because primitive don't pass as function argument)
757
758     if TypeDomain == "Square" then
759         if TypeCut == "Ox" then
760             x1 = linspace(-R, R, n);
761             y1 = linspace( e, R, int(n/2));
762         else  // for TypeCut = "Oy" ...
763             x1 = linspace( e, R, int(n/2));
764             y1 = linspace(-R, R, n);
765         end
766         X1 = ones(y1')*x1 ; Y1 = y1'*ones(x1);
767
768     else // for TypeDomain = "Disk"
769         r = linspace(0,R, n(2));
770         if TypeCut == "Ox" then
771             theta = linspace(0,%pi,n(1))';
772             X1 = cos(theta)*r;
773             Y1 = e + sin(theta)*r;
774         else // for TypeCut = "Oy"
775             theta = linspace(-%pi/2,%pi/2,n(1))';
776             X1 = e + cos(theta)*r;
777             Y1 = sin(theta)*r;
778         end
779     end
780
781     X2 = -X1 ; Y2 = -Y1;
782     Z1 = evstr(StrFunc+"(X1 + %i*Y1)");
783     Z2 = evstr(StrFunc+"(X2 + %i*Y2)");
784     [xr1,yr1,zr1] = nf3d(X1,Y1,real(Z1));
785     [xr2,yr2,zr2] = nf3d(X2,Y2,real(Z2));
786     xr = [xr1 xr2]; yr = [yr1 yr2]; zr = [zr1 zr2];
787     [xi1,yi1,zi1] = nf3d(X1,Y1,imag(Z1));
788     [xi2,yi2,zi2] = nf3d(X2,Y2,imag(Z2));
789     xi = [xi1 xi2]; yi = [yi1 yi2]; zi = [zi1 zi2];
790
791 endfunction
792
793 // =============================================================================
794 // updateStatusBar
795 // + Update the string in the text frame
796 // =============================================================================
797 function updateStatusBar(tag,msg, msg_color)
798     time_active = 2; //Time the message is active in s
799
800     if argn(2) == 0 then
801         set(tag, "String", " ");
802         return
803     end
804
805     h = gcf();
806     set(tag, "Foregroundcolor", msg_color, "String", msg);
807
808     delta_time = 0;
809     timer()
810     while delta_time < time_active
811         delta_time = delta_time + timer();
812     end
813
814     if is_handle_valid(h)
815         updateStatusBar();
816     end
817 endfunction
818
819 funcprot(prot);
820
821 demo_custom();
822
823 clear demo_custom();