2009-05-18 28 views
18

Bir dizi 2 boyutlu nokta alabilen ve eğriyi modelleyen daha büyük bir dizi noktaya geri dönebilen basit bir kütüphane bulmayı umuyorum. Temelde, JFreeChart gelen bu örnek gibi uydurma eğrisinin etkisini almak istiyorum:Java eğri uydurma kütüphanesi

alt text http://www.jfree.org/jfreechart/images/XYSplineRendererDemo1a.png

JFreeChart sorun kodu API bu tür sağlamaz olmasıdır. Hatta kaynağa baktım ve algoritma gerçek resme sıkı sıkıya bağlı. Sen bu eğriden ve bununla getPathIterator() Ne belgelere göre yapabilirsiniz

+0

Soru varlık: Tek yüzden, Eğri Uydurma kod Java (tabi bu kod bazı kütüphanelerde çekin OLACAK örnek kodu vermek için soruyu başka sözcüklerle olabilir bir tavsiye olarak görülebilir). Bu soru JFreeChart ile ilgili değil, sadece puanları alıp EKRAN EDER, ancak ek puanlar üretmez. Ben Bağlantılı ve İlgili tam olarak bu soruyu göstermediğini çok şaşırdım. –

cevap

0

ben hiç yapmadım, ama hızlı bir Google arama Bezier eğrileri Sonra http://java.sun.com/j2se/1.5.0/docs/api/java/awt/geom/QuadCurve2D.Double.html

uygulanır ortaya almak, diyor "şekil sınırlarının koordinatları", ki bu sizin aradığınız şeydir.

:
+1

Hayır, bunu yapmak istemiyor. Eğrinin kontrol noktalarını, spline enterpolasyonu veya bazı sezgisel metot kullanarak hesaplamalıdır. – Matej

+0

Daha iyi okumanızı öneririm http://en.wikipedia.org/wiki/Spline_(mathematics) ve http://en.wikipedia.org/wiki/B%C3%A9zier_curve Bezier eğrileri Bu eğrileri modelleyebilir. Bu eğri üzerinde noktaların koordinatlarına sahip olarak, istediğini etkili bir şekilde alır. – jbasko

4

Apache Commons Math

özellikle "SplineInterpolator", bir (X), p (x) Groovy gelen alfa için interpolasyon arama işlevleri olan API docs

bir örnek için bkz algoritmalar iyi bir dizi ekstrapolasyonlara için konu dışı bir örnek

package example.com 

import org.apache.commons.math3.analysis.interpolation.SplineInterpolator 
import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction 

import statec.Extrapolate.Value; 

class Interpolate { 

    enum Value { 
     ALPHA, BETA 
    } 

    def static xValues  = [ 
     -284086, 
     -94784, 
     31446, 
     354837, 
     667782, 
     982191 
    ] 
    def static alphaValues = [ 
     71641, 
     78245, 
     80871, 
     94045, 
     105780, 
     119616 
    ] 
    def static betaValues = [ 
     95552, 
     103413, 
     108667, 
     128456, 
     144686, 
     171953 
    ] 

    static def getValueByName(Value value, int i) { 
     def res 
     switch (value) { 
      case Value.ALPHA: 
       res = alphaValues[i] 
       break 
      case Value.BETA: 
       res = betaValues[i] 
       break 
      default: 
       assert false 
     } 
     return res 
    } 

    static PolynomialSplineFunction interpolate(Value value) { 
     def yValues = [] 
     int i = 0 
     xValues.each { 
      def y = getValueByName(value, i++) 
      yValues << (y as Double) 
     } 
     SplineInterpolator spi = new SplineInterpolator() 
     return spi.interpolate(xValues as double[], yValues as double[]) 
    } 

    static void main(def argv) { 
     // 
     // Create a map mapping a Value instance to its interpolating function 
     // 
     def interpolations = [:] 
     Value.values().each { 
      interpolations[it] = interpolate(it) 
     } 
     // 
     // Create an array of new x values to compute display. 
     // Make sure the last "original" value is in there! 
     // Note that the newxValues MUST stay within the range of the original xValues! 
     // 
     def newxValues = [] 
     for (long x = xValues[0] ; x < xValues[-1] ; x+=25000) { 
      newxValues << x 
     } 
     newxValues << xValues[-1] 
     // 
     // Write interpolated values for ALPHA and BETA, adding the original values in columns 4 and 5 
     // 
     System.out << "X , ALPHA, BETA, X_orig, ALPHA_orig, BETA_orig" << "\n" 
     int origIndex = 0 
     newxValues.each { long x -> 
      def alpha_ipol = interpolations[Value.ALPHA].value(x) 
      def beta_ipol = interpolations[Value.BETA].value(x) 
      String out = "${x} , ${alpha_ipol} , ${beta_ipol}" 
      if (x >= xValues[origIndex]) { 
       out += ", ${xValues[origIndex]}, ${alphaValues[origIndex]}, ${betaValues[origIndex]}" 
       origIndex++ 
      } 
      System.out << out << "\n" 
     } 
    } 
} 

The resulting output, plotted in LibreOffice Calc

Ve şimdi, eğlenceli olduğu için. Burada, yukarıdakiyle aynı verileri kullanıyoruz, ancak 2. derece bir polinom kullanarak ekstrapolasyon yapıyoruz. Tabii ki uygun sınıflar. Yine, Groovy: "beklemeye"

package example.com 

import org.apache.commons.math3.analysis.polynomials.PolynomialFunction 
import org.apache.commons.math3.fitting.PolynomialFitter 
import org.apache.commons.math3.fitting.WeightedObservedPoint 
import org.apache.commons.math3.optim.SimpleVectorValueChecker 
import org.apache.commons.math3.optim.nonlinear.vector.jacobian.GaussNewtonOptimizer 

class Extrapolate { 

    enum Value { 
     ALPHA, BETA 
    } 

    def static xValues  = [ 
     -284086, 
     -94784, 
     31446, 
     354837, 
     667782, 
     982191 
    ] 
    def static alphaValues = [ 
     71641, 
     78245, 
     80871, 
     94045, 
     105780, 
     119616 
    ] 
    def static betaValues = [ 
     95552, 
     103413, 
     108667, 
     128456, 
     144686, 
     171953 
    ] 

    static def getValueByName(Value value, int i) { 
     def res 
     switch (value) { 
      case Value.ALPHA: 
       res = alphaValues[i] 
       break 
      case Value.BETA: 
       res = betaValues[i] 
       break 
      default: 
       assert false 
     } 
     return res 
    } 

    static PolynomialFunction extrapolate(Value value) { 
     // 
     // how to check that we converged 
     // 
     def checker 
     A: { 
      double relativeThreshold = 0.01 
      double absoluteThreshold = 10 
      int maxIter = 1000 
      checker = new SimpleVectorValueChecker(relativeThreshold, absoluteThreshold, maxIter) 
     } 
     // 
     // how to fit 
     // 
     def fitter 
     B: { 
      def useLUdecomposition = true 
      def optimizer = new GaussNewtonOptimizer(useLUdecomposition, checker) 
      fitter = new PolynomialFitter(optimizer) 
      int i = 0 
      xValues.each { 
       def weight = 1.0 
       def y = getValueByName(value, i++) 
       fitter.addObservedPoint(new WeightedObservedPoint(weight, it, y)) 
      } 
     } 
     // 
     // fit using a 2-degree polynomial; guess at a linear function at first 
     // "a0 + (a1 * x) + (a2 * x²)"; a linear guess mean a2 == 0 
     // 
     def params 
     C: { 
      def mStart = getValueByName(value,0) 
      def mEnd = getValueByName(value,-1) 
      def xStart = xValues[0] 
      def xEnd = xValues[-1] 
      def a2 = 0 
      def a1 = (mEnd - mStart)/(xEnd - xStart) // slope 
      def a0 = mStart - (xStart * a1) // 0-intersection 
      def guess = [a0 , a1 , a2] 
      params = fitter.fit(guess as double[]) 
     } 
     // 
     // make polynomial 
     // 
     return new PolynomialFunction(params) 
    } 

    static void main(def argv) { 
     // 
     // Create a map mapping a Value instance to its interpolating function 
     // 
     def extrapolations = [:] 
     Value.values().each { 
      extrapolations[it] = extrapolate(it) 
     } 
     // 
     // New x, this times reaching out past the range of the original xValues 
     // 
     def newxValues = [] 
     for (long x = xValues[0] - 400000L ; x < xValues[-1] + 400000L ; x += 10000) { 
      newxValues << x 
     } 
     // 
     // Write the extrapolated series ALPHA and BETA, adding the original values in columns 4 and 5 
     // 
     System.out << "X , ALPHA, BETA, X_orig, ALPHA_orig, BETA_orig" << "\n" 
     int origIndex = 0 
     newxValues.each { long x -> 
      def alpha_xpol = extrapolations[Value.ALPHA].value(x) 
      def beta_xpol = extrapolations[Value.BETA].value(x) 
      String out = "${x} , ${alpha_xpol} , ${beta_xpol}" 
      if (origIndex < xValues.size() && x >= xValues[origIndex]) { 
       out += ", ${xValues[origIndex]}, ${alphaValues[origIndex]}, ${betaValues[origIndex]}" 
       origIndex++ 
      } 
      System.out << out << "\n" 
     } 
    } 
} 

The resulting output, plotted in LibreOffice Calc