Commit 93ee56f1 authored by Jiri (George) Lebl's avatar Jiri (George) Lebl Committed by George Lebl

slopefield works from GUI in a very rudimentary way


Fri Nov 14 00:29:17 2008  Jiri (George) Lebl <jirka@5z.com>

	* src/graphing.c: slopefield works from GUI in a very rudimentary way


svn path=/trunk/; revision=691
parent 7dff9299
Fri Nov 14 00:29:17 2008 Jiri (George) Lebl <jirka@5z.com>
* src/graphing.c: slopefield works from GUI in a very rudimentary way
Sun Nov 09 23:33:04 2008 Jiri (George) Lebl <jirka@5z.com> Sun Nov 09 23:33:04 2008 Jiri (George) Lebl <jirka@5z.com>
* src/graphing.c: another step forwards towards implementation of * src/graphing.c: another step forwards towards implementation of
......
...@@ -82,6 +82,8 @@ static GtkWidget *line_plot = NULL; ...@@ -82,6 +82,8 @@ static GtkWidget *line_plot = NULL;
static GtkPlotData *line_data[MAXFUNC] = { NULL }; static GtkPlotData *line_data[MAXFUNC] = { NULL };
static GtkPlotData *parametric_data = NULL; static GtkPlotData *parametric_data = NULL;
static GtkPlotData *slopefield_data = NULL;
static GtkPlotData *vectorfield_data = NULL;
static GtkWidget *plot_entries[MAXFUNC] = { NULL }; static GtkWidget *plot_entries[MAXFUNC] = { NULL };
static GtkWidget *plot_entries_status[MAXFUNC] = { NULL }; static GtkWidget *plot_entries_status[MAXFUNC] = { NULL };
...@@ -148,6 +150,14 @@ static double plottinc = 0.01; ...@@ -148,6 +150,14 @@ static double plottinc = 0.01;
static int plotVtick = 10; static int plotVtick = 10;
static int plotHtick = 10; static int plotHtick = 10;
static double *plot_points_x = NULL;
static double *plot_points_y = NULL;
static double *plot_points_dx = NULL;
static double *plot_points_dy = NULL;
static int plot_points_num = 0;
/* /*
Surface Surface
*/ */
...@@ -1423,6 +1433,10 @@ clear_graph (void) ...@@ -1423,6 +1433,10 @@ clear_graph (void)
parametric_data = NULL; parametric_data = NULL;
slopefield_data = NULL;
vectorfield_data = NULL;
surface_data = NULL; surface_data = NULL;
} }
...@@ -1923,59 +1937,70 @@ plot_func_data (GtkPlot *plot, GtkPlotData *data, double x, gboolean *error) ...@@ -1923,59 +1937,70 @@ plot_func_data (GtkPlot *plot, GtkPlotData *data, double x, gboolean *error)
} }
static double static double
surface_func_data (GtkPlot *plot, GtkPlotData *data, double x, double y, gboolean *error) call_xy_or_z_function (GelEFunc *f, double x, double y, gboolean *ex)
{ {
static int hookrun = 0;
gboolean ex = FALSE;
double z, size;
GelETree *func_ret = NULL; GelETree *func_ret = NULL;
double z;
if (error != NULL)
*error = FALSE;
if G_UNLIKELY (interrupted) {
if (error != NULL)
*error = TRUE;
return 0.0;
}
/* complex function */ /* complex function */
if (surface_func->nargs == 1) { if (f->nargs == 1) {
mpw_set_d_complex (plot_arg->val.value, x, y); mpw_set_d_complex (plot_arg->val.value, x, y);
z = call_func (plot_ctx, surface_func, plot_arg, &ex, z = call_func (plot_ctx, f, plot_arg, ex,
&func_ret); &func_ret);
} else if (surface_func->nargs == 2) { } else if (f->nargs == 2) {
mpw_set_d (plot_arg->val.value, x); mpw_set_d (plot_arg->val.value, x);
mpw_set_d (plot_arg2->val.value, y); mpw_set_d (plot_arg2->val.value, y);
z = call_func2 (plot_ctx, surface_func, plot_arg, plot_arg2, z = call_func2 (plot_ctx, f, plot_arg, plot_arg2,
&ex, &func_ret); ex, &func_ret);
} else { } else {
mpw_set_d (plot_arg->val.value, x); mpw_set_d (plot_arg->val.value, x);
mpw_set_d (plot_arg2->val.value, y); mpw_set_d (plot_arg2->val.value, y);
mpw_set_d_complex (plot_arg3->val.value, x, y); mpw_set_d_complex (plot_arg3->val.value, x, y);
z = call_func3 (plot_ctx, surface_func, plot_arg, plot_arg2, z = call_func3 (plot_ctx, f, plot_arg, plot_arg2,
plot_arg3, &ex, &func_ret); plot_arg3, ex, &func_ret);
} }
if (func_ret != NULL) { if (func_ret != NULL) {
/* complex function */ /* complex function */
if (func_ret->func.func->nargs == 1) { if (func_ret->func.func->nargs == 1) {
mpw_set_d_complex (plot_arg->val.value, x, y); mpw_set_d_complex (plot_arg->val.value, x, y);
z = call_func (plot_ctx, func_ret->func.func, plot_arg, &ex, z = call_func (plot_ctx, func_ret->func.func, plot_arg, ex,
NULL); NULL);
} else if (func_ret->func.func->nargs == 2) { } else if (func_ret->func.func->nargs == 2) {
mpw_set_d (plot_arg->val.value, x); mpw_set_d (plot_arg->val.value, x);
mpw_set_d (plot_arg2->val.value, y); mpw_set_d (plot_arg2->val.value, y);
z = call_func2 (plot_ctx, func_ret->func.func, plot_arg, plot_arg2, z = call_func2 (plot_ctx, func_ret->func.func, plot_arg, plot_arg2,
&ex, NULL); ex, NULL);
} else { } else {
mpw_set_d (plot_arg->val.value, x); mpw_set_d (plot_arg->val.value, x);
mpw_set_d (plot_arg2->val.value, y); mpw_set_d (plot_arg2->val.value, y);
mpw_set_d_complex (plot_arg3->val.value, x, y); mpw_set_d_complex (plot_arg3->val.value, x, y);
z = call_func3 (plot_ctx, func_ret->func.func, plot_arg, plot_arg2, z = call_func3 (plot_ctx, func_ret->func.func, plot_arg, plot_arg2,
plot_arg3, &ex, NULL); plot_arg3, ex, NULL);
} }
} }
return z;
}
static double
surface_func_data (GtkPlot *plot, GtkPlotData *data, double x, double y, gboolean *error)
{
static int hookrun = 0;
gboolean ex = FALSE;
double z, size;
if (error != NULL)
*error = FALSE;
if G_UNLIKELY (interrupted) {
if (error != NULL)
*error = TRUE;
return 0.0;
}
z = call_xy_or_z_function (surface_func, x, y, &ex);
if G_UNLIKELY (ex) { if G_UNLIKELY (ex) {
if (error != NULL) if (error != NULL)
*error = TRUE; *error = TRUE;
...@@ -2009,6 +2034,54 @@ surface_func_data (GtkPlot *plot, GtkPlotData *data, double x, double y, gboolea ...@@ -2009,6 +2034,54 @@ surface_func_data (GtkPlot *plot, GtkPlotData *data, double x, double y, gboolea
return z; return z;
} }
static void
get_slopefield_points (void)
{
double x, y, vt, ht, z, mt, dx, dy;
int i, j, k;
gboolean ex;
ht = (plotx2 - plotx1) / plotHtick;
vt = (ploty2 - ploty1) / plotVtick;
mt = MIN (ht, vt) / 2;
g_free (plot_points_x);
g_free (plot_points_y);
g_free (plot_points_dx);
g_free (plot_points_dy);
plot_points_x = g_new (double, (plotHtick+1)*(plotVtick+1));
plot_points_y = g_new (double, (plotHtick+1)*(plotVtick+1));
plot_points_dx = g_new (double, (plotHtick+1)*(plotVtick+1));
plot_points_dy = g_new (double, (plotHtick+1)*(plotVtick+1));
k = 0;
for (i = 0; i <= plotHtick; i++) {
for (j = 0; j <= plotVtick; j++) {
x = plotx1 + ht*i;
y = ploty1 + vt*j;
ex = FALSE;
z = call_xy_or_z_function (slopefield_func,
x, y, &ex);
if G_LIKELY ( ! ex) {
dx = 1 / sqrt(z*z +1);
dy = z*dx;
plot_points_x[k] = x;//-dx/2;
plot_points_dx[k] = dx;
plot_points_y[k] = y;//-dy/2;
plot_points_dy[k] = dy;
k++;
}
}
}
plot_points_num = k;
}
static char * static char *
label_func (int i, GelEFunc *func, const char *var, const char *name) label_func (int i, GelEFunc *func, const char *var, const char *name)
{ {
...@@ -2299,6 +2372,25 @@ parametric_get_value (double *x, double *y, double t) ...@@ -2299,6 +2372,25 @@ parametric_get_value (double *x, double *y, double t)
return TRUE; return TRUE;
} }
static void
init_plot_ctx (void)
{
if G_UNLIKELY (plot_ctx == NULL) {
mpw_t xx;
plot_ctx = eval_get_context ();
mpw_init (xx);
plot_arg = gel_makenum_use (xx);
mpw_init (xx);
plot_arg2 = gel_makenum_use (xx);
mpw_init (xx);
plot_arg3 = gel_makenum_use (xx);
}
}
static void static void
plot_functions (void) plot_functions (void)
{ {
...@@ -2360,14 +2452,7 @@ plot_functions (void) ...@@ -2360,14 +2452,7 @@ plot_functions (void)
plot_setup_axis (); plot_setup_axis ();
if G_UNLIKELY (plot_arg == NULL) { init_plot_ctx ();
plot_ctx = eval_get_context ();
}
if G_UNLIKELY (plot_arg == NULL) {
mpw_t xx;
mpw_init (xx);
plot_arg = gel_makenum_use (xx);
}
color_i = 0; color_i = 0;
...@@ -2429,6 +2514,7 @@ plot_functions (void) ...@@ -2429,6 +2514,7 @@ plot_functions (void)
/* how many actually went */ /* how many actually went */
len = MAX(1,i); len = MAX(1,i);
/* FIXME: LEAK! */
gtk_plot_data_set_points (parametric_data, x, y, dx, dy, len); gtk_plot_data_set_points (parametric_data, x, y, dx, dy, len);
gtk_plot_add_data (GTK_PLOT (line_plot), parametric_data); gtk_plot_add_data (GTK_PLOT (line_plot), parametric_data);
...@@ -2454,6 +2540,39 @@ plot_functions (void) ...@@ -2454,6 +2540,39 @@ plot_functions (void)
} }
gtk_plot_data_set_legend (parametric_data, label); gtk_plot_data_set_legend (parametric_data, label);
g_free (label); g_free (label);
}
if (slopefield_func != NULL) {
get_slopefield_points ();
if (plot_points_num > 0) {
GdkColor color;
double vt, ht, mt;
ht = (plotx2 - plotx1) / plotHtick;
vt = (ploty2 - ploty1) / plotVtick;
mt = MIN (ht, vt) / 2;
slopefield_data = GTK_PLOT_DATA(gtk_plot_flux_new());
gtk_plot_add_data (GTK_PLOT (line_plot),
slopefield_data);
gdk_color_parse ("blue", &color);
gtk_plot_data_set_line_attributes (slopefield_data,
GTK_PLOT_LINE_NONE,
0, 0, 1, &color);
/* FIXME: */
gtk_plot_flux_set_size_max (GTK_PLOT_FLUX (slopefield_data), 10);
gtk_plot_flux_set_scale_max (GTK_PLOT_FLUX (slopefield_data), 0.5);
gtk_plot_flux_set_arrow (GTK_PLOT_FLUX (slopefield_data),
0, 0, GTK_PLOT_SYMBOL_NONE);
gtk_widget_show (GTK_WIDGET (slopefield_data));
gtk_plot_data_set_points (slopefield_data,
plot_points_x,
plot_points_y,
plot_points_dx,
plot_points_dy,
plot_points_num);
}
} }
/* FIXME : slopefield / vectorfield */ /* FIXME : slopefield / vectorfield */
...@@ -2512,24 +2631,7 @@ plot_surface_functions (void) ...@@ -2512,24 +2631,7 @@ plot_surface_functions (void)
gtk_plot3d_rotate_x (GTK_PLOT3D (surface_plot), 60.0); gtk_plot3d_rotate_x (GTK_PLOT3D (surface_plot), 60.0);
gtk_plot3d_rotate_z (GTK_PLOT3D (surface_plot), 30.0); gtk_plot3d_rotate_z (GTK_PLOT3D (surface_plot), 30.0);
if G_UNLIKELY (plot_arg == NULL) { init_plot_ctx ();
plot_ctx = eval_get_context ();
}
if G_UNLIKELY (plot_arg == NULL) {
mpw_t xx;
mpw_init (xx);
plot_arg = gel_makenum_use (xx);
}
if G_UNLIKELY (plot_arg2 == NULL) {
mpw_t xx;
mpw_init (xx);
plot_arg2 = gel_makenum_use (xx);
}
if G_UNLIKELY (plot_arg3 == NULL) {
mpw_t xx;
mpw_init (xx);
plot_arg3 = gel_makenum_use (xx);
}
if (surface_func != NULL) { if (surface_func != NULL) {
char *label; char *label;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment