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 * 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 }