Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jfreechart/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * -------------------------- 28: * NonGridContourDataset.java 29: * -------------------------- 30: * (C) Copyright 2002-2007, by David M. O'Donnell. 31: * 32: * Original Author: David M. O'Donnell; 33: * Contributor(s): David Gilbert (for Object Refinery Limited); 34: * 35: * Changes (from 24-Jul-2003) 36: * -------------------------- 37: * 24-Jul-2003 : Added standard header (DG); 38: * ------------- JFREECHART 1.0.x --------------------------------------------- 39: * 31-Jan-2007 : Deprecated (DG); 40: * 41: */ 42: 43: package org.jfree.data.contour; 44: 45: import org.jfree.chart.plot.XYPlot; 46: import org.jfree.chart.renderer.xy.XYBlockRenderer; 47: import org.jfree.data.Range; 48: 49: /** 50: * A convenience class that extends the {@link DefaultContourDataset} to 51: * accommodate non-grid data. 52: * 53: * @deprecated This class is no longer supported (as of version 1.0.4). If 54: * you are creating contour plots, please try to use {@link XYPlot} and 55: * {@link XYBlockRenderer}. 56: */ 57: public class NonGridContourDataset extends DefaultContourDataset { 58: 59: /** Default number of x values. */ 60: static final int DEFAULT_NUM_X = 50; 61: 62: /** Default number of y values. */ 63: static final int DEFAULT_NUM_Y = 50; 64: 65: /** Default power. */ 66: static final int DEFAULT_POWER = 4; 67: 68: /** 69: * Default constructor. 70: */ 71: public NonGridContourDataset() { 72: super(); 73: } 74: 75: /** 76: * Constructor for NonGridContourDataset. Uses default values for grid 77: * dimensions and weighting. 78: * 79: * @param seriesName the series name. 80: * @param xData the x values. 81: * @param yData the y values. 82: * @param zData the z values. 83: */ 84: public NonGridContourDataset(String seriesName, 85: Object[] xData, Object[] yData, 86: Object[] zData) { 87: super(seriesName, xData, yData, zData); 88: buildGrid(DEFAULT_NUM_X, DEFAULT_NUM_Y, DEFAULT_POWER); 89: } 90: 91: /** 92: * Constructor for NonGridContourDataset. 93: * 94: * @param seriesName the series name. 95: * @param xData the x values. 96: * @param yData the y values. 97: * @param zData the z values. 98: * @param numX number grid cells in along the x-axis 99: * @param numY number grid cells in along the y-axis 100: * @param power exponent for inverse distance weighting 101: */ 102: public NonGridContourDataset(String seriesName, 103: Object[] xData, Object[] yData, 104: Object[] zData, 105: int numX, int numY, int power) { 106: super(seriesName, xData, yData, zData); 107: buildGrid(numX, numY, power); 108: } 109: 110: /** 111: * Builds a regular grid. Maps the non-grid data into the regular grid 112: * using an inverse distance between grid and non-grid points. Weighting 113: * of distance can be controlled by setting through the power parameter 114: * that controls the exponent used on the distance weighting 115: * (e.g., distance^power). 116: * 117: * @param numX number grid points in along the x-axis 118: * @param numY number grid points in along the y-axis 119: * @param power exponent for inverse distance weighting 120: */ 121: protected void buildGrid(int numX, int numY, int power) { 122: 123: int numValues = numX * numY; 124: double[] xGrid = new double[numValues]; 125: double[] yGrid = new double [numValues]; 126: double[] zGrid = new double [numValues]; 127: 128: // Find min, max for the x and y axes 129: double xMin = 1.e20; 130: for (int k = 0; k < this.xValues.length; k++) { 131: xMin = Math.min(xMin, this.xValues[k].doubleValue()); 132: } 133: 134: double xMax = -1.e20; 135: for (int k = 0; k < this.xValues.length; k++) { 136: xMax = Math.max(xMax, this.xValues[k].doubleValue()); 137: } 138: 139: double yMin = 1.e20; 140: for (int k = 0; k < this.yValues.length; k++) { 141: yMin = Math.min(yMin, this.yValues[k].doubleValue()); 142: } 143: 144: double yMax = -1.e20; 145: for (int k = 0; k < this.yValues.length; k++) { 146: yMax = Math.max(yMax, this.yValues[k].doubleValue()); 147: } 148: 149: Range xRange = new Range(xMin, xMax); 150: Range yRange = new Range(yMin, yMax); 151: 152: xRange.getLength(); 153: yRange.getLength(); 154: 155: // Determine the cell size 156: double dxGrid = xRange.getLength() / (numX - 1); 157: double dyGrid = yRange.getLength() / (numY - 1); 158: 159: // Generate the grid 160: double x = 0.0; 161: for (int i = 0; i < numX; i++) { 162: if (i == 0) { 163: x = xMin; 164: } 165: else { 166: x += dxGrid; 167: } 168: double y = 0.0; 169: for (int j = 0; j < numY; j++) { 170: int k = numY * i + j; 171: xGrid[k] = x; 172: if (j == 0) { 173: y = yMin; 174: } 175: else { 176: y += dyGrid; 177: } 178: yGrid[k] = y; 179: } 180: } 181: 182: // Map the nongrid data into the new regular grid 183: for (int kGrid = 0; kGrid < xGrid.length; kGrid++) { 184: double dTotal = 0.0; 185: zGrid[kGrid] = 0.0; 186: for (int k = 0; k < this.xValues.length; k++) { 187: double xPt = this.xValues[k].doubleValue(); 188: double yPt = this.yValues[k].doubleValue(); 189: double d = distance(xPt, yPt, xGrid[kGrid], yGrid[kGrid]); 190: if (power != 1) { 191: d = Math.pow(d, power); 192: } 193: d = Math.sqrt(d); 194: if (d > 0.0) { 195: d = 1.0 / d; 196: } 197: else { // if d is real small set the inverse to a large number 198: // to avoid INF 199: d = 1.e20; 200: } 201: if (this.zValues[k] != null) { 202: // scale by the inverse of distance^power 203: zGrid[kGrid] += this.zValues[k].doubleValue() * d; 204: } 205: dTotal += d; 206: } 207: zGrid[kGrid] = zGrid[kGrid] / dTotal; //remove distance of the sum 208: } 209: 210: //initalize xValues, yValues, and zValues arrays. 211: initialize( 212: formObjectArray(xGrid), formObjectArray(yGrid), 213: formObjectArray(zGrid) 214: ); 215: 216: } 217: 218: /** 219: * Calculates the distance between two points. 220: * 221: * @param xDataPt the x coordinate. 222: * @param yDataPt the y coordinate. 223: * @param xGrdPt the x grid coordinate. 224: * @param yGrdPt the y grid coordinate. 225: * 226: * @return The distance between two points. 227: */ 228: protected double distance(double xDataPt, 229: double yDataPt, 230: double xGrdPt, 231: double yGrdPt) { 232: double dx = xDataPt - xGrdPt; 233: double dy = yDataPt - yGrdPt; 234: return Math.sqrt(dx * dx + dy * dy); 235: } 236: 237: }