genius r745 - in trunk: . help/C src
- From: jirka svn gnome org
- To: svn-commits-list gnome org
- Subject: genius r745 - in trunk: . help/C src
- Date: Thu, 5 Mar 2009 06:01:39 +0000 (UTC)
Author: jirka
Date: Thu Mar 5 06:01:39 2009
New Revision: 745
URL: http://svn.gnome.org/viewvc/genius?rev=745&view=rev
Log:
Wed Mar 04 23:58:43 2009 Jiri (George) Lebl <jirka 5z com>
* src/graphing.c: add two more style strings to LinePlotDrawLine.
First "window" can set the window, with a "fit" being a fitting
window. Also allow drawing of arrows by "arrow" followed by
"end", "both", "origin", "none" (done in canvas coordinates, not
screen coordinates, not ideal, try zooming)
* src/graphing.c, src/funclib.c: a bit of cleanup, some pointless
optimizations, and make sure the graphing functions don't get
called during plotting. Also setting LinePlotWindow,
SurfacePlotWindow will change zoom immediately as one would expect
* help/C/gel-function-list.xml: update
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/help/C/gel-function-list.xml
trunk/help/C/genius.txt
trunk/help/C/genius.xml
trunk/src/funclib.c
trunk/src/graphing.c
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Thu Mar 5 06:01:39 2009
@@ -4,14 +4,16 @@
* Draw solutions for vector fields
* Add VectorfieldDrawSolution and VectorfieldClearSolutions
* AskString now allows setting a default
-* An icon for the plot button
+* LinePlotDrawLine can change the plot winow and draw arrows
* Read-only files are handled properly
* Clip all lines to within the plot window
+* LinePlotWindow, SurfacePlotWindow now update the zoom immediately
* Fix zooming into vectorfield/slopefileld/parametric plots
* Fix flicker when plotting
* Fix line plot scale precision in case the x and y axis have very different
scales
* Remove dependence on libgnome/ui
+* An icon for the plot button
* Some optimizations
* Several other minor bugfixes
* Translation updates
Modified: trunk/help/C/gel-function-list.xml
==============================================================================
--- trunk/help/C/gel-function-list.xml (original)
+++ trunk/help/C/gel-function-list.xml Thu Mar 5 06:01:39 2009
@@ -4824,15 +4824,28 @@
<varname>n</varname> by 2 matrix for a longer line.
</para>
<para>
- Extra parameters can be added to specify line color and thickness,
- by adding a string <userinput>"color"</userinput> or
- <userinput>"thickness"</userinput> and the color and thickness
- after as a string or integer respectively.
+ Extra parameters can be added to specify line color, thickness,
+ arrows, and the plotting window.
+ You can do this by adding a string <userinput>"color"</userinput>,
+ <userinput>"thickness"</userinput>,
+ <userinput>"window"</userinput>, or
+ <userinput>"arrow"</userinput>, and after it either
+ the color string, the thicknes as an integer, the window
+ as 4-vector, and for arrow either
+ <userinput>"origin"</userinput>,
+ <userinput>"end"</userinput>,
+ <userinput>"both"</userinput>, or
+ <userinput>"none"</userinput>. For
+ <userinput>"window"</userinput> we can specify
+ <userinput>"fit"</userinput> rather than a vector in which case,
+ the x range will be set precisely and the y range will be set with
+ five percent borders around the line.
</para>
<para>
Examples:
<screen><prompt>genius></prompt> <userinput>LinePlotDrawLine(0,0,1,1,"color","blue","thickness",3)</userinput>
<prompt>genius></prompt> <userinput>LinePlotDrawLine([0,0;1,-1;-1,-1])</userinput>
+<prompt>genius></prompt> <userinput>LinePlotDrawLine([0,0;1,1],"arrow","end")</userinput>
</screen>
</para>
</listitem>
Modified: trunk/help/C/genius.txt
==============================================================================
--- trunk/help/C/genius.txt (original)
+++ trunk/help/C/genius.txt Thu Mar 5 06:01:39 2009
@@ -5477,14 +5477,20 @@
Draw a line from x1,y1 to x2,y2. x1,y1, x2,y2 can be replaced by
an n by 2 matrix for a longer line.
- Extra parameters can be added to specify line color and thickness,
- by adding a string "color" or "thickness" and the color and
- thickness after as a string or integer respectively.
+ Extra parameters can be added to specify line color, thickness,
+ arrows, and the plotting window. You can do this by adding a
+ string "color", "thickness", "window", or "arrow", and after it
+ either the color string, the thicknes as an integer, the window as
+ 4-vector, and for arrow either "origin", "end", "both", or "none".
+ For "window" we can specify "fit" rather than a vector in which
+ case, the x range will be set precisely and the y range will be
+ set with five percent borders around the line.
Examples:
genius> LinePlotDrawLine(0,0,1,1,"color","blue","thickness",3)
genius> LinePlotDrawLine([0,0;1,-1;-1,-1])
+ genius> LinePlotDrawLine([0,0;1,1],"arrow","end")
LinePlotParametric
Modified: trunk/help/C/genius.xml
==============================================================================
--- trunk/help/C/genius.xml (original)
+++ trunk/help/C/genius.xml Thu Mar 5 06:01:39 2009
@@ -5,7 +5,7 @@
<!ENTITY appname "Genius">
<!ENTITY appversion "1.0.6">
<!ENTITY manrevision "0.2.3">
- <!ENTITY date "February 2009">
+ <!ENTITY date "March 2009">
<!ENTITY legal SYSTEM "legal.xml">
Modified: trunk/src/funclib.c
==============================================================================
--- trunk/src/funclib.c (original)
+++ trunk/src/funclib.c Thu Mar 5 06:01:39 2009
@@ -332,17 +332,17 @@
{
int secs;
- if ( ! check_argument_nonnegative_integer (a, 0, "wait"))
+ if G_UNLIKELY ( ! check_argument_nonnegative_integer (a, 0, "wait"))
return NULL;
secs = gel_get_nonnegative_integer (a[0]->val.value, "wait");
- if (secs < 0)
+ if G_UNLIKELY (secs < 0)
return NULL;
if (secs == 0) {
if (evalnode_hook != NULL)
(*evalnode_hook)();
- if (interrupted)
+ if G_UNLIKELY (interrupted)
return NULL;
else
return gel_makenum_null ();
@@ -373,7 +373,7 @@
sleep (1);
}
- if (interrupted)
+ if G_UNLIKELY (interrupted)
return NULL;
else
return gel_makenum_null ();
@@ -502,11 +502,11 @@
GelMatrix *m;
int size, i;
- if ( ! check_argument_nonnegative_integer (a, 0, "rand"))
+ if G_UNLIKELY ( ! check_argument_nonnegative_integer (a, 0, "rand"))
return NULL;
size = gel_get_nonnegative_integer (a[0]->val.value, "rand");
- if (size < 0)
+ if G_UNLIKELY (size < 0)
return NULL;
if (size == 0)
@@ -533,15 +533,15 @@
GelMatrix *m;
int sizex, sizey, i, j;
- if ( ! check_argument_nonnegative_integer (a, 0, "rand") ||
- ! check_argument_nonnegative_integer (a, 1, "rand"))
+ if G_UNLIKELY ( ! check_argument_nonnegative_integer (a, 0, "rand") ||
+ ! check_argument_nonnegative_integer (a, 1, "rand"))
return NULL;
sizey = gel_get_nonnegative_integer (a[0]->val.value, "rand");
- if (sizey < 0)
+ if G_UNLIKELY (sizey < 0)
return NULL;
sizex = gel_get_nonnegative_integer (a[1]->val.value, "rand");
- if (sizex < 0)
+ if G_UNLIKELY (sizex < 0)
return NULL;
if (sizex == 0 || sizey == 0)
@@ -587,12 +587,12 @@
if (args == 1) {
mpw_t fr;
- if ( ! check_argument_integer (a, 0, "randint"))
+ if G_UNLIKELY ( ! check_argument_integer (a, 0, "randint"))
return NULL;
mpw_init (fr);
mpw_randint (fr, a[0]->val.value);
- if (error_num != 0) {
+ if G_UNLIKELY (error_num != 0) {
mpw_clear (fr);
return NULL;
}
@@ -603,12 +603,12 @@
GelMatrix *m;
int size, i;
- if ( ! check_argument_integer (a, 0, "randint") ||
- ! check_argument_nonnegative_integer (a, 1, "randint"))
+ if G_UNLIKELY ( ! check_argument_integer (a, 0, "randint") ||
+ ! check_argument_nonnegative_integer (a, 1, "randint"))
return NULL;
size = gel_get_nonnegative_integer (a[1]->val.value, "randint");
- if (size < 0)
+ if G_UNLIKELY (size < 0)
return NULL;
if (size == 0)
@@ -620,7 +620,7 @@
mpw_t fr;
mpw_init (fr);
mpw_randint (fr, a[0]->val.value);
- if (error_num != 0) {
+ if G_UNLIKELY (error_num != 0) {
mpw_clear (fr);
/* This can only happen if a[0]->val.value is
* evil, in which case we have not set any
@@ -645,16 +645,16 @@
GelMatrix *m;
int sizex, sizey, i, j;
- if ( ! check_argument_integer (a, 0, "randint") ||
- ! check_argument_nonnegative_integer (a, 1, "randint") ||
- ! check_argument_nonnegative_integer (a, 2, "randint"))
+ if G_UNLIKELY ( ! check_argument_integer (a, 0, "randint") ||
+ ! check_argument_nonnegative_integer (a, 1, "randint") ||
+ ! check_argument_nonnegative_integer (a, 2, "randint"))
return NULL;
sizey = gel_get_nonnegative_integer (a[1]->val.value, "randint");
- if (sizey < 0)
+ if G_UNLIKELY (sizey < 0)
return NULL;
sizex = gel_get_nonnegative_integer (a[2]->val.value, "randint");
- if (sizex < 0)
+ if G_UNLIKELY (sizex < 0)
return NULL;
if (sizex == 0 || sizey == 0)
@@ -667,7 +667,7 @@
mpw_t fr;
mpw_init (fr);
mpw_randint (fr, a[0]->val.value);
- if (error_num != 0) {
+ if G_UNLIKELY (error_num != 0) {
mpw_clear (fr);
/* This can only happen if a[0]->val.value is
* evil, in which case we have not set any
@@ -1263,10 +1263,10 @@
static GelETree *
CatalanConstant_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
{
- mpw_t e;
- mpw_init (e);
- mpw_catalan_constant (e);
- return gel_makenum_use (e);
+ mpw_t cc;
+ mpw_init (cc);
+ mpw_catalan_constant (cc);
+ return gel_makenum_use (cc);
}
/*pi function (or pi variable or whatever)*/
@@ -1283,7 +1283,7 @@
static GelETree *
GoldenRatio_op (GelCtx *ctx, GelETree * * a, gboolean *exception)
{
- if (golden_ratio_iscached)
+ if G_LIKELY (golden_ratio_iscached)
return gel_makenum (golden_ratio_cache);
mpw_init (golden_ratio_cache);
@@ -1733,7 +1733,7 @@
return NULL;
mpw_init(fr);
mpw_numerator(fr,a[0]->val.value);
- if(error_num) {
+ if G_UNLIKELY (error_num) {
error_num = 0;
mpw_clear(fr);
return NULL;
@@ -1758,7 +1758,7 @@
return NULL;
mpw_init(fr);
mpw_denominator(fr,a[0]->val.value);
- if(error_num) {
+ if G_UNLIKELY (error_num) {
error_num = 0;
mpw_clear(fr);
return NULL;
@@ -1833,15 +1833,15 @@
num = mpw_peek_real_mpz (ctx->modulo);
is_prime = mympz_is_prime (num, -1);
- if ( ! is_prime) {
+ if G_UNLIKELY ( ! is_prime) {
gel_errorout (_("%s: square root for composite moduli "
"is not yet implemented"), "sqrt");
return NULL;
}
- if (SqrtModPrime_id == NULL)
+ if G_UNLIKELY (SqrtModPrime_id == NULL)
SqrtModPrime_id = d_intern ("SqrtModPrime");
SqrtModPrime = d_lookup_only_global (SqrtModPrime_id);
- if (SqrtModPrime == NULL) {
+ if G_UNLIKELY (SqrtModPrime == NULL) {
gel_errorout (_("%s: Cannot find square root function "
"for prime moduli"), "sqrt");
return NULL;
@@ -1873,8 +1873,8 @@
}
if(a[0]->type==MATRIX_NODE) {
- if(gel_matrixw_width(a[0]->mat.matrix) !=
- gel_matrixw_height(a[0]->mat.matrix)) {
+ if G_UNLIKELY (gel_matrixw_width(a[0]->mat.matrix) !=
+ gel_matrixw_height(a[0]->mat.matrix)) {
gel_errorout (_("%s: matrix argument is not square"),
"exp");
return NULL;
@@ -1906,7 +1906,7 @@
return NULL;
mpw_init(fr);
mpw_ln(fr,a[0]->val.value);
- if(error_num) {
+ if G_UNLIKELY (error_num) {
error_num = 0;
mpw_clear(fr);
return NULL;
@@ -1931,7 +1931,7 @@
return NULL;
mpw_init(fr);
mpw_log2(fr,a[0]->val.value);
- if(error_num) {
+ if G_UNLIKELY (error_num) {
error_num = 0;
mpw_clear(fr);
return NULL;
@@ -1956,7 +1956,7 @@
return NULL;
mpw_init(fr);
mpw_log10(fr,a[0]->val.value);
- if(error_num) {
+ if G_UNLIKELY (error_num) {
error_num = 0;
mpw_clear(fr);
return NULL;
@@ -5427,9 +5427,9 @@
mpw_clear (arg.val.value);
- if (error_num != 0 ||
- ret == NULL ||
- ret->type != VALUE_NODE) {
+ if G_UNLIKELY (error_num != 0 ||
+ ret == NULL ||
+ ret->type != VALUE_NODE) {
gel_freetree (ret);
return FALSE;
}
Modified: trunk/src/graphing.c
==============================================================================
--- trunk/src/graphing.c (original)
+++ trunk/src/graphing.c Thu Mar 5 06:01:39 2009
@@ -286,6 +286,14 @@
};
static void
+color_alloc (GdkColor *color)
+{
+ GdkColormap *colormap = gdk_colormap_get_system();
+ gdk_colormap_alloc_color (colormap, color, FALSE /* writable */, TRUE /* best_match */);
+ /* errors? */
+}
+
+static void
plot_window_setup (void)
{
if (graph_window != NULL) {
@@ -1944,6 +1952,7 @@
FALSE /* vminor */);
gdk_color_parse ("gray75", &gray);
+ color_alloc (&gray);
gtk_plot_x0line_set_attributes (GTK_PLOT (line_plot),
GTK_PLOT_LINE_SOLID,
@@ -2978,7 +2987,7 @@
gtk_plot_add_data (GTK_PLOT (line_plot), data);
gtk_plot_data_hide_legend (data);
- gdk_color_alloc (gdk_colormap_get_system (), color);
+ color_alloc (color);
gtk_plot_data_set_line_attributes (data,
GTK_PLOT_LINE_SOLID,
@@ -3287,6 +3296,7 @@
gtk_plot_add_data (GTK_PLOT (line_plot),
slopefield_data);
gdk_color_parse ("blue", &color);
+ color_alloc (&color);
gtk_plot_data_set_line_attributes (slopefield_data,
GTK_PLOT_LINE_NONE,
0, 0, 1, &color);
@@ -3339,6 +3349,7 @@
gtk_plot_add_data (GTK_PLOT (line_plot),
vectorfield_data);
gdk_color_parse ("blue", &color);
+ color_alloc (&color);
gtk_plot_data_set_line_attributes (vectorfield_data,
GTK_PLOT_LINE_NONE,
0, 0, 1, &color);
@@ -3477,7 +3488,7 @@
gtk_widget_show (GTK_WIDGET (line_data[i]));
gdk_color_parse (colors[color_i++], &color);
- gdk_color_alloc (gdk_colormap_get_system (), &color);
+ color_alloc (&color);
gtk_plot_data_set_line_attributes (line_data[i],
GTK_PLOT_LINE_SOLID,
0, 0, 2, &color);
@@ -3531,7 +3542,7 @@
gtk_widget_show (GTK_WIDGET (parametric_data));
gdk_color_parse (colors[color_i++], &color);
- gdk_color_alloc (gdk_colormap_get_system (), &color);
+ color_alloc (&color);
gtk_plot_data_set_line_attributes (parametric_data,
GTK_PLOT_LINE_SOLID,
0, 0, 2, &color);
@@ -5035,6 +5046,12 @@
int i;
GelEFunc *func = NULL;
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "SurfacePlot", "SurfacePlot");
+ return NULL;
+ }
+
i = 0;
if (a[i] != NULL && a[i]->type != FUNCTION_NODE) {
@@ -5167,6 +5184,12 @@
{
double x, y, dx;
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "SlopefieldDrawSolution", "SlopefieldDrawSolution");
+ return NULL;
+ }
+
GET_DOUBLE (x, 0, "SlopefieldDrawSolution");
GET_DOUBLE (y, 1, "SlopefieldDrawSolution");
GET_DOUBLE (dx, 2, "SlopefieldDrawSolution");
@@ -5192,6 +5215,11 @@
static GelETree *
SlopefieldClearSolutions_op (GelCtx *ctx, GelETree * * a, int *exception)
{
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "SlopefieldClearSolutions", "SlopefieldClearSolutions");
+ return NULL;
+ }
if (plot_mode != MODE_LINEPLOT_SLOPEFIELD) {
gel_errorout (_("%s: Slope field not active"),
"SlopefieldClearSolutions");
@@ -5208,26 +5236,32 @@
{
double x, y, dt, tlen;
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "VectorfieldDrawSolution", "VectorfieldDrawSolution");
+ return NULL;
+ }
+
GET_DOUBLE (x, 0, "VectorfieldDrawSolution");
GET_DOUBLE (y, 1, "VectorfieldDrawSolution");
GET_DOUBLE (dt, 2, "VectorfieldDrawSolution");
GET_DOUBLE (tlen, 3, "VectorfieldDrawSolution");
- if (dt <= 0.0) {
+ if G_UNLIKELY (dt <= 0.0) {
gel_errorout (_("%s: dt must be positive"),
"VectorfieldDrawSolution");
return NULL;
}
- if (tlen <= 0.0) {
+ if G_UNLIKELY (tlen <= 0.0) {
gel_errorout (_("%s: tlen must be positive"),
"VectorfieldDrawSolution");
return NULL;
}
- if (plot_mode != MODE_LINEPLOT_VECTORFIELD ||
- vectorfield_func_x == NULL ||
- vectorfield_func_y == NULL) {
+ if G_UNLIKELY (plot_mode != MODE_LINEPLOT_VECTORFIELD ||
+ vectorfield_func_x == NULL ||
+ vectorfield_func_y == NULL) {
gel_errorout (_("%s: Vector field not active"),
"VectorfieldDrawSolution");
return NULL;
@@ -5242,7 +5276,13 @@
static GelETree *
VectorfieldClearSolutions_op (GelCtx *ctx, GelETree * * a, int *exception)
{
- if (plot_mode != MODE_LINEPLOT_VECTORFIELD) {
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "VectorfieldClearSolutions", "VectorfieldClearSolutions");
+ return NULL;
+ }
+
+ if G_UNLIKELY (plot_mode != MODE_LINEPLOT_VECTORFIELD) {
gel_errorout (_("%s: Vector field not active"),
"VectorfieldClearSolutions");
return NULL;
@@ -5260,8 +5300,14 @@
GelEFunc *func = NULL;
int i;
- if (a[0] == NULL ||
- a[0]->type != FUNCTION_NODE) {
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "SlopefieldPlot", "SlopefieldPlot");
+ return NULL;
+ }
+
+ if G_UNLIKELY (a[0] == NULL ||
+ a[0]->type != FUNCTION_NODE) {
gel_errorout (_("%s: First argument must be a function"),
"SlopefieldPlot");
return NULL;
@@ -5363,12 +5409,18 @@
GelEFunc *funcy = NULL;
int i;
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "VectorfieldPlot", "VectorfieldPlot");
+ return NULL;
+ }
+
/* FIXME: also accept just one function and then treat it as complex
* valued */
- if (a[0] == NULL || a[1] == NULL ||
- a[0]->type != FUNCTION_NODE ||
- a[1]->type != FUNCTION_NODE) {
+ if G_UNLIKELY (a[0] == NULL || a[1] == NULL ||
+ a[0]->type != FUNCTION_NODE ||
+ a[1]->type != FUNCTION_NODE) {
gel_errorout (_("%s: First two arguments must be functions"), "VectorfieldPlot");
return NULL;
}
@@ -5415,24 +5467,24 @@
}
}
- if (x1 > x2) {
+ if G_UNLIKELY (x1 > x2) {
double s = x1;
x1 = x2;
x2 = s;
}
- if (y1 > y2) {
+ if G_UNLIKELY (y1 > y2) {
double s = y1;
y1 = y2;
y2 = s;
}
- if (x1 == x2) {
+ if G_UNLIKELY (x1 == x2) {
gel_errorout (_("%s: invalid X range"), "VectorfieldPlot");
goto whack_copied_funcs;
}
- if (y1 == y2) {
+ if G_UNLIKELY (y1 == y2) {
gel_errorout (_("%s: invalid Y range"), "VectorfieldPlot");
goto whack_copied_funcs;
}
@@ -5476,6 +5528,12 @@
GelEFunc *func[MAXFUNC] = { NULL };
int i;
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "LinePlot", "LinePlot");
+ return NULL;
+ }
+
for (i = 0;
i < MAXFUNC && a[i] != NULL && a[i]->type == FUNCTION_NODE;
i++) {
@@ -5484,12 +5542,12 @@
funcs++;
}
- if (a[i] != NULL && a[i]->type == FUNCTION_NODE) {
+ if G_UNLIKELY (a[i] != NULL && a[i]->type == FUNCTION_NODE) {
gel_errorout (_("%s: only up to 10 functions supported"), "LinePlot");
goto whack_copied_funcs;
}
- if (funcs == 0) {
+ if G_UNLIKELY (funcs == 0) {
gel_errorout (_("%s: argument not a function"), "LinePlot");
goto whack_copied_funcs;
}
@@ -5521,31 +5579,31 @@
}
}
/* FIXME: what about errors */
- if (error_num != 0) {
+ if G_UNLIKELY (error_num != 0) {
error_num = 0;
goto whack_copied_funcs;
}
}
}
- if (x1 > x2) {
+ if G_UNLIKELY (x1 > x2) {
double s = x1;
x1 = x2;
x2 = s;
}
- if (y1 > y2) {
+ if G_UNLIKELY (y1 > y2) {
double s = y1;
y1 = y2;
y2 = s;
}
- if (x1 == x2) {
+ if G_UNLIKELY (x1 == x2) {
gel_errorout (_("%s: invalid X range"), "LinePlot");
goto whack_copied_funcs;
}
- if (y1 == y2) {
+ if G_UNLIKELY (y1 == y2) {
gel_errorout (_("%s: invalid Y range"), "LinePlot");
goto whack_copied_funcs;
}
@@ -5567,7 +5625,7 @@
plot_mode = MODE_LINEPLOT;
plot_functions (FALSE /* do_window_present */);
- if (interrupted)
+ if G_UNLIKELY (interrupted)
return NULL;
else
return gel_makenum_null ();
@@ -5589,9 +5647,15 @@
GelEFunc *funcy = NULL;
int i;
- if (a[0] == NULL || a[1] == NULL ||
- a[0]->type != FUNCTION_NODE ||
- a[1]->type != FUNCTION_NODE) {
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "LinePlotParametric", "LinePlotParametric");
+ return NULL;
+ }
+
+ if G_UNLIKELY (a[0] == NULL || a[1] == NULL ||
+ a[0]->type != FUNCTION_NODE ||
+ a[1]->type != FUNCTION_NODE) {
gel_errorout (_("%s: First two arguments must be functions"), "LinePlotParametric");
return NULL;
}
@@ -5625,7 +5689,7 @@
}
}
/* FIXME: what about errors */
- if (error_num != 0) {
+ if G_UNLIKELY (error_num != 0) {
error_num = 0;
goto whack_copied_funcs;
}
@@ -5653,36 +5717,36 @@
}
}
/* FIXME: what about errors */
- if (error_num != 0) {
+ if G_UNLIKELY (error_num != 0) {
error_num = 0;
goto whack_copied_funcs;
}
}
}
- if (x1 > x2) {
+ if G_UNLIKELY (x1 > x2) {
double s = x1;
x1 = x2;
x2 = s;
}
- if (y1 > y2) {
+ if G_UNLIKELY (y1 > y2) {
double s = y1;
y1 = y2;
y2 = s;
}
- if (x1 == x2) {
+ if G_UNLIKELY (x1 == x2) {
gel_errorout (_("%s: invalid X range"), "LinePlotParametric");
goto whack_copied_funcs;
}
- if (y1 == y2) {
+ if G_UNLIKELY (y1 == y2) {
gel_errorout (_("%s: invalid Y range"), "LinePlotParametric");
goto whack_copied_funcs;
}
- if (t1 >= t2 || tinc <= 0) {
+ if G_UNLIKELY (t1 >= t2 || tinc <= 0) {
gel_errorout (_("%s: invalid T range"), "LinePlotParametric");
goto whack_copied_funcs;
}
@@ -5706,7 +5770,7 @@
plot_mode = MODE_LINEPLOT_PARAMETRIC;
plot_functions (FALSE /* do_window_present */);
- if (interrupted)
+ if G_UNLIKELY (interrupted)
return NULL;
else
return gel_makenum_null ();
@@ -5727,8 +5791,14 @@
GelEFunc *func = NULL;
int i;
- if (a[0] == NULL ||
- a[0]->type != FUNCTION_NODE) {
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "LinePlotCParametric", "LinePlotCParametric");
+ return NULL;
+ }
+
+ if G_UNLIKELY (a[0] == NULL ||
+ a[0]->type != FUNCTION_NODE) {
gel_errorout (_("%s: First argument must be a function"),
"LinePlotCParametric");
return NULL;
@@ -5761,7 +5831,7 @@
}
}
/* FIXME: what about errors */
- if (error_num != 0) {
+ if G_UNLIKELY (error_num != 0) {
error_num = 0;
goto whack_copied_funcs;
}
@@ -5789,36 +5859,36 @@
}
}
/* FIXME: what about errors */
- if (error_num != 0) {
+ if G_UNLIKELY (error_num != 0) {
error_num = 0;
goto whack_copied_funcs;
}
}
}
- if (x1 > x2) {
+ if G_UNLIKELY (x1 > x2) {
double s = x1;
x1 = x2;
x2 = s;
}
- if (y1 > y2) {
+ if G_UNLIKELY (y1 > y2) {
double s = y1;
y1 = y2;
y2 = s;
}
- if (x1 == x2) {
+ if G_UNLIKELY (x1 == x2) {
gel_errorout (_("%s: invalid X range"), "LinePlotCParametric");
goto whack_copied_funcs;
}
- if (y1 == y2) {
+ if G_UNLIKELY (y1 == y2) {
gel_errorout (_("%s: invalid Y range"), "LinePlotCParametric");
goto whack_copied_funcs;
}
- if (t1 >= t2 || tinc <= 0) {
+ if G_UNLIKELY (t1 >= t2 || tinc <= 0) {
gel_errorout (_("%s: invalid T range"), "LinePlotCParametric");
goto whack_copied_funcs;
}
@@ -5841,7 +5911,7 @@
plot_mode = MODE_LINEPLOT_PARAMETRIC;
plot_functions (FALSE /* do_window_present */);
- if (interrupted)
+ if G_UNLIKELY (interrupted)
return NULL;
else
return gel_makenum_null ();
@@ -5856,29 +5926,81 @@
static GelETree *
LinePlotClear_op (GelCtx *ctx, GelETree * * a, int *exception)
{
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "LinePlotClear", "LinePlotClear");
+ return NULL;
+ }
+
line_plot_clear_funcs ();
/* This will just clear the window */
plot_mode = MODE_LINEPLOT;
plot_functions (FALSE /* do_window_present */);
- if (interrupted)
+ if G_UNLIKELY (interrupted)
return NULL;
else
return gel_makenum_null ();
}
static gboolean
-get_line_numbers (GelETree *a, double **x, double **y, int *len)
+update_lineplot_window (double x1, double x2, double y1, double y2)
+{
+ if G_UNLIKELY (x1 > x2) {
+ double s = x1;
+ x1 = x2;
+ x2 = s;
+ }
+
+ if G_UNLIKELY (y1 > y2) {
+ double s = y1;
+ y1 = y2;
+ y2 = s;
+ }
+
+ reset_plotx1 = defx1 = x1;
+ reset_plotx2 = defx2 = x2;
+ reset_ploty1 = defy1 = y1;
+ reset_ploty2 = defy2 = y2;
+
+ if (plotx1 == x1 &&
+ plotx2 == x2 &&
+ ploty1 == y1 &&
+ ploty2 == y2)
+ return FALSE;
+
+ plotx1 = x1;
+ plotx2 = x2;
+ ploty1 = y1;
+ ploty2 = y2;
+
+ return TRUE;
+}
+
+
+
+static gboolean
+get_line_numbers (GelETree *a, double **x, double **y, int *len,
+ double *minx, double *maxx, double *miny, double *maxy)
{
int i;
GelMatrixW *m;
+ gboolean nominmax = TRUE;
+#define UPDATE_MINMAX \
+ if (minx != NULL) { \
+ if (xx > *maxx || nominmax) *maxx = xx; \
+ if (xx < *minx || nominmax) *minx = xx; \
+ if (yy > *maxy || nominmax) *maxy = yy; \
+ if (yy < *miny || nominmax) *miny = yy; \
+ nominmax = FALSE; \
+ }
g_return_val_if_fail (a->type == MATRIX_NODE, FALSE);
m = a->mat.matrix;
- if ( ! gel_is_matrix_value_only_real (m)) {
+ if G_UNLIKELY ( ! gel_is_matrix_value_only_real (m)) {
gel_errorout (_("%s: Line should be given as a real, n by 2 matrix "
"with columns for x and y, n>=2"),
"LinePlotDrawLine");
@@ -5893,10 +6015,12 @@
*y = g_new (double, *len);
for (i = 0; i < *len; i++) {
+ double xx, yy;
GelETree *t = gel_matrixw_index (m, 0, i);
- (*x)[i] = mpw_get_double (t->val.value);
+ (*x)[i] = xx = mpw_get_double (t->val.value);
t = gel_matrixw_index (m, 1, i);
- (*y)[i] = mpw_get_double (t->val.value);
+ (*y)[i] = yy = mpw_get_double (t->val.value);
+ UPDATE_MINMAX
}
} else if (gel_matrixw_width (m) == 1 &&
gel_matrixw_height (m) % 2 == 0 &&
@@ -5907,10 +6031,12 @@
*y = g_new (double, *len);
for (i = 0; i < *len; i++) {
+ double xx, yy;
GelETree *t = gel_matrixw_index (m, 0, 2*i);
- (*x)[i] = mpw_get_double (t->val.value);
+ (*x)[i] = xx = mpw_get_double (t->val.value);
t = gel_matrixw_index (m, 0, (2*i) + 1);
- (*y)[i] = mpw_get_double (t->val.value);
+ (*y)[i] = yy = mpw_get_double (t->val.value);
+ UPDATE_MINMAX
}
} else if (gel_matrixw_height (m) == 1 &&
gel_matrixw_width (m) % 2 == 0 &&
@@ -5921,10 +6047,12 @@
*y = g_new (double, *len);
for (i = 0; i < *len; i++) {
+ double xx, yy;
GelETree *t = gel_matrixw_index (m, 2*i, 0);
- (*x)[i] = mpw_get_double (t->val.value);
+ (*x)[i] = xx = mpw_get_double (t->val.value);
t = gel_matrixw_index (m, (2*i) + 1, 0);
- (*y)[i] = mpw_get_double (t->val.value);
+ (*y)[i] = yy = mpw_get_double (t->val.value);
+ UPDATE_MINMAX
}
} else {
gel_errorout (_("%s: Line should be given as a real, n by 2 matrix "
@@ -5934,8 +6062,46 @@
}
return TRUE;
+#undef UPDATE_MINMAX
}
+static void
+draw_arrowhead (double xx1, double yy1, double xx2, double yy2,
+ int thickness, GdkColor *color)
+{
+ double x1, x2, y1, y2, xm, ym;
+ double *ax, *ay;
+ double angle;
+
+ /* nowhere to go */
+ if (xx1 == xx2 && yy1 == yy2)
+ return;
+
+
+ gtk_plot_get_pixel (GTK_PLOT (line_plot), xx1, yy1, &x1, &y1);
+ gtk_plot_get_pixel (GTK_PLOT (line_plot), xx2, yy2, &x2, &y2);
+
+ angle = atan2 ( (y2-y1) , (x2-x1) );
+
+ ax = g_new (double, 3);
+ ay = g_new (double, 3);
+ ax[1] = xx2;
+ ay[1] = yy2;
+
+ xm = x2 - cos(angle) * /*al*/ 5* thickness;
+ ym = y2 - sin(angle) * /*al*/ 5* thickness;
+ gtk_plot_get_point (GTK_PLOT (line_plot),
+ xm - sin(angle)* /*aw*/5* thickness / 2.0,
+ ym + cos(angle)* /*aw*/5* thickness / 2.0,
+ & (ax[0]), & (ay[0]));
+ gtk_plot_get_point (GTK_PLOT (line_plot),
+ xm + sin(angle)* /*aw*/5* thickness / 2.0,
+ ym - cos(angle)* /*aw*/5* thickness / 2.0,
+ & (ax[2]), & (ay[2]));
+
+ draw_line (ax, ay, 3, thickness, color);
+}
+
static GelETree *
LinePlotDrawLine_op (GelCtx *ctx, GelETree * * a, int *exception)
@@ -5943,27 +6109,26 @@
int len;
int nextarg;
double *x, *y;
+ double minx = 0, miny = 0, maxx = 0, maxy = 0;
GdkColor color;
int thickness;
+ gboolean arrow_origin = FALSE;
+ gboolean arrow_end = FALSE;
int i;
+ gboolean update = FALSE;
- 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 ();
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "LinePlotDrawLine", "LinePlotDrawLine");
+ return NULL;
}
+ ensure_window (FALSE /* do_window_present */);
+
if (a[0]->type == MATRIX_NODE) {
- if ( ! get_line_numbers (a[0], &x, &y, &len))
- return FALSE;
+ if G_UNLIKELY ( ! get_line_numbers (a[0], &x, &y, &len,
+ &minx, &maxx, &miny, &maxy))
+ return NULL;
nextarg = 1;
} else {
double x1, y1, x2, y2;
@@ -5984,6 +6149,11 @@
y[0] = y1;
y[1] = y2;
nextarg = 4;
+
+ minx = MIN(x1,x2);
+ maxx = MAX(x1,x2);
+ miny = MIN(y1,y2);
+ maxy = MAX(y1,y2);
}
gdk_color_parse ("black", &color);
@@ -5995,10 +6165,24 @@
GelToken *id;
static GelToken *colorid = NULL;
static GelToken *thicknessid = NULL;
+ static GelToken *windowid = NULL;
+ static GelToken *fitid = NULL;
+ static GelToken *arrowid = NULL;
+ static GelToken *originid = NULL;
+ static GelToken *endid = NULL;
+ static GelToken *bothid = NULL;
+ static GelToken *noneid = NULL;
if (colorid == NULL) {
colorid = d_intern ("color");
thicknessid = d_intern ("thickness");
+ windowid = d_intern ("window");
+ fitid = d_intern ("fit");
+ arrowid = d_intern ("arrow");
+ originid = d_intern ("origin");
+ endid = d_intern ("end");
+ bothid = d_intern ("both");
+ noneid = d_intern ("none");
}
if (a[i]->type == STRING_NODE)
@@ -6043,13 +6227,95 @@
thickness = gel_get_nonnegative_integer (a[i+1]->val.value,
"LinePlotDrawLine");
i++;
+ } else if (id == windowid) {
+ double x1, x2, y1, y2;
+ if G_UNLIKELY (a[i+1] == NULL ||
+ (a[i+1]->type != STRING_NODE &&
+ a[i+1]->type != IDENTIFIER_NODE &&
+ a[i+1]->type != MATRIX_NODE)) {
+ gel_errorout (_("%s: No window specified"),
+ "LinePlotDrawLine");
+ g_free (x);
+ g_free (y);
+ return NULL;
+ }
+ if ((a[i+1]->type == STRING_NODE &&
+ fitid == d_intern (a[i+1]->str.str)) ||
+ (a[i+1]->type == IDENTIFIER_NODE &&
+ fitid == a[i+1]->id.id)) {
+ x1 = minx;
+ x2 = maxx;
+ y1 = miny;
+ y2 = maxy;
+ if G_UNLIKELY (x1 == x2) {
+ x1 -= 0.1;
+ x2 += 0.1;
+ }
+
+ /* assume line is a graph so x fits tightly */
+
+ if G_UNLIKELY (y1 == y2) {
+ y1 -= 0.1;
+ y2 += 0.1;
+ } else {
+ /* Make window 5% larger on each vertical side */
+ double height = (y2-y1);
+ y1 -= height * 0.05;
+ y2 += height * 0.05;
+ }
+
+ update = update_lineplot_window (x1, x2, y1, y2);
+ } else if (get_limits_from_matrix (a[i+1], &x1, &x2, &y1, &y2)) {
+ update = update_lineplot_window (x1, x2, y1, y2);
+ } else {
+ g_free (x);
+ g_free (y);
+ return NULL;
+ }
+ i++;
+ } else if (id == arrowid) {
+ GelToken *astyleid;
+
+ if G_UNLIKELY (a[i+1] == NULL ||
+ (a[i+1]->type != STRING_NODE &&
+ a[i+1]->type != IDENTIFIER_NODE)) {
+ gel_errorout (_("%s: arrow style should be \"origin\", \"end\", \"both\", or \"none\""),
+ "LinePlotDrawLine");
+ g_free (x);
+ g_free (y);
+ return NULL;
+ }
+ if (a[i+1]->type == STRING_NODE)
+ astyleid = d_intern (a[i+1]->str.str);
+ else
+ astyleid = a[i+1]->id.id;
+
+ if (astyleid == originid) {
+ arrow_origin = TRUE;
+ arrow_end = FALSE;
+ } else if (astyleid == endid) {
+ arrow_origin = FALSE;
+ arrow_end = TRUE;
+ } else if (astyleid == bothid) {
+ arrow_origin = TRUE;
+ arrow_end = TRUE;
+ } else if (astyleid == noneid) {
+ arrow_origin = FALSE;
+ arrow_end = FALSE;
+ } else {
+ gel_errorout (_("%s: arrow style should be \"origin\", \"end\", \"both\", or \"none\""),
+ "LinePlotDrawLine");
+ g_free (x);
+ g_free (y);
+ return NULL;
+ }
+ i++;
} else {
gel_errorout (_("%s: Unknown style"), "LinePlotDrawLine");
g_free (x);
g_free (y);
return NULL;
}
-
} else {
gel_errorout (_("%s: Bad parameter"), "LinePlotDrawLine");
g_free (x);
@@ -6058,8 +6324,37 @@
}
}
+ 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 ();
+ update = FALSE;
+ }
+
+
+ if (line_plot == NULL) {
+ add_line_plot ();
+ plot_setup_axis ();
+ update = FALSE;
+ }
+
+ if (update) {
+ plot_axis ();
+ }
+
draw_line (x, y, len, thickness, &color);
+ if (arrow_end && len > 1)
+ draw_arrowhead (x[len-2], y[len-2],
+ x[len-1], y[len-1],
+ thickness, &color);
+ if (arrow_origin && len > 1)
+ draw_arrowhead (x[1], y[1],
+ x[0], y[0],
+ thickness, &color);
+
return gel_makenum_null ();
}
@@ -6067,13 +6362,21 @@
set_LinePlotWindow (GelETree * a)
{
double x1, x2, y1, y2;
- if ( ! get_limits_from_matrix (a, &x1, &x2, &y1, &y2))
+
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "set_LinePlotWindow", "set_LinePlotWindow");
+ return NULL;
+ }
+
+
+ if G_UNLIKELY ( ! get_limits_from_matrix (a, &x1, &x2, &y1, &y2))
return NULL;
- reset_plotx1 = plotx1 = defx1 = x1;
- reset_plotx2 = plotx2 = defx2 = x2;
- reset_ploty1 = ploty1 = defy1 = y1;
- reset_ploty2 = ploty2 = defy2 = y2;
+ if (update_lineplot_window (x1, x2, y1, y2)) {
+ if (line_plot != NULL)
+ plot_axis ();
+ }
return make_matrix_from_limits ();
}
@@ -6088,15 +6391,54 @@
set_SurfacePlotWindow (GelETree * a)
{
double x1, x2, y1, y2, z1, z2;
- if ( ! get_limits_from_matrix_surf (a, &x1, &x2, &y1, &y2, &z1, &z2))
+ gboolean update = FALSE;
+
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "set_SurfacePlotWindow", "set_SurfacePlotWindow");
+ return NULL;
+ }
+
+ if G_UNLIKELY ( ! get_limits_from_matrix_surf (a, &x1, &x2, &y1, &y2, &z1, &z2))
return NULL;
- surf_defx1 = x1;
- surf_defx2 = x2;
- surf_defy1 = y1;
- surf_defy2 = y2;
- surf_defz1 = z1;
- surf_defz2 = z2;
+ if G_UNLIKELY (x1 > x2) {
+ double s = x1;
+ x1 = x2;
+ x2 = s;
+ }
+
+ if G_UNLIKELY (y1 > y2) {
+ double s = y1;
+ y1 = y2;
+ y2 = s;
+ }
+
+ if G_UNLIKELY (z1 > z2) {
+ double s = z1;
+ z1 = z2;
+ z2 = s;
+ }
+
+
+ if (surfacex1 != x1 ||
+ surfacex2 != x2 ||
+ surfacey1 != y1 ||
+ surfacey2 != y2 ||
+ surfacez1 != z1 ||
+ surfacez2 != z2)
+ update = TRUE;
+
+ reset_surfacex1 = surfacex1 = surf_defx1 = x1;
+ reset_surfacex2 = surfacex2 = surf_defx2 = x2;
+ reset_surfacey1 = surfacey1 = surf_defy1 = y1;
+ reset_surfacey2 = surfacey2 = surf_defy2 = y2;
+ reset_surfacez1 = surfacez1 = surf_defz1 = z1;
+ reset_surfacez2 = surfacez2 = surf_defz2 = z2;
+
+ if (update && surface_plot != NULL) {
+ plot_axis ();
+ }
return make_matrix_from_limits_surf ();
}
@@ -6110,6 +6452,12 @@
static GelETree *
set_VectorfieldNormalized (GelETree * a)
{
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "set_VectorfieldNormalized", "set_VectorfieldNormalized");
+ return NULL;
+ }
+
if G_UNLIKELY ( ! check_argument_bool (&a, 0, "set_VectorfieldNormalized"))
return NULL;
if (a->type == VALUE_NODE)
@@ -6129,6 +6477,11 @@
static GelETree *
set_LinePlotDrawLegends (GelETree * a)
{
+ if G_UNLIKELY (plot_in_progress != 0) {
+ gel_errorout (_("%s: Plotting in progress, cannot call %s"),
+ "set_LinePlotDrawLegends", "set_LinePlotDrawLegends");
+ return NULL;
+ }
if G_UNLIKELY ( ! check_argument_bool (&a, 0, "set_LinePlotDrawLegend"))
return NULL;
if (a->type == VALUE_NODE)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]