* Bug 16292 fixed: hallchart() debugged & improved 06/21206/4
Samuel GOUGEON [Sat, 4 Jan 2020 22:19:45 +0000 (23:19 +0100)]
  http://bugzilla.scilab.org/16292

  hallchart page updated (PDF): http://bugzilla.scilab.org/attachment.cgi?id=5050

Change-Id: Ifb9edde7b430df6c3b0a34d086b01666c56af41b

20 files changed:
scilab/CHANGES.md
scilab/modules/cacsd/help/en_US/linear_analysis/freq_domain/hallchart.xml
scilab/modules/cacsd/help/ja_JP/linear_analysis/freq_domain/hallchart.xml [deleted file]
scilab/modules/cacsd/macros/hallchart.sci
scilab/modules/helptools/etc/images_md5.txt
scilab/modules/helptools/images/hallchart_en_US_1.png
scilab/modules/helptools/images/hallchart_en_US_2.png
scilab/modules/helptools/images/hallchart_en_US_3.png
scilab/modules/helptools/images/hallchart_fr_FR_1.png
scilab/modules/helptools/images/hallchart_fr_FR_2.png
scilab/modules/helptools/images/hallchart_fr_FR_3.png
scilab/modules/helptools/images/hallchart_ja_JP_1.png
scilab/modules/helptools/images/hallchart_ja_JP_2.png
scilab/modules/helptools/images/hallchart_ja_JP_3.png
scilab/modules/helptools/images/hallchart_pt_BR_1.png
scilab/modules/helptools/images/hallchart_pt_BR_2.png
scilab/modules/helptools/images/hallchart_pt_BR_3.png
scilab/modules/helptools/images/hallchart_ru_RU_1.png
scilab/modules/helptools/images/hallchart_ru_RU_2.png
scilab/modules/helptools/images/hallchart_ru_RU_3.png

index 7f2600a..2ed67c9 100644 (file)
@@ -116,6 +116,7 @@ Feature changes and additions
   - When there is no solution, [] is returned.
   - When there is an infinite number of solutions, the err flag has a specific value.
   - The output size gets the input's one.
+<<<<<<< HEAD
 * `csvRead` and `csvTextScan` are now implemented without extra copies.
 * `editvar()` GUI support copy-paste of strings removing quotes.
 * calendar() can now display formated calendars.
@@ -129,6 +130,13 @@ Feature changes and additions
   - `riccati(H)` and `riccati(H,E)` syntaxes added, to describe the Riccati equation through its Hamiltonian H or (E,H) pencil.
   - The residual is returned as new 3rd output argument.
   - When no solution is found, `X=[]` | `X1=[]` is returned instead of yielding an error.
+=======
+* `hallchart()` is upgraded:
+  - The default set of modules is set automatically, according to data bounds.
+  - Handles of the grids and labels are returned. Post-processing them become easy.
+  - Named colors accepted ; better default colors.
+  - Improved placement of labels.
+>>>>>>> 839d040c90b... * Bug 16292 fixed: hallchart() debugged & improved
 
 
 Help pages:
@@ -307,6 +315,7 @@ Bug Fixes
 * [#16273](http://bugzilla.scilab.org/show_bug.cgi?id=16273): `calendar()` had no formated display mode.
 * [#16275](http://bugzilla.scilab.org/show_bug.cgi?id=16275): `fsolve(x0, fun, tol)` no longer took `tol` into account.
 * [#16290](http://bugzilla.scilab.org/show_bug.cgi?id=16290): The `cn`, `dn`, `ns`, `nc` and `nd` Jacobi elliptic functions were not available.
+* [#16292](http://bugzilla.scilab.org/show_bug.cgi?id=16292): `hallchart()` had bugs and a poor rendering.
 * [#16293](http://bugzilla.scilab.org/show_bug.cgi?id=16293): Some demos run in step-by-step console mode(4) did not focus user's attention to the console to proceed.
 * [#16299](http://bugzilla.scilab.org/show_bug.cgi?id=16299): After `graypolarplot()`, `colorbar()` displayed an empty ungraduated color bar.
 * [#16303](http://bugzilla.scilab.org/show_bug.cgi?id=16303): log10(x) had wrong dimensions when x is an hypermatrix.
index 77e055b..7ff49d1 100644 (file)
@@ -2,8 +2,8 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) INRIA
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2020 - Samuel GOUGEON
  *
  * This file is hereby licensed under the terms of the GNU GPL v2.0,
  * pursuant to article 5.3.4 of the CeCILL v.2.1.
  * along with this program.
  *
  -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook"  xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="hallchart">
+<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
+          xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML"
+          xmlns:db="http://docbook.org/ns/docbook"  xmlns:scilab="http://www.scilab.org"
+          xml:lang="en" xml:id="hallchart">
     <refnamediv>
         <refname>hallchart</refname>
-        <refpurpose>Draws the Hall chart</refpurpose>
+        <refpurpose>Draws a Hall chart</refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Syntax</title>
-        <synopsis>hallchart([ modules [,args [,colors]]])</synopsis>
+        <synopsis>
+            sh = hallchart(modules)
+            sh = hallchart(modules, args)
+            sh = hallchart(modules, args, colors)
+        </synopsis>
     </refsynopsisdiv>
     <refsection role="parameters">
         <title>Arguments</title>
             <varlistentry>
                 <term>modules</term>
                 <listitem>
-                    <para>real vector ( modules (in dB))</para>
+                    vector of real numbers: modules (in dB). Default values are computed
+                    according to the data bounds, whose default are [-4,3] for the Real axis
+                    and [-3 3] for the Imaginary one.
+                    <para/>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>args</term>
                 <listitem>
-                    <para>real vector (phases (in degree))</para>
+                    vector of real numbers: phases (in degree). Default values:
+                    <para/>
+                    <literal>[-90 -60 -40 -30 -25 -20 -15 -12 12 15 20 25 30 40 60 90]°</literal>
+                    <para/>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>colors</term>
                 <listitem>
-                    <para>a scalar or a vector, the color indices for isogain and iso phase curves</para>
+                    vector of 1 or 2 components specifying the colors of the isogain and isophase
+                    sets of curves. To choose the color for only one grid, set the other one to ""
+                    or 0. If a single color is provided, it is used for both gains and phases.
+                    <varname>colors</varname> may be specified either
+                    <itemizedlist>
+                        <listitem>
+                            by indices in the color map.
+                        </listitem>
+                        <listitem>
+                            named colors among the <link linkend="color_list">predefined ones</link>.
+                        </listitem>
+                        <listitem>
+                            "#RRGGBB" hexadecimal case-insensitive strings starting with "#",
+                            like "#FA7B35".
+                        </listitem>
+                        <listitem>
+                            A 1x3 or 2x3 matrix of [r g b] intensities such that 0 &lt;= r,g,b &lt;= 1.
+                        </listitem>
+                    </itemizedlist>
+                    <para/>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>sh</term>
+                <listitem>
+                    Structure with 4 fields:
+                    <itemizedlist>
+                        <listitem>
+                            <literal>.phaseLines</literal>: vector of handles of isophase lines.
+                            <literal>.phaseLines(i)</literal> is the line for
+                            <literal>args(i)</literal>.
+                        </listitem>
+                        <listitem>
+                            <literal>.phaseLabels</literal>: vector of handles of isophase labels.
+                            <literal>.phaseLabels(i)</literal> is the label for
+                            <literal>args(i)</literal>.
+                        </listitem>
+                        <listitem>
+                            <literal>.gainLines</literal>: vector of handles of isogain lines.
+                            <literal>.gainLines(i)</literal> is the line for
+                            <literal>modules(i)</literal>.
+                        </listitem>
+                        <listitem>
+                            <literal>.gainLabels</literal>: vector of handles of isogain labels.
+                            <literal>.gainLabels(i)</literal> is the label for
+                            <literal>modules(i)</literal>.
+                        </listitem>
+                    </itemizedlist>
+                    <para/>
                 </listitem>
             </varlistentry>
         </variablelist>
     </refsection>
     <refsection role="description">
         <title>Description</title>
-        <para> plot the Hall'chart: iso-module and iso-argument contours of
-            <literal>y/(1+y)</literal> in the <literal>real(y)</literal>, <literal>imag(y)</literal> plane
+        <para>
+            plots the Hall's chart: iso-module and iso-argument contours of
+            <literal>y/(1+y)</literal> in the <literal>real(y)</literal>,
+            <literal>imag(y)</literal> plane
         </para>
         <para>
             <literal>hallchart</literal> may be used in conjunction with
             <link linkend="nyquist">nyquist</link>.
         </para>
+        <note>
+            Datatips on isogain and isophase curves are customized.
+        </note>
+    </refsection>
+    <refsection role="examples">
+        <title>Examples</title>
         <para>
-            The default values for <literal>modules</literal> and
-            <literal>args</literal> are respectively :
-        </para>
-        <para>
-            <literal>[-20 -10 -6 -4 -2 2 4 6 10 20]</literal>
-        </para>
-        <para>
-            <literal>[-90 -60 -45 -30 -15 15 30 45 60 90]</literal>
+            <emphasis role="bold">Charts in an empty default or empty preset axes:</emphasis> Note that default Hall chart titles are then set:
         </para>
-    </refsection>
-    <refsection>
-        <title>Graphics entities organization</title>
+        <programlisting role="example"><![CDATA[
+clf
+// In a default axes
+subplot(1,2,1)
+hallchart();
+
+// In a preset empty axes
+subplot(1,2,2)
+plotframe([-4 -2 1 4]) // xmin ymin ymax ymax
+hallchart();
+    ]]></programlisting>
+        <scilab:image localized="true">
+        clf
+        // In a default axes
+        subplot(1,2,1)
+        hallchart();
+
+        // In a preset empty axes
+        subplot(1,2,2)
+        plotframe([-4 -2 1 4])
+        hallchart();
+        gcf().axes_size = [800 450];
+        </scilab:image>
         <para>
-            The <literal>hallchart</literal> function create a single
-            compound object which is generally the last child of the current
-            axes. This compound object contains a set of compound objects, one
-            for each grid curve. The first ones are the iso module curves and
-            the last one the iso-argument contours. Each of these compound
-            objects contains a Polyline object (the curve) and a Text object
-            (the label). The following piece of code can be used to change the color of the ith iso module curve:
+            <emphasis role="bold">Customizing some elements</emphasis> of the grids and labels:
         </para>
-        <programlisting role="customizing"><![CDATA[
-    clf();hallchart()
-    ax=gca();//handle on current axes
-    c=ax.children($).children;// the handles on the chart grid curves
-    i=4; //the index of the -4dB curve
-    ci=c(i); //the handle on the -4dB curve
-    ci.children(1).foreground=color('red'); //draw it in red
+        <programlisting role="example"><![CDATA[
+clf
+h = hallchart();
 
-    j=3; // the index of the -45° curve
-    cj=c(10+j); //the handle on the -45° curve
-    cj.children(1).thickness=3;//draw it thicker
+// 5dB isogain
+i = find(h.gainLabels.text=="5dB");
+    // Customizing the label
+set(h.gainLabels(i),"box","on","font_size",2,"font_foreground",color("red"));
+    // Customizing the line
+h.gainLines(i).thickness = 3;
+
+// +/-25° isophases
+i = grep(h.phaseLabels.text,"25°")
+    // Customizing the labels
+set(h.phaseLabels(i),"font_size",3,"font_foreground",color("blue"));
+    // Customizing the lines
+set(h.phaseLines(i), "thickness",2,"line_style",1);
      ]]></programlisting>
         <scilab:image localized="true">
-            clf();hallchart()
-            ax=gca();
-            c=ax.children($).children;
-            i=4;
-            ci=c(i);
-            ci.children(1).foreground=color('red');
-            j=3;
-            cj=c(10+j);
-            cj.children(1).thickness=3;
+            clf
+            h = hallchart();
+
+            // 5dB isogain
+            i = find(h.gainLabels.text=="5dB");
+                // Customizing the label
+            set(h.gainLabels(i),"box","on","font_size",2,"font_foreground",color("red"));
+                // Customizing the line
+            h.gainLines(i).thickness = 3;
+
+            // +/-25° isophases
+            i = grep(h.phaseLabels.text,"25°")
+                // Customizing the labels
+            set(h.phaseLabels(i),"font_size",3,"font_foreground",color("blue"));
+                // Customizing the line
+            set(h.phaseLines(i), "thickness",2,"line_style",1);
         </scilab:image>
-    </refsection>
-    <refsection role="examples">
-        <title>Examples</title>
-        <programlisting role="example"><![CDATA[
-    //Hall chart
-    clf();hallchart()
-    ]]></programlisting>
         <para>
-            <scilab:image localized="true">
-                hallchart()
-            </scilab:image>
+            <emphasis role="bold">Background of a Nyquist diagram</emphasis>
+            <para/>
+            Note that pre-existing titles are kept.
         </para>
+        <para>
         <programlisting role="example"><![CDATA[
-    //Hall chart as a grid for nyquist
-    s=poly(0,'s');
-    Plant=syslin('c',16000/((s+1)*(s+10)*(s+100)));
-    //two degree of freedom PID
-    tau=0.2;xsi=1.2;
-    PID=syslin('c',(1/(2*xsi*tau*s))*(1+2*xsi*tau*s+tau^2*s^2));
-    clf();
-    nyquist([Plant;Plant*PID],0.5,100,["Plant";"Plant and PID corrector"]);
-    hallchart(colors=color('light gray')*[1 1])
-    //move the caption in the lower right corner
-    ax=gca();Leg=ax.children(1);
-    Leg.legend_location="in_lower_right";
+s = %s;
+Plant = syslin('c', 16000/((s+1)*(s+10)*(s+100)));
+//two degree of freedom PID
+[tau, xsi] = (0.2, 1.2);
+PID = syslin('c',(1/(2*xsi*tau*s))*(1+2*xsi*tau*s+tau^2*s^2));
+
+clf
+nyquist([Plant;Plant*PID], 0.5, 100, ["Plant";"Plant and PID corrector"]);
+mod = [12 6 3 2 1 0.5 0.2 0.1 -6 -3 -2 -1 -0.5 -0.2 -0.1];
+hallchart(mod,, ["goldenrod1" ""]);
+// Move the caption to avoid hiding data
+Leg = gca().children(1);
+set(Leg,"legend_location","by_coordinates","position",[0.15 0.4]);
     ]]></programlisting>
-        <para>
-            <scilab:image localized="true">
-                s=poly(0,'s');
-                Plant=syslin('c',16000/((s+1)*(s+10)*(s+100)));
-                tau=0.2;xsi=1.2;
-                PID=syslin('c',(1/(2*xsi*tau*s))*(1+2*xsi*tau*s+tau^2*s^2));
-                nyquist([Plant;Plant*PID],0.5,100,["Plant";"Plant and PID corrector"]);
-                hallchart(colors=color('light gray')*[1 1])
-                ax=gca();Leg=ax.children(1);
-                Leg.legend_location="in_lower_right";
-            </scilab:image>
+        <scilab:image localized="true">
+        s = %s;
+        Plant = syslin('c', 16000/((s+1)*(s+10)*(s+100)));
+        //two degree of freedom PID
+        [tau, xsi] = (0.2, 1.2);
+        PID = syslin('c',(1/(2*xsi*tau*s))*(1+2*xsi*tau*s+tau^2*s^2));
+
+        clf
+        nyquist([Plant;Plant*PID], 0.5, 100, ["Plant";"Plant and PID corrector"]);
+        mod = [12 6 3 2 1 0.5 0.2 0.1 -6 -3 -2 -1 -0.5 -0.2 -0.1];
+        hallchart(mod,, ["goldenrod1" ""]);
+        // Move the caption to avoid hiding data
+        Leg = gca().children(1);
+        set(Leg,"legend_location","by_coordinates","position",[0.15 0.4]);
+        </scilab:image>
         </para>
     </refsection>
     <refsection role="see also">
         <title>See also</title>
         <simplelist type="inline">
             <member>
+                <link linkend="nicholschart">nicholschart</link>
+            </member>
+            <member>
                 <link linkend="nyquist">nyquist</link>
             </member>
             <member>
-                <link linkend="nicholschart">nicholschart</link>
+                <link linkend="black">black</link>
+            </member>
+            <member>
+                <link linkend="color_list">color_list</link>
             </member>
         </simplelist>
     </refsection>
+    <refsection>
+        <title>History</title>
+        <revhistory>
+            <revision>
+                <revnumber>6.1.0</revnumber>
+                <revremark>
+                    <itemizedlist>
+                        <listitem>
+                            The default values for the modules are computed according to the data bounds.
+                        </listitem>
+                        <listitem>
+                            The frames colors can be specified by their Scilab name or
+                            their "#RRGGBB" hexadecimal code. "" or 0 can be used as partial default.
+                        </listitem>
+                        <listitem>
+                            Output argument <literal>sh</literal> added.
+                        </listitem>
+                    </itemizedlist>
+                </revremark>
+            </revision>
+        </revhistory>
+    </refsection>
 </refentry>
diff --git a/scilab/modules/cacsd/help/ja_JP/linear_analysis/freq_domain/hallchart.xml b/scilab/modules/cacsd/help/ja_JP/linear_analysis/freq_domain/hallchart.xml
deleted file mode 100644 (file)
index 55d9da1..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) INRIA
- *
- * Copyright (C) 2012 - 2016 - Scilab Enterprises
- *
- * This file is hereby licensed under the terms of the GNU GPL v2.0,
- * pursuant to article 5.3.4 of the CeCILL v.2.1.
- * This file was originally licensed under the terms of the CeCILL v2.1,
- * and continues to be available under such terms.
- * For more information, see the COPYING file which you should have received
- * along with this program.
- *
- -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org"  xml:lang="ja" xml:id="hallchart">
-    <refnamediv>
-        <refname>hallchart</refname>
-        <refpurpose>ホール図を描画</refpurpose>
-    </refnamediv>
-    <refsynopsisdiv>
-        <title>呼び出し手順</title>
-        <synopsis>hallchart([ modules [,args [,colors]]])</synopsis>
-    </refsynopsisdiv>
-    <refsection role="parameters">
-        <title>パラメータ</title>
-        <variablelist>
-            <varlistentry>
-                <term>modules</term>
-                <listitem>
-                    <para>実数ベクトル (モジュール (単位: dB))</para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>args</term>
-                <listitem>
-                    <para>実数ベクトル (位相 (単位:度))</para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>colors</term>
-                <listitem>
-                    <para>スカラーまたはベクトル, 等ゲインおよび等位相曲線の色インデックス</para>
-                </listitem>
-            </varlistentry>
-        </variablelist>
-    </refsection>
-    <refsection role="description">
-        <title>説明</title>
-        <para>
-            ホール図をプロット: <literal>real(y)</literal>, <literal>imag(y)</literal> 平面における
-            <literal>y/(1+y)</literal> の等モジュールおよび等引数等高線
-        </para>
-        <para>
-            <literal>hallchart</literal> は
-            <link linkend="nyquist">nyquist</link>と組み合わせて使用することができます.
-        </para>
-        <para>
-            <literal>modules</literal>および<literal>args</literal>のデフォルト値は
-            それぞれ次のようになります :
-        </para>
-        <para>
-            <literal>[-20 -10 -6 -4 -2 2 4 6 10 20]</literal>
-        </para>
-        <para>
-            <literal>[-90 -60 -45 -30 -15 15 30 45 60 90]</literal>
-        </para>
-    </refsection>
-    <refsection>
-        <title>グラフィックエンティティの構成</title>
-        <para>
-            <literal>hallchart</literal>関数は通常カレントの軸の最後の子である
-            Compoundオブジェクトを1つ作成します.
-            このCompoundオブジェクトには各グリッド曲線に一つずつの
-            compoundオブジェクトの集合が含まれます.
-            最初のオブジェクトは,等モジュール曲線,最後のオブジェクトは
-            等引数等高線となります.
-            これらのcompoundオブジェクトの各々には,
-            ポリラインオブジェクト(曲線)とテキストオブジェクト(ラベル)が含まれます.
-            以下のコードをi番目の等モジュール曲線の色を変更する際に使用することができます:
-        </para>
-        <programlisting role="customizing"><![CDATA[
-    clf();hallchart()
-    ax=gca();//カレントの軸のハンドル
-    c=ax.children($).children;// chartグリッド曲線のハンドル
-    i=4; //-4dB曲線のインデックス
-    ci=c(i); //-4dB曲線のハンドル
-    ci.children(1).foreground=color('red'); //赤で描く
-    j=3; // the index of the -45°曲線のインデックス
-    cj=c(10+j); // -45° 曲線のハンドル
-    cj.children(1).thickness=3;//線幅を太くする
-     ]]></programlisting>
-        <scilab:image localized="true">
-            clf();hallchart()
-            ax=gca();
-            c=ax.children($).children;
-            i=4;
-            ci=c(i);
-            ci.children(1).foreground=color('red');
-            j=3;
-            cj=c(10+j);
-            cj.children(1).thickness=3;
-        </scilab:image>
-    </refsection>
-    <refsection role="examples">
-        <title>例</title>
-        <programlisting role="example"><![CDATA[
-    //ホール図
-    clf();hallchart()
-    ]]></programlisting>
-        <para>
-            <scilab:image localized="true">
-                hallchart()
-            </scilab:image>
-        </para>
-        <programlisting role="example"><![CDATA[
-    //ナイキストのグリッドとしてホール図を作成
-    s=poly(0,'s');
-    Plant=syslin('c',16000/((s+1)*(s+10)*(s+100)));
-    //二自由度PID
-    tau=0.2;xsi=1.2;
-    PID=syslin('c',(1/(2*xsi*tau*s))*(1+2*xsi*tau*s+tau^2*s^2));
-    clf();
-    nyquist([Plant;Plant*PID],0.5,100,["Plant";"Plant and PID corrector"]);
-    hallchart(colors=color('light gray')*[1 1])
-    //右下隅のキャプションを移動
-    ax=gca();Leg=ax.children(1);
-    Leg.legend_location="in_lower_right";
-    ]]></programlisting>
-        <para>
-            <scilab:image localized="true">
-                s=poly(0,'s');
-                Plant=syslin('c',16000/((s+1)*(s+10)*(s+100)));
-                tau=0.2;xsi=1.2;
-                PID=syslin('c',(1/(2*xsi*tau*s))*(1+2*xsi*tau*s+tau^2*s^2));
-                clf();
-                nyquist([Plant;Plant*PID],0.5,100,["Plant";"Plant and PID corrector"]);
-                hallchart(colors=color('light gray')*[1 1])
-                ax=gca();Leg=ax.children(1);
-                Leg.legend_location="in_lower_right";
-            </scilab:image>
-        </para>
-    </refsection>
-    <refsection role="see also">
-        <title>参照</title>
-        <simplelist type="inline">
-            <member>
-                <link linkend="nyquist">nyquist</link>
-            </member>
-            <member>
-                <link linkend="nicholschart">nicholschart</link>
-            </member>
-        </simplelist>
-    </refsection>
-</refentry>
index ed533fb..654b788 100644 (file)
@@ -1,6 +1,7 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) 2010 - INRIA - Serge STEER
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2020 - Samuel GOUGEON
 //
 // This file is hereby licensed under the terms of the GNU GPL v2.0,
 // pursuant to article 5.3.4 of the CeCILL v.2.1.
 // For more information, see the COPYING file which you should have received
 // along with this program.
 
-function hallchart(modules,args,colors)
-    defaultmodules=[-20 -10 -6 -4 -2 2 4 6 10 20];//in dB
-    defaultargs=[-90 -60 -45 -30 -15 15 30 45 60 90]; //in degree
-    defaultbounds=[-3.5 -2;3 2];
-    if exists("modules","local")==0 then
-        modules=defaultmodules
+function hstruct = hallchart(modules,args,colors)
+
+    // Data bounds
+    // -----------
+    dataBounds = [-4 -3 ; 3 3];
+    axesAlreadyUsed = %f
+    if winsid()<>[] then
+        ax = gca();
+        axesAlreadyUsed = length(ax.children) <> 0
+        if axesAlreadyUsed | or(ax.data_bounds<>gda().data_bounds)
+            dataBounds = ax.data_bounds
+        else
+            ax.data_bounds = dataBounds
+        end
+    end
+    [?,k] = max(abs(dataBounds(3:4)))
+    Yextrem = dataBounds(2+k)
+
+    // Check/set modules
+    // -----------------
+    if ~isdef("modules","l") then
+        // Default modules
+        // ---------------
+        yo = Yextrem
+        dBp = hallGetDefaultModules(dataBounds(1), yo, 8)
+        dBm = hallGetDefaultModules(dataBounds(2), yo, 8)
+        modules = gsort([dBm dBp],"g","i")
     else
-        if type(modules)|~isreal(modules)<>1 then
+        if type(modules)<>1 | ~isreal(modules) then
             error(msprintf("%s: Wrong type for imput argument ""%s"": real floating point array expected\n"),"hallchart","modules");
         end
-        modules=matrix(modules,1,-1)
+        modules = matrix(modules,1,-1)
     end
-    if exists("args","local")==0 then
-        args=defaultargs
+
+    // Check/set Phases
+    // ----------------
+    if ~isdef("args","l") then
+        args = [-90 -60 -40 -30 -25 -20 -15 -12 12 15 20 25 30 40 60 90]; //in degree
     else
         if type(args)<>1|~isreal(args) then
             error(msprintf("%s: Wrong type for imput argument ""%s"": real floating point array expected\n"),"hallchart","args");
         end
-        args=matrix(args,1,-1)
+        args = matrix(args,1,-1)
     end
 
-    if exists("colors","local")==0 then
-        colors=[4 12];
+    // Check/set colors
+    // ----------------
+    defaultCol = ["pink" "skyblue1"]
+    if ~isdef("colors","l") then
+        colors = defaultCol
+    end
+    // Manage "" or 0 input values as default color
+    if type(colors)==10 then
+        if colors(1)=="", colors(1) = defaultCol(1), end
+        if size(colors,"*")>1 & colors(2)=="", colors(2) = defaultCol(2), end
+    elseif type(colors)==1 & or(colors>1)
+        if colors(1)==0, colors(1) = color(defaultCol(1)), end
+        if size(colors,"*")>1 & colors(2)==0, colors(2) = color(defaultCol(2)), end
+    end
+    c = iscolor(colors);
+    if or(isnan(c))
+        msg = _("%s: Argument #%d: Wrong color specification.\n")
+        error(msprintf(msg, "hallchart", 3))
+    end
+    if size(c,1)==1 then
+        c = [c ; c];    // Same color for both subframes
     else
-        if type(colors)<>1|~isreal(colors) then
-            error(msprintf("%s: Wrong type for imput argument ""%s"": real floating point array expected\n"),"hallchart","colors");
-        end
-        if size(colors,"*")==1 then
-            colors=colors*ones(1,2)
-        end
+        c = c(1:2, :);  // selects only the 2 first inputs (no warning)
+    end
+    if size(c,2)==3
+        colors = addcolor(c);
+    else
+        colors = c
     end
 
-    fig=gcf();
-    immediate_drawing=fig.immediate_drawing;
-    fig.immediate_drawing="off";
-
-    ax=gca();
-    nc=size(ax.children,"*")
-    if nc==0 then
-        ax.data_bounds=defaultbounds;
-        ax.axes_visible="on";
-        ax.x_label.text=_("Real axis");
-        ax.y_label.text=_("Imaginary axis");
-        ax.title.text=_("Hall chart")
+    // =======
+    // DRAWING
+    // =======
+    fig = gcf();
+    immediate_drawing = fig.immediate_drawing;
+    fig.immediate_drawing = "off";
+
+    ax = gca();
+    nc = size(ax.children,"*")
+    if ~axesAlreadyUsed
+        ax.axes_visible = "on";
+        xlabel(_("Real axis"), "fontsize",2);
+        ylabel(_("Imaginary axis"), "fontsize",2);
+        title(_("Hall chart"), "fontsize",3)
         ax.box="on";
     end
+    wh = xstringl(0,0,"28dB")(3:4); // Text vshift, for accurate labels placement
 
     //iso modules circles. Circles whose center are (-M^2/(M^2-1),0) and
     //radius M/(M^2-1) with M=|H(jw)| and H=G/(1+G)
 
-    M=exp(log(10)*modules/20)
-    radius=M./(M.*M-ones(M))
-    xc=-M.*radius
-    yc=0
-    radius=abs(radius)
+    M = exp(log(10)*modules/20)
+    radius = M ./ (M.*M-ones(M))
+    xc = -M .* radius
+    yc = 0
+    radius = abs(radius)
     //arcs replaced by polylines to be able to use datatips
     //  xarcs([xc-radius;yc+radius;2*radius;2*radius;0*M;360*64*ones(M)])
     //  A=gce()
     //  E=unglue(A);
-    w=linspace(0,2*%pi,200)
-    c=cos(w);s=sin(w)
-    chart_handles=[]
-    for i=1:size(M,"*")
-        xpoly(xc(i)+radius(i)*c,yc+radius(i)*s)
-        ec=gce();
-        ec.foreground=colors(1);
-        ec.line_style=7;
-        ec.clip_state="clipgrf";
+    w = linspace(0,2*%pi,200)
+    c = cos(w)
+    s = sin(w)
+    chart_handles = []
+    [gainLines, gainLabels] = ([],[])
+    [phaseLines, phaseLabels] = ([],[])
+
+    // Best diagonal angles for positive and negative gain labels:
+    // (we assume xmin<-1, xmax>0, ymin<0, ymax>0. Full adaptative automatic
+    //  settings might be improved later).
+    anglePositiveGainLabels = atand(Yextrem, -1-dataBounds(1))
+    angleNegativeGainLabels = atand(Yextrem, dataBounds(2))
+    if  anglePositiveGainLabels * angleNegativeGainLabels >0 ..
+        & abs(dataBounds(3))==abs(dataBounds(4)) then
+        angleNegativeGainLabels = - angleNegativeGainLabels
+    end
+    // Plotting
+    for i = 1:size(M,"*")
+        xpoly(xc(i)+radius(i)*c, yc+radius(i)*s)
+        ec = gce();
+        ec.foreground = colors(1);
+        ec.line_style = 7;
+        ec.clip_state = "clipgrf";
         ec.display_function = "formatHallModuleTip";
         ec.display_function_data = modules(i);
-        if 2*int(i/2)==i then
-            xs=xc(i)+radius(i)*cos(%pi/6)
-            ys=yc+radius(i)*sin(%pi/6)
+        // Looks for the intersection of the circle with the straight line
+        // to the furthest corner
+        if modules(i) > 0
+            t = tand(anglePositiveGainLabels)
+            b = t^2
+            delta = 4*((b-xc(i))^2 - (1+t^2)*(b + xc(i)^2 - radius(i)^2))
+            xs = (-2*(b-xc(i)) - sqrt(delta))/(2*(1+t^2))
+            ys = -t*(1+xs)
         else
-            xs=xc(i)+radius(i)*cos(-%pi/6)
-            ys=yc+radius(i)*sin(-%pi/6)
-
+            t = tand(angleNegativeGainLabels)
+            b = 0
+            delta = 4*((b-xc(i))^2 - (1+t^2)*(b + xc(i)^2 - radius(i)^2))
+            xs = (-2*(b-xc(i)) + sqrt(delta))/(2*(1+t^2))
+            ys = t*xs
         end
 
-        xstring(xs,ys,string(modules(i))+_("dB"));
-        el=gce();
+        xstring(xs+sign(modules(i))*wh(1)/3, ys, msprintf("%gdB\n",modules(i)));
+        el = gce();
 
-        el.font_foreground=colors(1);
-        el.clip_state="clipgrf";
-        chart_handles=[glue([el ec]) chart_handles];
+        el.font_foreground = colors(1);
+        el.clip_state = "clipgrf";
+        el.text_box = [0 0];
+        el.text_box_mode = "centered";
+        chart_handles = [glue([el ec]) chart_handles];
+        gainLines = [gainLines ec]
+        gainLabels = [gainLabels el]
     end
 
     //iso phase circles. Circles whose center are (-1/2, 1/(2*N)) and
     //radius sqrt(1+N^2)/(2*N) with N=tan(arg(H(-jw)))
 
-    N=tan(args*%pi/180);
-    radius=sqrt(1+N.^2)./(2*N);
-    xc=-1/2;
-    yc=1 ./(2*N);
-
+    N = tan(args/180*%pi);
+    radius = sqrt(1+N.^2)./(2*N);
+    xc = -1/2;
+    yc = 1 ./ (2*N);
     //  xarcs([xc-radius;yc+radius;2*radius;2*radius;0*N;360*64*ones(N)])
     //  E=unglue(gce());
-    for i=1:size(N,"*")
-        xpoly(xc+radius(i)*c,yc(i)+radius(i)*s);ec=gce();
-        ec.foreground=colors(2);
-        ec.line_style=7;
-        ec.clip_state="clipgrf";
+    for i = 1:size(N,"*")
+        xpoly(xc+radius(i)*c, yc(i)+radius(i)*s);
+        ec = gce();
+        ec.foreground = colors(2);
+        ec.line_style = 7;
+        ec.clip_state = "clipgrf";
         ec.display_function = "formatHallPhaseTip";
         ec.display_function_data = args(i);
-        xstring(xc,yc(i)+radius(i),msprintf("%g°",args(i)));
-        el=gce();
-        el.font_foreground=colors(2);
-        el.clip_state="clipgrf";
-        chart_handles=[glue([el ec]) chart_handles];
+        xstring(xc, yc(i)+radius(i)+wh(2)/4, msprintf("%g°", args(i)));
+        el = gce();
+        el.text_box = [0 0];
+        el.text_box_mode = "centered";
+        el.font_foreground = colors(2);
+        el.clip_state = "clipgrf";
+        chart_handles = [glue([el ec]) chart_handles];
+        phaseLines = [phaseLines ec]
+        phaseLabels = [phaseLabels el]
     end
-    chart_handles=glue(chart_handles)
+    chart_handles = glue(chart_handles)
     //reorder axes children to make chart drawn before the previously
     // drawn curves if any
-    for k=1:nc
-        swap_handles(ax.children(k),ax.children(k+1))
+    for k = 1:nc
+        swap_handles(ax.children(k), ax.children(k+1))
     end
-    fig.immediate_drawing=immediate_drawing;
+    ax.data_bounds = dataBounds
+    fig.immediate_drawing = immediate_drawing
+    hstruct = struct("gainLines" ,gainLines, "gainLabels"  ,gainLabels, ..
+                     "phaseLines",phaseLines, "phaseLabels",phaseLabels)
+endfunction
+// ---------------------------------------------------------------------------
+function gains = hallGetDefaultModules(xo, yo, n)
+    // xo: abscissa of the left/right axes bound
+    // yo: ordinates of the furthest bottom|top axes bound
+    // n: number of default modules
+
+    a = (xo^2 + yo^2)
+    //      Search the circle of the (smallest) one passing
+    //      to the furthest left corner (xo,yo)
+    M2 = a / (1 + a + 2*xo)
+    Rmax = sqrt(M2) / abs(M2-1)
+    R = linspace(0, Rmax, n)(2:$);
+    //      Search the circle whose left/right side touches the left/right axes bound
+    Medge = xo / (1+xo)
+    //      Corresponding dB
+    dBedge = 20*log10(Medge)
+
+    if xo < 0 then
+        // Positive gains:
+        //      Generating corresponding dB
+        M = (1 + sqrt(1+4*R.^2)) ./ R / 2
+        dB = 20*log10(M)
+        //      If dBleft > dB(1) => we add it as small circle
+        if dBedge > dB(1)
+            dB = [dB(1)^2/dB(2) dB]
+        end
+        Round = ceil
+    else
+        // Negative gains:
+        //      Generating corresponding dB
+        M = (-1 + sqrt(1+4*R.^2)) ./ R / 2
+        dB = 20*log10(M)
+        //      If dBright < dB(1) => we add it as small circle
+        if dBedge < dB(1)
+            dB = [dB(1)^2/dB(2) dB]
+        end
+        Round = floor
+    end
+
+    // Special rounding of dB values
+    d = abs(dB(1:$-1) - dB(2:$))
+    d($+1) = d($)^2/d($-1)
+    f = 10^floor(log10(d))
+    // At last, we have them:
+    gains = Round(dB ./ f).*f
 endfunction
index 9f76bbc..0e136b9 100644 (file)
@@ -729,21 +729,21 @@ grayplot_1.png=a24a994d92924535d660c5655aaa2089
 grayplot_2.png=a9e3251523550c0c43869fdf37c7f127
 graypolarplot_1.png=00268b5468c68bd5ae7035eda03436cd
 group_1.png=6b464b1c93fe85515d25c7657ec66167
-hallchart_en_US_1.png=01a4557f393fe401dc180f3f0c74626c
-hallchart_en_US_2.png=ea1bd806ba768bef51e1df208af65b07
-hallchart_en_US_3.png=19a304fad91a9edb44b6c13d062ef1c5
-hallchart_fr_FR_1.png=01a4557f393fe401dc180f3f0c74626c
-hallchart_fr_FR_2.png=ea1bd806ba768bef51e1df208af65b07
-hallchart_fr_FR_3.png=19a304fad91a9edb44b6c13d062ef1c5
-hallchart_ja_JP_1.png=01a4557f393fe401dc180f3f0c74626c
-hallchart_ja_JP_2.png=ea1bd806ba768bef51e1df208af65b07
-hallchart_ja_JP_3.png=434f9d799a84fc944a3a18651be4e909
-hallchart_pt_BR_1.png=01a4557f393fe401dc180f3f0c74626c
-hallchart_pt_BR_2.png=ea1bd806ba768bef51e1df208af65b07
-hallchart_pt_BR_3.png=19a304fad91a9edb44b6c13d062ef1c5
-hallchart_ru_RU_1.png=01a4557f393fe401dc180f3f0c74626c
-hallchart_ru_RU_2.png=ea1bd806ba768bef51e1df208af65b07
-hallchart_ru_RU_3.png=19a304fad91a9edb44b6c13d062ef1c5
+hallchart_en_US_1.png=ab69e470907648c5016b5cea7dda0ab6
+hallchart_en_US_2.png=4541241c0ddfc457304ab991622674db
+hallchart_en_US_3.png=dc897cce236116eab58cadab38e96ff2
+hallchart_fr_FR_1.png=ab69e470907648c5016b5cea7dda0ab6
+hallchart_fr_FR_2.png=4541241c0ddfc457304ab991622674db
+hallchart_fr_FR_3.png=dc897cce236116eab58cadab38e96ff2
+hallchart_ja_JP_1.png=ab69e470907648c5016b5cea7dda0ab6
+hallchart_ja_JP_2.png=4541241c0ddfc457304ab991622674db
+hallchart_ja_JP_3.png=dc897cce236116eab58cadab38e96ff2
+hallchart_pt_BR_1.png=ab69e470907648c5016b5cea7dda0ab6
+hallchart_pt_BR_2.png=4541241c0ddfc457304ab991622674db
+hallchart_pt_BR_3.png=dc897cce236116eab58cadab38e96ff2
+hallchart_ru_RU_1.png=ab69e470907648c5016b5cea7dda0ab6
+hallchart_ru_RU_2.png=4541241c0ddfc457304ab991622674db
+hallchart_ru_RU_3.png=dc897cce236116eab58cadab38e96ff2
 hilbert_1.png=51518f324c6c0ba177825aa4dca3d431
 hist3d_2.png=115bdb026707dd18523c17d8e8a1fadc
 hist3d_3.png=9367e60ee55651b1cdedecff26d2c9d7
index 5ed9fd7..42df3bd 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_en_US_1.png and b/scilab/modules/helptools/images/hallchart_en_US_1.png differ
index 69c2d8a..7c88476 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_en_US_2.png and b/scilab/modules/helptools/images/hallchart_en_US_2.png differ
index d0a4a08..a3977c1 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_en_US_3.png and b/scilab/modules/helptools/images/hallchart_en_US_3.png differ
index fc9dca6..450e85d 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_fr_FR_1.png and b/scilab/modules/helptools/images/hallchart_fr_FR_1.png differ
index 225c53f..332e9ba 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_fr_FR_2.png and b/scilab/modules/helptools/images/hallchart_fr_FR_2.png differ
index 9c8a362..0474100 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_fr_FR_3.png and b/scilab/modules/helptools/images/hallchart_fr_FR_3.png differ
index 0a04003..50a05c7 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_ja_JP_1.png and b/scilab/modules/helptools/images/hallchart_ja_JP_1.png differ
index 5ed7cdb..2bd96eb 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_ja_JP_2.png and b/scilab/modules/helptools/images/hallchart_ja_JP_2.png differ
index 5d8c53d..fdd782b 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_ja_JP_3.png and b/scilab/modules/helptools/images/hallchart_ja_JP_3.png differ
index ca0c1da..f92a5fc 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_pt_BR_1.png and b/scilab/modules/helptools/images/hallchart_pt_BR_1.png differ
index f6845a0..a6fae25 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_pt_BR_2.png and b/scilab/modules/helptools/images/hallchart_pt_BR_2.png differ
index 9557453..7e65fb0 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_pt_BR_3.png and b/scilab/modules/helptools/images/hallchart_pt_BR_3.png differ
index 29e341f..e60294e 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_ru_RU_1.png and b/scilab/modules/helptools/images/hallchart_ru_RU_1.png differ
index cd80f9b..3856cb5 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_ru_RU_2.png and b/scilab/modules/helptools/images/hallchart_ru_RU_2.png differ
index af86cd3..57d4848 100644 (file)
Binary files a/scilab/modules/helptools/images/hallchart_ru_RU_3.png and b/scilab/modules/helptools/images/hallchart_ru_RU_3.png differ