Interpolates points given in the 2D plane : Geometry « 2D Graphics GUI « Java

Home
Java
1.2D Graphics GUI
2.2D Graphics GUI1
3.3D
4.Advanced Graphics
5.Ant
6.Apache Common
7.Chart
8.Class
9.Collections Data Structure
10.Data Type
11.Database SQL JDBC
12.Design Pattern
13.Development Class
14.EJB3
15.Email
16.Event
17.File Input Output
18.Game
19.Generics
20.GWT
21.Hibernate
22.I18N
23.J2EE
24.J2ME
25.JDK 6
26.JNDI LDAP
27.JPA
28.JSP
29.JSTL
30.Language Basics
31.Network Protocol
32.PDF RTF
33.Reflection
34.Regular Expressions
35.Scripting
36.Security
37.Servlets
38.Spring
39.Swing Components
40.Swing JFC
41.SWT JFace Eclipse
42.Threads
43.Tiny Application
44.Velocity
45.Web Services SOA
46.XML
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
SCJP
Java » 2D Graphics GUI » GeometryScreenshots 
Interpolates points given in the 2D plane
 

import java.awt.geom.Point2D;
import java.util.Arrays;

/* This code is PUBLIC DOMAIN */

/*
 * @(#)Spline2D.java
 
 * Copyright (c) 2003 Martin Krueger
 * Copyright (c) 2005 David Benson
 *  
 */

/**
 * Interpolates points given in the 2D plane. The resulting spline
 * is a function s: R -> R^2 with parameter t in [0,1].
 
 @author krueger
 */
public class Spline2D {

  /** 
   *  Array representing the relative proportion of the total distance
   *  of each point in the line ( i.e. first point is 0.0, end point is
   *  1.0, a point halfway on line is 0.5 ).
   */
  private double[] t;
  private Spline splineX;
  private Spline splineY;
  /**
   * Total length tracing the points on the spline
   */
  private double length;
  
  /**
   * Creates a new Spline2D.
   @param points
   */
  public Spline2D(Point2D[] points) {
    double[] x = new double[points.length];
    double[] y = new double[points.length];
    
    for(int i = 0; i< points.length; i++) {
      x[i= points[i].getX();
      y[i= points[i].getY()
    }
    
    init(x, y);
  }

  /**
   * Creates a new Spline2D.
   @param x
   @param y
   */
  public Spline2D(double[] x, double[] y) {
    init(x, y);
  }

  private void init(double[] x, double[] y) {
    if (x.length != y.length) {
      throw new IllegalArgumentException("Arrays must have the same length.");
    }
    
    if (x.length < 2) {
      throw new IllegalArgumentException("Spline edges must have at least two points.");
    }

    t = new double[x.length];
    t[00.0// start point is always 0.0
    
    // Calculate the partial proportions of each section between each set
    // of points and the total length of sum of all sections
    for (int i = 1; i < t.length; i++) {
      double lx = x[i- x[i-1];
      double ly = y[i- y[i-1];
      // If either diff is zero there is no point performing the square root
      if 0.0 == lx ) {
        t[i= Math.abs(ly);
      else if 0.0 == ly ) {
        t[i= Math.abs(lx);
      else {
        t[i= Math.sqrt(lx*lx+ly*ly);
      }
      
      length += t[i];
      t[i+= t[i-1];
    }
    
    for(int i = 1; i< (t.length)-1; i++) {
      t[i= t[i/ length;
    }
    
    t[(t.length)-11.0// end point is always 1.0
    
    splineX = new Spline(t, x);
    splineY = new Spline(t, y);
  }

  /**
   @param t 0 <= t <= 1
   */
  public double[] getPoint(double t) {
    double[] result = new double[2];
    result[0= splineX.getValue(t);
    result[1= splineY.getValue(t);

    return result;
  }
  
  /**
   * Used to check the correctness of this spline
   */
  public boolean checkValues() {
    return (splineX.checkValues() && splineY.checkValues());
  }

  public double getDx(double t) {
    return splineX.getDx(t);
  }
  
  public double getDy(double t) {
    return splineY.getDx(t);
  }
  
  public Spline getSplineX() {
    return splineX;
  }
  
  public Spline getSplineY() {
    return splineY;
  }
  
  public double getLength() {
    return length;
  }

}


/**
 * Interpolates given values by B-Splines.
 
 @author krueger
 */
class Spline {

  private double[] xx;
  private double[] yy;

  private double[] a;
  private double[] b;
  private double[] c;
  private double[] d;

  /** tracks the last index found since that is mostly commonly the next one used */
  private int storageIndex = 0;

  /**
   * Creates a new Spline.
   @param xx
   @param yy
   */
  public Spline(double[] xx, double[] yy) {
    setValues(xx, yy);
  }

  /**
   * Set values for this Spline.
   @param xx
   @param yy
   */
  public void setValues(double[] xx, double[] yy) {
    this.xx = xx;
    this.yy = yy;
    if (xx.length > 1) {
      calculateCoefficients();
    }
  }

  /**
   * Returns an interpolated value.
   @param x
   @return the interpolated value
   */
  public double getValue(double x) {
    if (xx.length == 0) {
      return Double.NaN;
    }

    if (xx.length == 1) {
      if (xx[0== x) {
        return yy[0];
      else {
        return Double.NaN;
      }
    }

    int index = Arrays.binarySearch(xx, x);
    if (index > 0) {
      return yy[index];
    }

    index = - (index + 11;
    //TODO linear interpolation or extrapolation
    if (index < 0) {
      return yy[0];
    }

    return a[index]
      + b[index(x - xx[index])
      + c[index* Math.pow(x - xx[index]2)
      + d[index* Math.pow(x - xx[index]3);
  }

  /**
   * Returns an interpolated value. To be used when a long sequence of values
   * are required in order, but ensure checkValues() is called beforehand to
   * ensure the boundary checks from getValue() are made
   @param x
   @return the interpolated value
   */
  public double getFastValue(double x) {
    // Fast check to see if previous index is still valid
    if (storageIndex > -&& storageIndex < xx.length-&& x > xx[storageIndex&& x < xx[storageIndex + 1]) {

    else {
      int index = Arrays.binarySearch(xx, x);
      if (index > 0) {
        return yy[index];
      }
      index = - (index + 11;
      storageIndex = index;
    }
  
    //TODO linear interpolation or extrapolation
    if (storageIndex < 0) {
      return yy[0];
    }
    double value = x - xx[storageIndex];
    return a[storageIndex]
          + b[storageIndex* value
          + c[storageIndex(value * value)
          + d[storageIndex(value * value * value);
  }

  /**
   * Used to check the correctness of this spline
   */
  public boolean checkValues() {
    if (xx.length < 2) {
      return false;
    else {
      return true;
    }
  }

  /**
   * Returns the first derivation at x.
   @param x
   @return the first derivation at x
   */
  public double getDx(double x) {
    if (xx.length == || xx.length == 1) {
      return 0;
    }

    int index = Arrays.binarySearch(xx, x);
    if (index < 0) {
      index = - (index + 11;
    }

    return b[index]
      * c[index(x - xx[index])
      * d[index* Math.pow(x - xx[index]2);
  }

  /**
   * Calculates the Spline coefficients.
   */
  private void calculateCoefficients() {
    int N = yy.length;
    a = new double[N];
    b = new double[N];
    c = new double[N];
    d = new double[N];

    if (N == 2) {
      a[0= yy[0];
      b[0= yy[1- yy[0];
      return;
    }

    double[] h = new double[N - 1];
    for (int i = 0; i < N - 1; i++) {
      a[i= yy[i];
      h[i= xx[i + 1- xx[i];
      // h[i] is used for division later, avoid a NaN
      if (h[i== 0.0) {
        h[i0.01;
      }
    }
    a[N - 1= yy[N - 1];

    double[][] A = new double[N - 2][N - 2];
    double[] y = new double[N - 2];
    for (int i = 0; i < N - 2; i++) {
      y[i=
        3
          ((yy[i + 2- yy[i + 1]) / h[i
            1]
            (yy[i + 1- yy[i]) / h[i]);

      A[i][i(h[i+ h[i + 1]);

      if (i > 0) {
        A[i][i - 1= h[i];
      }

      if (i < N - 3) {
        A[i][i + 1= h[i + 1];
      }
    }
    solve(A, y);

    for (int i = 0; i < N - 2; i++) {
      c[i + 1= y[i];
      b[i(a[i + 1- a[i]) / h[i(* c[i+ c[i + 1]) * h[i];
      d[i(c[i + 1- c[i]) (* h[i]);
    }
    b[N - 2=
      (a[N - 1- a[N - 2]) / h[N
        2]
        (* c[N - 2+ c[N - 1]) * h[N
        2];
    d[N - 2(c[N - 1- c[N - 2]) (* h[N - 2]);
  }

  /**
   * Solves Ax=b and stores the solution in b.
   */
  public void solve(double[][] A, double[] b) {
    int n = b.length;
    for (int i = 1; i < n; i++) {
      A[i][i - 1= A[i][i - 1/ A[i - 1][i - 1];
      A[i][i= A[i][i- A[i - 1][i* A[i][i - 1];
      b[i= b[i- A[i][i - 1* b[i - 1];
    }

    b[n - 1= b[n - 1/ A[n - 1][n - 1];
    for (int i = b.length - 2; i >= 0; i--) {
      b[i(b[i- A[i][i + 1* b[i + 1]) / A[i][i];
    }
  }
}

   
  
Related examples in the same category
1.Collection of geometry utility methods
2.Unions Rectangle2D
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.