float Lowpass::lengthen_quality( Streamline *st, float radius, int nsamples, float dist, Window2d *win, int &which_end ) { int i; float rad; float delta; float x,y; float sum1 = 0; float sum2 = 0; int count1 = 0; int count2 = 0; VectorField *vf = st->vf; //printf("got vector field\n"); /* kluge to work around problems at the image borders */ float xmin = 2.0 / xsize; float ymin = 2.0 / ysize; float xmax = 1 - 2.0 / xsize; float ymax = image->getaspect() - 2.0 / ysize; /* measure the quality as we move away from the streamline's tail */ x = st->pts[0].x; y = st->pts[0].y; rad = radius * rad_image->get_value(x,y) / xsize; delta = dist * rad / nsamples; for (i = 0; i < nsamples; i++) { /* don't go too near the borders */ if (x < xmin || x > xmax || y < ymin || y > ymax) break; /* measure the point's quality */ float value = image->get_value(x,y); // printf("value in intial %f\n",value); if (value < target) sum1 += Square (target - value); count1++; /* move further away from the endpoint */ x -= delta * vf->xval(x,y); y -= delta * vf->yval(x,y); } /* now measure from the head */ x = st->pts[st->samples - 1].x; y = st->pts[st->samples - 1].y; rad = radius * rad_image->get_value(x,y) / xsize; delta = dist * rad / nsamples; for (i = 0; i < nsamples; i++) { /* don't go too near the borders */ if (x < xmin || x > xmax || y < ymin || y > ymax) break; /* measure the point's quality */ float value = image->get_value(x,y); if (value < target) sum2 += Square (target - value); count2++; /* move further away from the endpoint */ x += delta * vf->xval(x,y); y += delta * vf->yval(x,y); } /* determine quality */ float qual = 0; if (count1 + count2 != 0) qual = (sum1 + sum2) / (count1 + count2); /* say which end needs change more */ if (count1) sum1 /= count1; if (count2) sum2 /= count2; if (sum1 > sum2) which_end = TAIL; else which_end = HEAD; //printf("lengthen quality over\n"); return (qual); }
float Lowpass::main_body_quality( Streamline *st, float radius, int nsamples, float dist, Window2d *win, int &which_side ) { int i; float rad; float delta; float x,y; float sum = 0; int count = 0; VectorField *vf = st->vf; /* kluge to work around problems at the image borders */ float xmin = 2.0 / xsize; float ymin = 2.0 / ysize; float xmax = 1 - 2.0 / xsize; float ymax = image->getaspect() - 2.0 / ysize; /* measure the quality at several random positions along the streamline */ for (i = 0; i < nsamples; i++) { int index = (int) (st->samples * drand48()); SamplePoint *sample = &st->pts[index]; x = sample->x; y = sample->y; /* don't measure near the borders */ if (x < xmin || x > xmax || y < ymin || y > ymax) continue; rad = radius * rad_image->get_value(x,y) / xsize; delta = 0.3 * rad / nsamples; /* find out how to move perpendicular to the vector field */ float dx = - delta * vf->yval(x,y); float dy = delta * vf->xval(x,y); /* sample along either side of the streamline */ float x1 = x + dx; float y1 = y + dy; float x2 = x - dx; float y2 = y - dy; /* measure the quality at the two points */ float value1 = image->get_value(x1,y1); float value2 = image->get_value(x2,y2); // printf("value1: %f, value2: %f\n",value1,value2); sum += value1 - value2; count++; } /* return quality */ if (count == 0) return (0.0); else { if (sum > 0) which_side = LEFT; else which_side = RIGHT; return (fabs (sum / count)); } }
float Lowpass::shorten_quality( Streamline *st, float radius, int nsamples, float dist, Window2d *win, int &which_end ) { int i; float rad; float delta; float x,y; float sum1 = 0; float sum2 = 0; int count1 = 0; int count2 = 0; VectorField *vf = st->vf; /* kluge to work around problems at the image borders */ float xmin = 2.0 / xsize; float ymin = 2.0 / ysize; float xmax = 1 - 2.0 / xsize; float ymax = image->getaspect() - 2.0 / ysize; /* measure the quality as we move into the body of the streamline */ /* from the tail endpoint */ x = st->pts[0].x; y = st->pts[0].y; rad = radius * rad_image->get_value(x,y) / xsize; delta = dist * rad / nsamples; for (i = 0; i < nsamples; i++) { /* don't measure near the borders */ if (x < xmin || x > xmax || y < ymin || y > ymax) continue; /* measure the point's quality */ float value = image->get_value(x,y); if (value > target) sum1 += Square (target - value); count1++; /* debug drawing of samples */ if (win) { win->set_color_index (255); win->line (x, y, x, y); } /* move further away from the endpoint */ x += delta * vf->xval(x,y); y += delta * vf->yval(x,y); } /* now measure from the head */ x = st->pts[st->samples - 1].x; y = st->pts[st->samples - 1].y; rad = radius * rad_image->get_value(x,y) / xsize; delta = dist * rad / nsamples; for (i = 0; i < nsamples; i++) { /* don't measure near the borders */ if (x < xmin || x > xmax || y < ymin || y > ymax) continue; /* measure the point's quality */ float value = image->get_value(x,y); if (value > target) sum2 += Square (target - value); count2++; /* debug drawing of samples */ if (win) { win->set_color_index (255); win->line (x, y, x, y); } /* move further away from the endpoint */ x -= delta * vf->xval(x,y); y -= delta * vf->yval(x,y); } /* determine quality */ float qual = 0; if (count1 + count2 != 0) qual = (sum1 + sum2) / (count1 + count2); /* say which end needs change more */ if (count1) sum1 /= count1; if (count2) sum2 /= count2; if (sum1 > sum2) which_end = TAIL; else which_end = HEAD; return (qual); }