yphysToYscreen method
Converts physical y coordinate to screen y coordinate, which is returned relative to the data area. Formula: see .odt document in specpad source tree in the folder "manuals". have the type of PhysicalToScreen.
Implementation
double yphysToYscreen(double y) {
double yscreen;
int he = effectivePolylineHeight;
if (zoomRegion != null) {
double a2, b2;
if ((zoomRegion.ybottom - zoomRegion.ytop).abs() < 0.000001) {
a2 = 1.0; // TODO right?
b2 = -he / 2;
// yscale = 1.0; // ori
} else {
a2 = -he / (zoomRegion.ybottom - zoomRegion.ytop);
b2 = insety + a2 * zoomRegion.ytop; // ori
}
yscale = 1.0;
yshift1 = 0;
attr[PyA.YSHIFT1] = "0";
attr[PyA.YSCALE] = "1.0";
// double yzero = double.parse(attributes[PyA.YPOSITION_ZERO]);
// yzero = yzero - b2/effectivePolylineHeight;
// attributes[PyA.YPOSITION_ZERO] = "${yzero}";
// yscreen = -a2*y*yscale + b2; //ori
// b2=yzero*effectivePolylineHeight+insety;
yscreen = -a2 * y + b2;
// int hr = zoomRegion.ysbottom - zoomRegion.ystop;
// a = (hr/he) * a2;
// b = (hr/he)*(b2 - insety) + zoomRegion.ystop;
a = a2;
b = b2; // ori
// a = a2*yscale; b = b2;
} else {
// screen position of polyline value 0 point in % of effective view height: 0.5 means centered.
double ysLeft = double.parse(attr[PyA.YPOSITION_ZERO]); // orig
double yix1 = double.parse(attr[PyA.YIX1]);
double ys1, ys2, yix2;
// yscale is the accumulated user interactive mouse wheel scaling factor
// the next line ensures that "a", which is proportional to (c1-c2), does not change sign.
// Otherwise, after turning the mouse wheel too much, the spectrum would change sign and
// would be drawn upside down.
double c1 = ysLeft; // e.g.0.9 for spectra, 0.5 for fids
// c2 = 0 means ymax will be displayed at "insety":
double c2 = POLYLINE_INITIAL_YSCALE - yscale;
// ensure ys will not become 0 or even change sign when yscale too large:
if (c2 > c1) {
c2 = c1 - 0.01;
}
ys1 = c1 * he + insety; // screen pos. of leftmost point in region
ys2 = c2 * he + insety; // screen pos. of ymax in region
// This code defines that PyA.YPOSITION_ZERO is the rel. y position
// of the point y=0 of the data. One could also set yix1 = yValues[0] or
// yix1 = yValues[ixFirst] or ... (see PyA.YIX1)
// to define another point to take on PyA.YPOSITION_ZERO.
// The current solution works best for spectra, fids.
if (ymin < 0 && ymax < 0) {
// spectra with only negative values need special treatment for correct
// display: must invert all y values before computing screen coord.
y = -y;
double temp = -ymax;
ymax = -ymin;
ymin = temp;
yix1 = 0.0; // phys. y of ys1 (could be different for diff. y offset)
yix2 = ymax; // phys. y of ys2
} else {
// "normal" spectra with mixed positive and negative y values
yix1 = 0.0; // phys. y of ys1
yix2 = ymax; // phys. y of ys2
}
if ((yix2 - yix1).abs() < 0.000001 && y * yscale.abs() < 0.000001) {
// y == ymax, treat singular case for y = 0
a = 0.0; // TODO
} else if ((yix2 - yix1).abs() < 0.000001) {
// y == ymax, treat remaining singular case for y != 0
a = 0.0; // TODO
} else {
a = -(ys2 - ys1) / (yix2 - yix1);
}
b = ys1 + a * yix1 + yshift1 + yshift2;
yscreen = -a * y + b;
}
try {
yscreen.round(); // test, except, if failed
return yscreen;
} catch (e) {
// e.g. when zooming a data set containing only zeroes
return dataAreaHeight / 2;
}
}