/*
* 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.interpolation;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import org.geotools.geometry.iso.util.algorithm2D.AlgoPoint2D;
/**
* @author roehrig
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*
* @source $URL$
*/
public class ITP_Interpolation {
public enum TYPE {
HARDYMQ,
CARLSONHARDY,
STEADHARDY,
SHEPARD
}
// TODO JR
/**
* @author roehrig
*
*/
public static class Point3d {
public double x,y,z;
public Point3d(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
* @param p
* @return
*/
public double distance(Point3d p) {
return Math.sqrt(x*x+y*y+z*z);
}
}
public static boolean shepardModified(ArrayList<Point3d> pIn,
ArrayList<Point3d> pOut, double q, int nnbr) {
// pIn collection of GM_DirectPosition25OK
// pOutn collection of GM_DirectPosition25OK
// number of neighbours of pIn to be used in the interpolation: nnbr
if (nnbr == 0) nnbr = pIn.size() - 1;
// get node with neighbours aqnd gradients
ArrayList<PointNeighboursGradients> png = ITP_Interpolation.akimaGradient(pIn, nnbr);
for (int i=0; i< pOut.size();++i) {
ITP_Interpolation.shepardModified(png, q, pOut.get(i));
}
return true;
}
private static ArrayList<PointNeighboursGradients> akimaGradient(ArrayList<Point3d> pIn, int nnbr) {
// transform each node into a node, neighbours and gradients
ArrayList<PointNeighboursGradients> result = new ArrayList<PointNeighboursGradients>(pIn.size());
//final ITP_Interpolation dummy = new ITP_Interpolation();
for (int i=0; i< pIn.size();++i) {
Point3d p = pIn.get(i);
// creates an object for node, neighbours and gradients
PointNeighboursGradients png = new PointNeighboursGradients(p);
// set the neighbours
png.setClosestPoints(pIn, nnbr);
// set the gradients
png.setAkimaGradient();
result.add(png);
}
return result;
}
private static void shepardModified(ArrayList<PointNeighboursGradients> pngColl, double q, Point3d p_eval) {
PointNeighboursGradients png0;
double[] dist = new double[pngColl.size()];
double distMax = 0.0;
for (int i = 0; i < pngColl.size(); ++i) {
png0 = (PointNeighboursGradients)pngColl.get(i);
if (q == 2) {
dist[i] = (p_eval.x-png0.mP.x)*(p_eval.x-png0.mP.x)+
(p_eval.y-png0.mP.y)*(p_eval.y-png0.mP.y);
} else {
dist[i] = Math.pow(p_eval.distance(png0.mP), q);
}
distMax = Math.max(dist[i], distMax);
}
double sum0 = 0.0;
double sum1 = 0.0;
Point2D p0 = new Point2D.Double();
Point2D p1 = new Point2D.Double();
for (int i = 0; i < pngColl.size(); ++i) {
png0 = (PointNeighboursGradients)pngColl.get(i);
double prod = 1.0;
for (int j = 0; j < pngColl.size(); ++j) {
if (i != j) {
prod *= dist[j] / distMax;
if (prod == 0.0) {
PointNeighboursGradients png1 = (PointNeighboursGradients)pngColl.get(j);
p_eval.z = png1.mP.z;
return;
}
}
}
p0.setLocation(p_eval.x,p_eval.y);
p1.setLocation(png0.mP.x,png0.mP.y);
sum0 += (png0.mP.z + AlgoPoint2D.scalar(AlgoPoint2D.subtract(p0,p1),png0.mGradXY))* prod;
sum1 += prod;
}
p_eval.z = (sum0 / sum1);
}
}