/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2006-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.geometry.iso.util.algorithmND; /** * This class offers methods to process basic operations on double arrays in n-dimensional space. * In majority, these algorithms are non-robust in sense that floating-point rounding errors may occur. * * @author Jackson Roehrig and Sanjay Jena * * * * * @source $URL$ */ public class AlgoPointND { /** * Returns the square of the distance between two points * * @param p0 * @param p1 * @return double */ public static double getDistanceSquare(double[] p0, double[] p1) { double sum = 0.0; for (int i=0, n=p0.length; i<n; ++i) { double a = p1[i] - p0[i]; sum += a*a; } return sum; } /** * Returns the distance between two points * * @param p0 * @param p1 * @return double */ public static double getDistance(double[] p0, double[] p1) { // OK double sum = 0.0; for (int i=0, n=p0.length; i<n; ++i) { double a = p1[i] - p0[i]; sum += a*a; } return Math.sqrt(sum); } /** * Returns the distance from the coordinate represented by <code>p0</code> to the origin of the coordinate system. * * Note: This method is NON-ROBUST due to floating-point rounding errors. * Inexact results according to floating-point rounding errors may be caused. * * @param p0 * @return double */ public static double getDistanceToOrigin(double[] p0) { // Test OK double sum = 0.0; for (int i=0, n=p0.length; i<n; ++i) { sum += p0[i]*p0[i]; } return Math.sqrt(sum); } // /** // * @param p0 // * @return double // */ // public static double getDistanceToOriginSquare(double[] p0) { // double sum = 0.0; // for (int i=0, n=p0.length; i<n; ++i) { // sum += p0[i]*p0[i]; // } // return sum; // } /** * Substracts a coordinate <code>p0</code> from a coordinate <code>p1</code>. * * Note: This method is NON-ROBUST due to floating-point rounding errors. * Inexact results according to floating-point rounding errors may be caused. * * @param p0 * @param p1 * @return p1 - p0 : double[] */ public static double[] subtract(double[] p0, double[] p1) { // Test OK int n = p0.length; double result[]= new double[n]; for (int i=0; i<n; ++i) { result[i]= p1[i] - p0[i]; } return result; } /** * Adds a coordinate to another coordinate * * @param p0 * @param p1 * @return double[] */ public static double[] add(double[] p0, double[] p1) { // Test OK int n = p0.length; double result[]= new double[n]; for (int i=0; i<n; ++i) { result[i]= p0[i] + p1[i]; } return result; } // /** // * @param p0 // * @param factor // * @return double[] // */ // public static double[] add(double[] p0, double factor) { // int n = p0.length; // double result[]= new double[n]; // for (int i=0; i<n; ++i) { // result[i]= p0[i] + factor; // } // return result; // } /** * @param p0 * @param factor * @return double[] */ public static double[] scale(double[] p0, double factor){ int n = p0.length; double result[]= new double[n]; for (int i=0; i<n; ++i) { result[i]= p0[i]*factor; } return result; } /** * @param c0 * @param c1 * @param maxSpacingSquare is the square of the max. allowed spacing * @return only the intermediate coordinates */ public static double[][] split(double[] c0, double[] c1, double maxSpacingSquare) { // TODO Test // TODO Documentation double distSquare = getDistanceSquare(c0,c1); if (distSquare>maxSpacingSquare) { int n = (int)Math.ceil(Math.sqrt( distSquare/ maxSpacingSquare)); double r = 1.0 / n; double[][] result = new double[n-1][]; for (int i=1; i<n; ++i) { result[i-1] = evaluate(c0, c1, i*r); //result[i] = evaluate(c0, c1, i*r); } return result; } return null; } // /** // * @param c0 // * @param n // * @return double[] // */ // public static double[] divide(double[] c0, int n) { // int nc = c0.length; // double[] result = new double[nc]; // for (int i=0; i<nc; ++i) { // result[i] = c0[i]/n; // } // return result; // } /** * Interpolation of a straigt line given by two coordinates <code>c0</code> and <code>c1</code>. * The method will return a double array which describes the coordinate at distance <code>r</code> * on this straight line, whith a parametrisation of 0.0 at <code>c0</code> and 1.0 at <code>c1</code>. * * Note: This method is NON-ROBUST due to floating-point rounding errors. * Inexact results according to floating-point rounding errors may be caused. * * @param c0 * @param c1 * @param r * @return double[] */ public static double[] evaluate(double[] c0, double[] c1, double r) { // ok int n = c0.length; double[] result = new double[n]; double s = 1.0 - r; for (int i=0; i<n; ++i) { result[i] = s * c0[i] + r * c1[i]; } return result; } // /** // * @param c0 // * @param c1 // * @param r // * @return double[] // */ // public static double[] evaluate(double[] c0, double[] c1, double[] r) { // int n = c0.length; // double[] result = new double[n]; // for (int i=0; i<n; ++i) { // result[i] = (1.0 - r[i]) * c0[i] + r[i] * c1[i]; // } // return result; // } /** * Normalizes a vector which begins at the origin and ends at <code>p</code> to length 1 * * Note: This method is NON-ROBUST due to floating-point rounding errors. * Inexact results according to floating-point rounding errors may be caused. * * @param p the end point of the vector * * @return double[] End point of the normalized vector * @return NULL if the result is not valid (for example when <code>p</code> is the origin) */ public static double[] normalize(double[] p) { // Test OK double len = getDistanceToOrigin(p); double[] rCoord = null; if ( len > 0.0 ) { rCoord = scale(p,1.0 / len); } else { for (int i=0, n=p.length; i<n; ++i) { p[i] = 0.0; } } return rCoord; } }