001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2007, 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-2007, by David M. O'Donnell. 031 * 032 * Original Author: David M. O'Donnell; 033 * Contributor(s): David Gilbert (for Object Refinery Limited); 034 * 035 * $Id: NonGridContourDataset.java,v 1.3.2.2 2007/01/31 15:56:19 mungady Exp $ 036 * 037 * Changes (from 24-Jul-2003) 038 * -------------------------- 039 * 24-Jul-2003 : Added standard header (DG); 040 * ------------- JFREECHART 1.0.x --------------------------------------------- 041 * 31-Jan-2007 : Deprecated (DG); 042 * 043 */ 044 045 package org.jfree.data.contour; 046 047 import org.jfree.chart.plot.XYPlot; 048 import org.jfree.chart.renderer.xy.XYBlockRenderer; 049 import org.jfree.data.Range; 050 051 /** 052 * A convenience class that extends the {@link DefaultContourDataset} to 053 * accommodate non-grid data. 054 * 055 * @deprecated This class is no longer supported. If you are creating 056 * contour plots, please try to use {@link XYPlot} and 057 * {@link XYBlockRenderer}. 058 */ 059 public class NonGridContourDataset extends DefaultContourDataset { 060 061 /** Default number of x values. */ 062 static final int DEFAULT_NUM_X = 50; 063 064 /** Default number of y values. */ 065 static final int DEFAULT_NUM_Y = 50; 066 067 /** Default power. */ 068 static final int DEFAULT_POWER = 4; 069 070 /** 071 * Default constructor. 072 */ 073 public NonGridContourDataset() { 074 super(); 075 } 076 077 /** 078 * Constructor for NonGridContourDataset. Uses default values for grid 079 * dimensions and weighting. 080 * 081 * @param seriesName the series name. 082 * @param xData the x values. 083 * @param yData the y values. 084 * @param zData the z values. 085 */ 086 public NonGridContourDataset(String seriesName, 087 Object[] xData, Object[] yData, 088 Object[] zData) { 089 super(seriesName, xData, yData, zData); 090 buildGrid(DEFAULT_NUM_X, DEFAULT_NUM_Y, DEFAULT_POWER); 091 } 092 093 /** 094 * Constructor for NonGridContourDataset. 095 * 096 * @param seriesName the series name. 097 * @param xData the x values. 098 * @param yData the y values. 099 * @param zData the z values. 100 * @param numX number grid cells in along the x-axis 101 * @param numY number grid cells in along the y-axis 102 * @param power exponent for inverse distance weighting 103 */ 104 public NonGridContourDataset(String seriesName, 105 Object[] xData, Object[] yData, 106 Object[] zData, 107 int numX, int numY, int power) { 108 super(seriesName, xData, yData, zData); 109 buildGrid(numX, numY, power); 110 } 111 112 /** 113 * Builds a regular grid. Maps the non-grid data into the regular grid 114 * using an inverse distance between grid and non-grid points. Weighting 115 * of distance can be controlled by setting through the power parameter 116 * that controls the exponent used on the distance weighting 117 * (e.g., distance^power). 118 * 119 * @param numX number grid points in along the x-axis 120 * @param numY number grid points in along the y-axis 121 * @param power exponent for inverse distance weighting 122 */ 123 protected void buildGrid(int numX, int numY, int power) { 124 125 int numValues = numX * numY; 126 double[] xGrid = new double[numValues]; 127 double[] yGrid = new double [numValues]; 128 double[] zGrid = new double [numValues]; 129 130 // Find min, max for the x and y axes 131 double xMin = 1.e20; 132 for (int k = 0; k < this.xValues.length; k++) { 133 xMin = Math.min(xMin, this.xValues[k].doubleValue()); 134 } 135 136 double xMax = -1.e20; 137 for (int k = 0; k < this.xValues.length; k++) { 138 xMax = Math.max(xMax, this.xValues[k].doubleValue()); 139 } 140 141 double yMin = 1.e20; 142 for (int k = 0; k < this.yValues.length; k++) { 143 yMin = Math.min(yMin, this.yValues[k].doubleValue()); 144 } 145 146 double yMax = -1.e20; 147 for (int k = 0; k < this.yValues.length; k++) { 148 yMax = Math.max(yMax, this.yValues[k].doubleValue()); 149 } 150 151 Range xRange = new Range(xMin, xMax); 152 Range yRange = new Range(yMin, yMax); 153 154 xRange.getLength(); 155 yRange.getLength(); 156 157 // Determine the cell size 158 double dxGrid = xRange.getLength() / (numX - 1); 159 double dyGrid = yRange.getLength() / (numY - 1); 160 161 // Generate the grid 162 double x = 0.0; 163 for (int i = 0; i < numX; i++) { 164 if (i == 0) { 165 x = xMin; 166 } 167 else { 168 x += dxGrid; 169 } 170 double y = 0.0; 171 for (int j = 0; j < numY; j++) { 172 int k = numY * i + j; 173 xGrid[k] = x; 174 if (j == 0) { 175 y = yMin; 176 } 177 else { 178 y += dyGrid; 179 } 180 yGrid[k] = y; 181 } 182 } 183 184 // Map the nongrid data into the new regular grid 185 for (int kGrid = 0; kGrid < xGrid.length; kGrid++) { 186 double dTotal = 0.0; 187 zGrid[kGrid] = 0.0; 188 for (int k = 0; k < this.xValues.length; k++) { 189 double xPt = this.xValues[k].doubleValue(); 190 double yPt = this.yValues[k].doubleValue(); 191 double d = distance(xPt, yPt, xGrid[kGrid], yGrid[kGrid]); 192 if (power != 1) { 193 d = Math.pow(d, power); 194 } 195 d = Math.sqrt(d); 196 if (d > 0.0) { 197 d = 1.0 / d; 198 } 199 else { // if d is real small set the inverse to a large number 200 // to avoid INF 201 d = 1.e20; 202 } 203 if (this.zValues[k] != null) { 204 // scale by the inverse of distance^power 205 zGrid[kGrid] += this.zValues[k].doubleValue() * d; 206 } 207 dTotal += d; 208 } 209 zGrid[kGrid] = zGrid[kGrid] / dTotal; //remove distance of the sum 210 } 211 212 //initalize xValues, yValues, and zValues arrays. 213 initialize( 214 formObjectArray(xGrid), formObjectArray(yGrid), 215 formObjectArray(zGrid) 216 ); 217 218 } 219 220 /** 221 * Calculates the distance between two points. 222 * 223 * @param xDataPt the x coordinate. 224 * @param yDataPt the y coordinate. 225 * @param xGrdPt the x grid coordinate. 226 * @param yGrdPt the y grid coordinate. 227 * 228 * @return The distance between two points. 229 */ 230 protected double distance(double xDataPt, 231 double yDataPt, 232 double xGrdPt, 233 double yGrdPt) { 234 double dx = xDataPt - xGrdPt; 235 double dy = yDataPt - yGrdPt; 236 return Math.sqrt(dx * dx + dy * dy); 237 } 238 239 }