001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jfreechart/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 025 * in the United States and other countries.] 026 * 027 * -------------------------- 028 * NonGridContourDataset.java 029 * -------------------------- 030 * (C) Copyright 2002-2008, by David M. O'Donnell. 031 * 032 * Original Author: David M. O'Donnell; 033 * Contributor(s): David Gilbert (for Object Refinery Limited); 034 * 035 * Changes (from 24-Jul-2003) 036 * -------------------------- 037 * 24-Jul-2003 : Added standard header (DG); 038 * ------------- JFREECHART 1.0.x --------------------------------------------- 039 * 31-Jan-2007 : Deprecated (DG); 040 * 041 */ 042 043 package org.jfree.data.contour; 044 045 import org.jfree.chart.plot.XYPlot; 046 import org.jfree.chart.renderer.xy.XYBlockRenderer; 047 import org.jfree.data.Range; 048 049 /** 050 * A convenience class that extends the {@link DefaultContourDataset} to 051 * accommodate non-grid data. 052 * 053 * @deprecated This class is no longer supported (as of version 1.0.4). If 054 * you are creating contour plots, please try to use {@link XYPlot} and 055 * {@link XYBlockRenderer}. 056 */ 057 public class NonGridContourDataset extends DefaultContourDataset { 058 059 /** Default number of x values. */ 060 static final int DEFAULT_NUM_X = 50; 061 062 /** Default number of y values. */ 063 static final int DEFAULT_NUM_Y = 50; 064 065 /** Default power. */ 066 static final int DEFAULT_POWER = 4; 067 068 /** 069 * Default constructor. 070 */ 071 public NonGridContourDataset() { 072 super(); 073 } 074 075 /** 076 * Constructor for NonGridContourDataset. Uses default values for grid 077 * dimensions and weighting. 078 * 079 * @param seriesName the series name. 080 * @param xData the x values. 081 * @param yData the y values. 082 * @param zData the z values. 083 */ 084 public NonGridContourDataset(String seriesName, 085 Object[] xData, Object[] yData, 086 Object[] zData) { 087 super(seriesName, xData, yData, zData); 088 buildGrid(DEFAULT_NUM_X, DEFAULT_NUM_Y, DEFAULT_POWER); 089 } 090 091 /** 092 * Constructor for NonGridContourDataset. 093 * 094 * @param seriesName the series name. 095 * @param xData the x values. 096 * @param yData the y values. 097 * @param zData the z values. 098 * @param numX number grid cells in along the x-axis 099 * @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 }