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.3 2007/04/04 09:09:24 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 (as of version 1.0.4). If
056: * you are creating 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, Object[] xData,
087: Object[] yData, Object[] zData) {
088: super (seriesName, xData, yData, zData);
089: buildGrid(DEFAULT_NUM_X, DEFAULT_NUM_Y, DEFAULT_POWER);
090: }
091:
092: /**
093: * Constructor for NonGridContourDataset.
094: *
095: * @param seriesName the series name.
096: * @param xData the x values.
097: * @param yData the y values.
098: * @param zData the z values.
099: * @param numX number grid cells in along the x-axis
100: * @param numY number grid cells in along the y-axis
101: * @param power exponent for inverse distance weighting
102: */
103: public NonGridContourDataset(String seriesName, Object[] xData,
104: Object[] yData, Object[] zData, int numX, int numY,
105: 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: } else {
165: x += dxGrid;
166: }
167: double y = 0.0;
168: for (int j = 0; j < numY; j++) {
169: int k = numY * i + j;
170: xGrid[k] = x;
171: if (j == 0) {
172: y = yMin;
173: } else {
174: y += dyGrid;
175: }
176: yGrid[k] = y;
177: }
178: }
179:
180: // Map the nongrid data into the new regular grid
181: for (int kGrid = 0; kGrid < xGrid.length; kGrid++) {
182: double dTotal = 0.0;
183: zGrid[kGrid] = 0.0;
184: for (int k = 0; k < this .xValues.length; k++) {
185: double xPt = this .xValues[k].doubleValue();
186: double yPt = this .yValues[k].doubleValue();
187: double d = distance(xPt, yPt, xGrid[kGrid],
188: yGrid[kGrid]);
189: if (power != 1) {
190: d = Math.pow(d, power);
191: }
192: d = Math.sqrt(d);
193: if (d > 0.0) {
194: d = 1.0 / d;
195: } else { // if d is real small set the inverse to a large number
196: // to avoid INF
197: d = 1.e20;
198: }
199: if (this .zValues[k] != null) {
200: // scale by the inverse of distance^power
201: zGrid[kGrid] += this .zValues[k].doubleValue() * d;
202: }
203: dTotal += d;
204: }
205: zGrid[kGrid] = zGrid[kGrid] / dTotal; //remove distance of the sum
206: }
207:
208: //initalize xValues, yValues, and zValues arrays.
209: initialize(formObjectArray(xGrid), formObjectArray(yGrid),
210: formObjectArray(zGrid));
211:
212: }
213:
214: /**
215: * Calculates the distance between two points.
216: *
217: * @param xDataPt the x coordinate.
218: * @param yDataPt the y coordinate.
219: * @param xGrdPt the x grid coordinate.
220: * @param yGrdPt the y grid coordinate.
221: *
222: * @return The distance between two points.
223: */
224: protected double distance(double xDataPt, double yDataPt,
225: double xGrdPt, double yGrdPt) {
226: double dx = xDataPt - xGrdPt;
227: double dy = yDataPt - yGrdPt;
228: return Math.sqrt(dx * dx + dy * dy);
229: }
230:
231: }
|