[genius] Wed Sep 21 18:55:34 2016 Jiri (George) Lebl <jirka 5z com>
- From: George Lebl <jirka src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [genius] Wed Sep 21 18:55:34 2016 Jiri (George) Lebl <jirka 5z com>
- Date: Wed, 21 Sep 2016 23:58:47 +0000 (UTC)
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]