command 'clip':

Clip a vector between the two scale values xmin and xmax.
Store the pointer to the original vector in v_unclipped.
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.
Prevent clipping if variable gridsize is set or vector is scale.
This commit is contained in:
h_vogt 2017-05-01 11:25:41 +02:00
parent 430a49b21e
commit 46b9e65e53
2 changed files with 46 additions and 19 deletions

View File

@ -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)))

View File

@ -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;