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 }