/** * This returns a blacker color than c. * * @param color * @return a blacker color than c */ public static Color blacker(Color color) { int r = color.getRed(); int g = color.getGreen(); int b = color.getBlue(); return new Color( Math.max(0, r - (255 - r) / 4), // little changes close to 255 have big effect Math.max(0, g - (255 - g) / 4), Math.max(0, b - (255 - b) / 4)); }
/** * This is used to convert an image'x x,y location into lonLat values. * * @param x x pixel of user click on image * @param y y pixel of user click on image * @param intWESN is the WESN of the graph on the image. Note that S will be numerically greater * than N. * @param doubleWESN is the lon lat WESN of the graph on the image * @param extentWESN is the maximum extent allowed (so center not shifted too far) * @return double[2] 0=lon 1=lat. or null if trouble (e.g., intWESN is null) */ public static double[] xyToLonLat( int x, int y, int[] intWESN, double[] doubleWESN, double[] extentWESN) { if (intWESN == null || doubleWESN == null || intWESN[0] >= intWESN[1] || intWESN[2] <= intWESN[3]) return null; double xRange = doubleWESN[1] - doubleWESN[0]; double yRange = doubleWESN[3] - doubleWESN[2]; double newX, newY; if (x < intWESN[0] || x > intWESN[1]) { // a click outside of graph shifts center to (theoretical) adjacent panel newX = x < intWESN[0] ? doubleWESN[0] - xRange / 2 : doubleWESN[1] + xRange / 2; newY = y < intWESN[3] ? doubleWESN[3] + yRange / 2 : // N y > intWESN[2] ? doubleWESN[2] - yRange / 2 : // S doubleWESN[2] + yRange / 2; // ensure not too far newX = Math.max(newX, extentWESN[0] + xRange / 2); newX = Math.min(newX, extentWESN[1] - xRange / 2); newY = Math.max(newY, extentWESN[2] + yRange / 2); newY = Math.min(newY, extentWESN[3] - yRange / 2); } else if (y < intWESN[3] || y > intWESN[2]) { // y is outside of graph, but x must be within graph newX = doubleWESN[0] + xRange / 2; newY = y < intWESN[3] ? doubleWESN[3] + yRange / 2 : doubleWESN[2] - yRange / 2; // ensure not too far newX = Math.max(newX, extentWESN[0] + xRange / 2); newX = Math.min(newX, extentWESN[1] - xRange / 2); newY = Math.max(newY, extentWESN[2] + yRange / 2); newY = Math.min(newY, extentWESN[3] - yRange / 2); } else { // click within the graph newX = doubleWESN[0] + (x - intWESN[0]) * xRange / (intWESN[1] - intWESN[0]); newY = doubleWESN[2] + (y - intWESN[2]) * yRange / (intWESN[3] - intWESN[2]); } return new double[] {newX, newY}; }
/** * The default palette (aka color bar) range ([0]=min, [1]=max). The values are also suitable for * the axis range on a graph. * * @param dataMin the raw minimum value of the data * @param dataMax the raw maximum value of the data * @return the default palette (aka color bar) range ([0]=min, [1]=max). */ public static double[] suggestPaletteRange(double dataMin, double dataMax) { double lowHigh[] = Math2.suggestLowHigh(dataMin, dataMax); // log axis? if (suggestPaletteScale(dataMin, dataMax) .equals("Log")) { // yes, use dataMin,dataMax, not lowHigh lowHigh[0] = Math2.suggestLowHigh(dataMin, 2 * dataMin)[0]; // trick to get nice suggested min>0 return lowHigh; } // axis is linear // suggest symmetric around 0 (symbolized by BlueWhiteRed)? if (suggestPalette(dataMin, dataMax) .equals("BlueWhiteRed")) { // yes, use dataMin,dataMax, not lowHigh double rangeMax = Math.max(-lowHigh[0], lowHigh[1]); lowHigh[0] = -rangeMax; lowHigh[1] = rangeMax; } // standard Rainbow Linear return lowHigh; }