/* * Copyright 2006, United States Government as represented by the Administrator * for the National Aeronautics and Space Administration. No copyright is * claimed in the United States under Title 17, U.S. Code. All Other Rights * Reserved. */ package gov.nasa.ial.mde.util; import gov.nasa.ial.mde.math.MultiPointXY; import gov.nasa.ial.mde.math.PointRT; import gov.nasa.ial.mde.math.PointXY; import gov.nasa.ial.mde.properties.MdeSettings; /** * <code>PointsUtil</code> is utility class for handling the PointXY and * MultiPointXY classes. * * @author Dan Dexter * @version 1.0 * @since 1.0 */ public class PointsUtil { /** * Converts the Polar points to Cartesian points. * * @param polars the points in Polar form. * @return the points in Cartesian form. */ public static PointXY[] toCartesian(PointXY[] polars) { int n = polars.length; PointXY[] r = new PointXY[n]; if (MdeSettings.DEBUG) { System.out.println("polars.length=" + n); } for (int i = 0; i < n; i++) { r[i] = new PointRT(polars[i].y, polars[i].x).toCartesian(); } return r; } // end toCartesian /** * Creates a multi-point array from the X and Y data arrays and interpolates * as necessary to ensure <code>length</code> number of points. * * @param leftIndex left starting array index. * @param rightIndex right ending array index. * @param length the length of the multi-point array to create. * @param xData X-data value array. * @param yData Y-data value array. * @return a multi-point array. */ public static MultiPointXY[] interpolatePoints(int leftIndex, int rightIndex, int length, double[] xData, double[] yData) { // If we only have one point then just repeat it. if (leftIndex == rightIndex) { // Just use the one point. return fillPoints(leftIndex, 1, xData, yData); } int pointBudget = length - ((rightIndex - leftIndex) + 1); double stepSize = (double) (rightIndex - leftIndex) / (double) (pointBudget + 1); MultiPointXY[] r = new MultiPointXY[length]; int lastPointPos = length - 1; int i, k, index, position, interpolateCnt; double x, y, xStep, yStep; double sum = 0.0; // Handle the first index as a special case to ensure we pick up this end point. r[0] = new MultiPointXY(xData[leftIndex], yData[leftIndex]); for (i = 1, index = leftIndex + 1; (i < lastPointPos) && (index <= rightIndex); i++, index++) { interpolateCnt = 0; position = index - leftIndex; while ((sum + stepSize) < position) { sum += stepSize; interpolateCnt++; } // Do linear interpolation of the X and Y real-data values between // the current index and the previous index. if (interpolateCnt > 0) { k = index - 1; x = xData[k]; y = yData[k]; k = interpolateCnt + 1; xStep = (xData[index] - x) / k; yStep = (yData[index] - y) / k; do { x += xStep; y += yStep; r[i] = new MultiPointXY(x, y); interpolateCnt--; i++; } while ((interpolateCnt > 0) && (i < lastPointPos)); } if (i < lastPointPos) { r[i] = new MultiPointXY(xData[index], yData[index]); } } // Handle the last index as a special case to ensure we pick up this end point. r[lastPointPos] = new MultiPointXY(xData[rightIndex], yData[rightIndex]); return r; } /** * Creates a multi-point array from the X and Y data arrays and decimates * as necessary to ensure <code>length</code> number of points. * * @param leftIndex left starting array index. * @param rightIndex right ending array index. * @param length the length of the multi-point array to create. * @param xData X-data value array. * @param yData Y-data value array. * @return a multi-point array. */ public static MultiPointXY[] decimatePoints(int leftIndex, int rightIndex, int length, double[] xData, double[] yData) { double stepSize = (double) ((rightIndex - leftIndex) + 1) / (double) length; MultiPointXY[] r = new MultiPointXY[length]; int lastIndex = length - 1; int i, index; double offset; // Handle the first index as a special case to ensure we pick up this end point. r[0] = new MultiPointXY(xData[leftIndex], yData[leftIndex]); // Decimate by using every dataStep value from the real-data. for (i = 1, offset = leftIndex + stepSize; i < lastIndex; i++, offset += stepSize) { index = (int) Math.round(offset); if (index > rightIndex) { index = rightIndex; } r[i] = new MultiPointXY(xData[index], yData[index]); } // Handle the last index as a special case to ensure we pick up this end point. r[lastIndex] = new MultiPointXY(xData[rightIndex], yData[rightIndex]); return r; } /** * Creates a multi-point array from the X and Y data arrays. * * @param leftIndex left starting array index. * @param rightIndex right ending array index. * @param xData X-data value array. * @param yData Y-data value array. * @return a multi-point array. */ public static MultiPointXY[] copyPoints(int leftIndex, int rightIndex, double[] xData, double[] yData) { int len = (rightIndex - leftIndex) + 1; MultiPointXY[] r = new MultiPointXY[len]; int i, dataIndex; for (i = 0, dataIndex = leftIndex; i < len; i++, dataIndex++) { r[i] = new MultiPointXY(xData[dataIndex], yData[dataIndex]); } return r; } /** * Creates a multi-point array from the X and Y data array value at the * specified index. * * @param index the array index in the data to fill the multi-point array with. * @param length the length of the multi-point array to create. * @param xData X-data value array. * @param yData Y-data value array. * @return a multi-point array. */ public static MultiPointXY[] fillPoints(int index, int length, double[] xData, double[] yData) { MultiPointXY point = new MultiPointXY(xData[index], yData[index]); MultiPointXY[] r = new MultiPointXY[length]; for (int i = 0; i < length; i++) { r[i] = point; } return r; } }