diff --git a/src/frontend/plotting/plotcurv.c b/src/frontend/plotting/plotcurv.c index 2c274923a..0dd0bf616 100644 --- a/src/frontend/plotting/plotcurv.c +++ b/src/frontend/plotting/plotcurv.c @@ -63,6 +63,11 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart) return; } + if (gridsize && v->v_unclipped) { + fprintf(cp_err, "Error: cannot interpolate clipped vector %s\n", v->v_name); + return; + } + if (gridsize && xs) { if (isreal(xs)) { increasing = (xs->v_realdata[0] < xs->v_realdata[1]); @@ -137,16 +142,17 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart) realpart(xs->v_compdata[i]); dy = isreal(v) ? v->v_realdata[i] : realpart(v->v_compdata[i]); - /* check for NAN */ - if (isnan(dy)) { - lx = dx; - ly = dy; - continue; - } - else if (!isnan(dy) && isnan(ly)) { - lx = dx; - ly = dy; - } + /* check for NAN, used in clipping */ + if(v->v_unclipped) + if (isnan(dy)) { + lx = dx; + ly = dy; + continue; + } + else if (!isnan(dy) && isnan(ly)) { + lx = dx; + ly = dy; + } /* end of check */ if ((i == 0 || (dir > 0 ? lx > dx : dir < 0 ? lx < dx : 0)) && (mono || (xs->v_plot && xs->v_plot->pl_scale == xs))) diff --git a/src/frontend/vectors.c b/src/frontend/vectors.c index cf698d5cc..a50311705 100644 --- a/src/frontend/vectors.c +++ b/src/frontend/vectors.c @@ -1153,32 +1153,53 @@ plot_prefix(char *pre, char *str) return (TRUE); } -/* Clip a vector between the two scale values xmin and xmax, +/* Clip a vector between the two scale values xmin and xmax. Store the pointer to the original vector in v_unclipped. -Set all data outside xmin and xmax will be set to NAN */ +Set all vector data outside xmin and xmax to NAN. +If 'clip vecname 0 0' is given, restore previous vector. +If clipping an already clipped vector, restore it before clipping again. */ bool vec_clip(char* vecname, double xmin, double xmax) { + /* Check for scale vector */ + if (cieq(plot_cur->pl_scale->v_name, vecname)) { + fprintf(stderr, "Warning: Scale vector %s cannot be clipped!\n", vecname); + return FALSE; + } + + struct dvec *oldvec = vec_fromplot(vecname, plot_cur); + bool onlyrestore = (xmax == 0 && xmin == 0); + + /* Check for curve-fitting, only allow 'clip vecname 0 0' to unclip vector */ + int gridsize; + if (cp_getvar("gridsize", CP_NUM, &gridsize) && !(oldvec->v_unclipped) && !onlyrestore) { + fprintf(stderr, "Warning: Cannot clip a vector, if curve-fitting with variable 'gridsize' is used!\n"); + return FALSE; + } + + /* check for xmin and xmax */ if (xmax < xmin) { double tmp = xmin; xmin = xmax; xmax = tmp; } - else if (xmax == 0 && xmin == 0) { - /* Restore unclipped vector */ - struct dvec *curvec = vec_fromplot(vecname, plot_cur); - struct dvec *restorevec = curvec->v_unclipped; - vec_free_x(curvec); + else if ((oldvec->v_unclipped) && ((xmax != xmin) || onlyrestore)) { + /* If vector is already clipped, restore unclipped vector */ + struct dvec *restorevec = oldvec->v_unclipped; + vec_free_x(oldvec); vec_new(restorevec); - return TRUE; + oldvec = restorevec; + oldvec->v_unclipped = NULL; /* should be NULL anyway */ + /* Just exit function after restoring previous vector, if command 'clip vecname 0 0' is given. */ + if (onlyrestore) + return TRUE; } else if (xmax == xmin) { fprintf(stderr, "Warnig: Cannot clip vector %s\n", vecname); return FALSE; } /* Create new vector as copy within current plot */ - struct dvec *oldvec = vec_fromplot(vecname, plot_cur); struct dvec *newvec = vec_copy(oldvec); newvec->v_unclipped = oldvec;