[genius] Wed Sep 21 18:55:34 2016 Jiri (George) Lebl <jirka 5z com>



commit 8a659d774a57f4a545d744750e1f285e52f974b3
Author: Jiri (George) Lebl <jiri lebl gmail com>
Date:   Wed Sep 21 18:58:22 2016 -0500

    Wed Sep 21 18:55:34 2016  Jiri (George) Lebl <jirka 5z com>
    
        * src/graphing.c: Add LinePlotWaitForClick and LinePlotMouseLocation
          for interactive programs
    
        * help/C/genius.xml: document the above
    
        * examples/: Make wandering ball interactive and add two Mandelbrot
          set examples, plus a Newton's fractal example

 ChangeLog                                       |   10 +++
 examples/Makefile.am                            |    2 +
 examples/complex-analysis-mandelbrot-define.gel |   58 +++++++++++++
 examples/complex-analysis-wandering-ball.gel    |   33 ++++++--
 help/C/genius.xml                               |   80 +++++++++++++-----
 src/graphing.c                                  |   98 +++++++++++++++++++++++
 6 files changed, 253 insertions(+), 28 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b0dfeb7..29f63ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Wed Sep 21 18:55:34 2016  Jiri (George) Lebl <jirka 5z com>
+
+       * src/graphing.c: Add LinePlotWaitForClick and LinePlotMouseLocation
+         for interactive programs
+
+       * help/C/genius.xml: document the above
+
+       * examples/: Make wandering ball interactive and add two Mandelbrot
+         set examples, plus a Newton's fractal example
+
 Wed Sep 07 14:45:53 2016  Jiri (George) Lebl <jirka 5z com>
 
        * ve/ve-misc.c: ignore a warning in ve_strftime
diff --git a/examples/Makefile.am b/examples/Makefile.am
index d74c5c6..d417ce3 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -23,6 +23,8 @@ example_DATA = \
        easy-matrix-examples.gel \
        peano.gel \
        vibrating-drumhead-modes.gel \
+       complex-analysis-mandelbrot-set.gel \
+       complex-analysis-mandelbrot-define.gel \
        complex-analysis-wandering-ball.gel \
        complex-analysis-mesh.gel
 
diff --git a/examples/complex-analysis-mandelbrot-define.gel b/examples/complex-analysis-mandelbrot-define.gel
new file mode 100644
index 0000000..bbddcfc
--- /dev/null
+++ b/examples/complex-analysis-mandelbrot-define.gel
@@ -0,0 +1,58 @@
+# Category: Complex Analysis
+# Name: Defining the Mandelbrot set
+#
+# Show the first 20 iterations of f(z) = z^2+c starting at 0 and using
+# the current mouse point as c.  If the iterations go out of |z| < 2,
+# then draw a red dot, otherwise draw a green dot.  Eventually the Mandelbrot
+# set should be in green and outside of it in red.
+
+LinePlotWindow = [-2,2,-2,2];
+
+mandelset = null;
+notmandelset = null;
+
+LinePlotDrawLegends = false;
+LinePlotClear();
+PlotWindowPresent ();
+
+circle = null;
+for t = 0.0 to 2*pi by 0.1 do (
+  circle = [circle;2*exp(1i*t)]
+);
+
+iterations = 20;
+
+lastc = null;
+
+while true do (
+  p = LinePlotMouseLocation ();
+  
+  if IsNull(p) then break;
+  
+  c = p@(1) + 1i*p@(2);
+
+  if c != lastc then (
+    lastc = c;
+    
+    points = zeros(2,1);
+    for n = 2 to iterations do (
+      points@(n) = (points@(n-1))^2+c;
+      if |points@(n)| > 100 then break 
+    );
+    
+    if |points@(n)| < 2.0 then
+      mandelset = [mandelset;c]
+    else
+      notmandelset = [notmandelset;c];
+   
+    PlotCanvasFreeze ();
+    LinePlotClear();
+    LinePlotDrawLine(circle, "thickness", 1, "color", "black");
+    LinePlotDrawPoints(mandelset, "thickness", 3, "color", "green");
+    LinePlotDrawPoints(notmandelset, "thickness", 3, "color", "red");
+    LinePlotDrawLine(points, "thickness", 2, "color", "gray");
+    LinePlotDrawPoints(points, "thickness", 6, "color", "blue");
+    PlotCanvasThaw ();
+  );
+  wait(0.000001);
+)
diff --git a/examples/complex-analysis-wandering-ball.gel b/examples/complex-analysis-wandering-ball.gel
index 837d382..abf4d0b 100644
--- a/examples/complex-analysis-wandering-ball.gel
+++ b/examples/complex-analysis-wandering-ball.gel
@@ -2,6 +2,8 @@
 # Name: Visualizing complex mappings, wandering ball
 #
 # Shows a bouncing wandering ball and its image under a complex map.
+# If the mouse is within the plot window, then the mouse location is
+# used for the ball location.
 # Source is in blue and the target is in red.
 #
 
@@ -11,11 +13,17 @@
 #function f(z) = 1i*z;
 #function f(z) = (3+1i)*z;
 #function f(z) = (3+1i)*z+(1+0.5i);
-function f(z) = 0.2*(z-5)*(z+5);
 #function f(z) = 0.2*z^2;
+#function f(z) = 0.01*z^3;
+function f(z) = 0.2*(z-5)*(z+5);
+#function f(z) = 0.01*z^2*(z-5)
+#function f(z) = 25/z;
+#function f(z) = 25/conj(z);
 #function f(z) = 0.1*(z-10)^2*z;
 #function f(z) = exp(z);
-#function f(z) = z^2+1i*z+0.1*sin(z^2);
+
+#for this one you probably want to increase the precision, see "mult" below
+#function f(z) = 0.05*(z^2+1i*z+0.1*sin(z^2));
 
 LinePlotDrawLegends = false;
 PlotWindowPresent(); # Make sure the window is raised
@@ -36,8 +44,8 @@ step = 0.05;
 
 # precision multiplier.  Increasing this number increases the
 # number of points
-mult=1;
-#mult = 3;
+#mult=1;
+mult = 3;
 #mult = 10;
 
 
@@ -48,8 +56,22 @@ line2pts = ApplyOverMatrix((0:(30*mult))',`(k)=1i*radius*(2.0*k/(30*mult)-1));
 
 dir = exp(1i*rand()*2*pi);
 pt = 0;
+lastp = null;
 
 while true do (
+       p = LinePlotMouseLocation ();
+       if IsNull(p) then break;
+       
+
+       # if mouse within window, use that
+       if confine_window@(1) <= p@(1) <= confine_window@(2) and
+          confine_window@(3) <= p@(2) <= confine_window@(4) then (
+               pt = p@(1) + 1i*p@(2);
+               # if at the same point, then just try again;
+               if pt == lastp then (wait(0.0001);continue);
+               lastp = pt
+       );
+
        PlotCanvasFreeze ();
        LinePlotClear ();
 
@@ -68,10 +90,9 @@ while true do (
        points = ApplyOverMatrix(points,f);
        LinePlotDrawLine(points,"color","red");
 
-
-
        PlotCanvasThaw ();
 
+       # Now wander around
 
        pt = pt+step*dir;
 
diff --git a/help/C/genius.xml b/help/C/genius.xml
index 060768f..ded95b8 100644
--- a/help/C/genius.xml
+++ b/help/C/genius.xml
@@ -3,8 +3,8 @@
 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"; [
   <!ENTITY app "<application>Genius Mathematics Tool</application>">
   <!ENTITY appname "Genius">
-  <!ENTITY appversion "1.0.21">
-  <!ENTITY date "August 2016">
+  <!ENTITY appversion "1.0.22">
+  <!ENTITY date "September 2016">
 
   <!ENTITY legal SYSTEM "legal.xml">
 
@@ -8781,6 +8781,34 @@ and has period <userinput>b-a</userinput>.</para>
         </varlistentry>
 
         <varlistentry>
+         <term><anchor id="gel-function-LinePlotCParametric"/>LinePlotCParametric</term>
+         <listitem>
+          <synopsis>LinePlotCParametric (func,...)</synopsis>
+          <synopsis>LinePlotCParametric (func,t1,t2,tinc)</synopsis>
+          <synopsis>LinePlotCParametric (func,t1,t2,tinc,x1,x2,y1,y2)</synopsis>
+          <para>
+           Plot a parametric complex valued function with a line.  First comes
+the function that returns <computeroutput>x+iy</computeroutput>,
+then optionally the <varname>t</varname> limits as <userinput>t1,t2,tinc</userinput>, then
+optionally the limits as <userinput>x1,x2,y1,y2</userinput>.
+          </para>
+         <para>
+           If limits are not
+           specified, then the currently set limits apply
+           (See <link linkend="gel-function-LinePlotWindow"><function>LinePlotWindow</function></link>).
+           If instead the string "fit" is given for the x and y limits, then the limits are the maximum 
extent of
+           the graph
+          </para>
+          <para>
+           The parameter
+           <link linkend="gel-function-LinePlotDrawLegends"><function>LinePlotDrawLegends</function></link>
+           controls the drawing of the legend.
+         </para>
+         </listitem>
+        </varlistentry>
+
+
+        <varlistentry>
          <term><anchor id="gel-function-LinePlotDrawLine"/>LinePlotDrawLine</term>
          <listitem>
           <synopsis>LinePlotDrawLine (x1,y1,x2,y2,...)</synopsis>
@@ -8927,6 +8955,24 @@ and has period <userinput>b-a</userinput>.</para>
         </varlistentry>
 
         <varlistentry>
+         <term><anchor id="gel-function-LinePlotMouseLocation"/>LinePlotMouseLocation</term>
+         <listitem>
+          <synopsis>LinePlotMouseLocation ()</synopsis>
+          <para>
+           Returns a row vector of a point on the line plot corresponding to
+           the current mouse location.  If the line plot is not visible,
+           then prints and error and returns <constant>null</constant>.
+           In this case you should run
+           <link linkend="gel-function-LinePlot"><function>LinePlot</function></link> or
+           <link linkend="gel-function-LinePlotClear"><function>LinePlotClear</function></link>
+           to put the graphing window into the line plot mode.
+           See also
+           <link 
linkend="gel-function-LinePlotWaitForClick"><function>LinePlotWaitForClick</function></link>.
+          </para>
+         </listitem>
+        </varlistentry>
+
+        <varlistentry>
          <term><anchor id="gel-function-LinePlotParametric"/>LinePlotParametric</term>
          <listitem>
           <synopsis>LinePlotParametric (xfunc,yfunc,...)</synopsis>
@@ -8955,29 +9001,19 @@ limits as <userinput>x1,x2,y1,y2</userinput>.
         </varlistentry>
 
         <varlistentry>
-         <term><anchor id="gel-function-LinePlotCParametric"/>LinePlotCParametric</term>
+         <term><anchor id="gel-function-LinePlotWaitForClick"/>LinePlotWaitForClick</term>
          <listitem>
-          <synopsis>LinePlotCParametric (func,...)</synopsis>
-          <synopsis>LinePlotCParametric (func,t1,t2,tinc)</synopsis>
-          <synopsis>LinePlotCParametric (func,t1,t2,tinc,x1,x2,y1,y2)</synopsis>
+          <synopsis>LinePlotWaitForClick ()</synopsis>
           <para>
-           Plot a parametric complex valued function with a line.  First comes
-the function that returns <computeroutput>x+iy</computeroutput>,
-then optionally the <varname>t</varname> limits as <userinput>t1,t2,tinc</userinput>, then
-optionally the limits as <userinput>x1,x2,y1,y2</userinput>.
-          </para>
-         <para>
-           If limits are not
-           specified, then the currently set limits apply
-           (See <link linkend="gel-function-LinePlotWindow"><function>LinePlotWindow</function></link>).
-           If instead the string "fit" is given for the x and y limits, then the limits are the maximum 
extent of
-           the graph
+           If in line plot mode, waits for a click on the line plot window
+           and returns the location of the click as a row vector.
+           If the window is closed
+           the function returns immediately with <constant>null</constant>.
+           If the window is not in line plot mode, it is put in it and shown
+           if not shown.
+           See also
+           <link 
linkend="gel-function-LinePlotMouseLocation"><function>LinePlotMouseLocation</function></link>.
           </para>
-          <para>
-           The parameter
-           <link linkend="gel-function-LinePlotDrawLegends"><function>LinePlotDrawLegends</function></link>
-           controls the drawing of the legend.
-         </para>
          </listitem>
         </varlistentry>
 
diff --git a/src/graphing.c b/src/graphing.c
index 07d0517..face762 100644
--- a/src/graphing.c
+++ b/src/graphing.c
@@ -1574,6 +1574,10 @@ static gdouble dozoom_xmax;
 static gdouble dozoom_ymax;
 static gboolean dozoom_just_click;
 
+static gboolean wait_for_click = FALSE;
+static gdouble click_x = 0.0;
+static gdouble click_y = 0.0;
+
 static gboolean
 dozoom_idle (gpointer data)
 {
@@ -1674,6 +1678,19 @@ plot_select_region (GtkPlotCanvas *canvas,
                ymin = tmp;
        }
 
+       if (wait_for_click) {
+               double x, y;
+               len = plotx2 - plotx1;
+               x = plotx1 + len * xmin;
+               len = ploty2 - ploty1;
+               y = ploty1 + len * ymin;
+               click_x = x;
+               click_y = y;
+               wait_for_click = FALSE;
+               return;
+       }
+
+
        if (plot_in_progress == 0 &&
            line_plot != NULL &&
            (plot_mode == MODE_LINEPLOT_SLOPEFIELD ||
@@ -8329,6 +8346,85 @@ PlotWindowPresent_op (GelCtx *ctx, GelETree * * a, int *exception)
        return gel_makenum_null ();
 }
 
+static GelETree *
+LinePlotWaitForClick_op (GelCtx *ctx, GelETree * * a, int *exception)
+{
+       GelETree *n;
+       GelMatrixW *m;
+
+       ensure_window (FALSE /* do_window_present */);
+
+       if (plot_mode != MODE_LINEPLOT &&
+           plot_mode != MODE_LINEPLOT_PARAMETRIC &&
+           plot_mode != MODE_LINEPLOT_SLOPEFIELD &&
+           plot_mode != MODE_LINEPLOT_VECTORFIELD) {
+               plot_mode = MODE_LINEPLOT;
+               clear_graph ();
+       }
+
+       if (line_plot == NULL) {
+               add_line_plot ();
+               plot_setup_axis ();
+       }
+
+       wait_for_click = TRUE;
+
+       while (wait_for_click) {
+               while (gtk_events_pending ())
+                       gtk_main_iteration ();
+               if (gel_interrupted) {
+                       wait_for_click = FALSE;
+                       return NULL;
+               }
+               if (line_plot == NULL) {
+                       wait_for_click = FALSE;
+                       return gel_makenum_null ();
+               }
+       }
+
+       /*make us a new empty node*/
+       GEL_GET_NEW_NODE (n);
+       n->type = GEL_MATRIX_NODE;
+       m = n->mat.matrix = gel_matrixw_new ();
+       n->mat.quoted = FALSE;
+       gel_matrixw_set_size (m, 2, 1);
+
+       gel_matrixw_set_index (m, 0, 0) = gel_makenum_d (click_x);
+       gel_matrixw_set_index (m, 1, 0) = gel_makenum_d (click_y);
+
+       return n;
+}
+
+static GelETree *
+LinePlotMouseLocation_op (GelCtx *ctx, GelETree * * a, int *exception)
+{
+       if (line_plot != NULL) {
+               GelETree *n;
+               GelMatrixW *m;
+               int xx, yy;
+               double x, y;
+
+               gtk_widget_get_pointer (GTK_WIDGET (line_plot), &xx, &yy);
+               gtk_plot_get_point (GTK_PLOT (line_plot), xx, yy, &x, &y);
+
+               /*make us a new empty node*/
+               GEL_GET_NEW_NODE (n);
+               n->type = GEL_MATRIX_NODE;
+               m = n->mat.matrix = gel_matrixw_new ();
+               n->mat.quoted = FALSE;
+               gel_matrixw_set_size (m, 2, 1);
+
+               gel_matrixw_set_index (m, 0, 0) = gel_makenum_d (x);
+               gel_matrixw_set_index (m, 1, 0) = gel_makenum_d (y);
+
+               return n;
+       } else {
+               gel_errorout (_("%s: Not in line plot mode.  Perhaps run LinePlot or LinePlotClear first."),
+                             "LinePlotMouseLocation");
+               return gel_makenum_null ();
+       }
+}
+
 void
 gel_plot_canvas_thaw_completely (void)
 {
@@ -10730,6 +10826,8 @@ gel_add_graph_functions (void)
        FUNC (PlotCanvasThaw, 0, "", "plotting", N_("Thaw the plot canvas and redraw the plot immediately"));
        FUNC (PlotWindowPresent, 0, "", "plotting", N_("Raise the plot window, and create the window if 
necessary"));
 
+       FUNC (LinePlotWaitForClick, 0, "", "plotting", N_("Wait for a click on the line plot window, return 
the location."));
+       FUNC (LinePlotMouseLocation, 0, "", "plotting", N_("Return current mouse location on the line plot 
window."));
 
        VFUNC (ExportPlot, 2, "filename,type", "plotting", N_("Export the current contents of the plot canvas 
to a file.  The file type is given by the string type, which can be \"png\", \"eps\", or \"ps\"."));
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]