• java 三次样条插值 画光滑曲线 例子


    java 三次样条插值 画光滑曲线 例子

    主要是做数值拟合,根据sin函数采点,取得数据后在java中插值并在swing中画出曲线,下面为截图  不光滑和光滑曲线前后对比:

      

    代码:

    执行类:

      1 package com.yang.logic;
      2 
      3 import java.util.ArrayList;
      4 import java.util.Collections;
      5 import java.util.Comparator;
      6 import java.util.List;
      7 
      8 import com.yang.logic.Drawlineforspline.Mypanel;
      9 
     10 public class Testspline {
     11     
     12     // 根据X排序
     13     class SortByX implements Comparator {
     14         public int compare(Object obj1, Object obj2) {
     15             PointStruct point1 = (PointStruct) obj1;
     16             PointStruct point2 = (PointStruct) obj2;
     17             if (point1.dx > point2.dx)
     18                 return 1;
     19             else
     20                 return 0;
     21         }
     22     } 
     23     //转化成数组
     24     public static ArrayList<Double> getArrayfList(List<PointStruct> l, String type) {
     25         ArrayList<Double> tmplist = new ArrayList<Double>();
     26         for (PointStruct p : l) {
     27             if (type == "ix") {
     28                 tmplist.add((double) p.ix);
     29             } else if (type == "iy") {
     30                 tmplist.add((double) p.iy);
     31             } else if (type == "dx") {
     32                 tmplist.add(p.dx);
     33             } else if (type == "dy") {
     34                 tmplist.add(p.dy);
     35             }
     36         }
     37         return tmplist;
     38     }
     39     
     40     public static void main(String[] args) {
     41         
     42         //将来做插值的点列表
     43         List <PointStruct> pl=new  ArrayList<PointStruct>();
     44         
     45         //【1】 模拟 sin函数值  做初始化特定点(插值点或样条),  曲线将来就穿过下面几点    
     46         //        0.1    1    2    3    4
     47         //        0.099833417    0.841470985    0.909297427    0.141120008    0.61802
     48         
     49         pl.add(new PointStruct(0.1,0.099833417));
     50         pl.add(new PointStruct(1,0.841470985));
     51         pl.add(new PointStruct(2,0.909297427));
     52         pl.add(new PointStruct(3,0.141120008));
     53         pl.add(new PointStruct(4,0.61802));
     54      
     55         //【2】 添加 需要的未知点(新插值点), 为了使曲线光滑  采用小的步长 填充在已知点之间
     56         List <PointStruct> target=new  ArrayList<PointStruct>();        
     57         double step=0.1;        
     58         for(int k=0;k<pl.size();k++){
     59             
     60             if((k+1)<pl.size()){
     61                 double tmpd=0;
     62                 while(tmpd<pl.get(k+1).dx){
     63                     tmpd=tmpd+step;
     64                     target.add(new PointStruct(tmpd,0.0));
     65                 }
     66             }
     67         }
     68         
     69         //把点集合转化成为 x,y 各自的坐标点 Double[]集合 
     70         ArrayList tmp_x = getArrayfList(pl,"dx");
     71         ArrayList tmp_y = getArrayfList(pl,"dy");
     72         Double[] xspline=new Double[tmp_x.size()];
     73         Double[] yspline=new Double[tmp_x.size()];        
     74         for(int e=0;e<tmp_x.size();e++){
     75             xspline[e]=(Double) tmp_x.get(e);
     76             yspline[e]=(Double) tmp_y.get(e);
     77         } 
     78         
     79         //【3】根据 插值点初始化插值对象,并用spline样条函数进行计算(做三次样条插值运算)
     80         Interpolation ip = new Interpolation(xspline, yspline);
     81         for(int j=0;j<target.size();j++){
     82             target.get(j).dy=ip.spline(target.get(j).dx);        
     83         }
     84         
     85         //把新生成的样条添加到点集合中  做以后画图用 
     86         pl.addAll(target);
     87         
     88         //根据x点的大小进行点集合的排序
     89         Testspline t2=new Testspline();
     90         Collections.sort(pl, t2.new SortByX());
     91         
     92         //因为结果太小,所有必要放大一定度数,同时 Java画图最像是整数,所有把双精度转成整形
     93         int intScale=100; 
     94         for(PointStruct p:pl){
     95              p.ix=(int) (p.dx*intScale);
     96              p.iy=(int) (p.dy*intScale);
     97         }
     98         
     99         //查看中间结果 即画图所用到的所有点
    100         int times=0;
    101         for(PointStruct p:pl){
    102             System.out.println(" order: :"+times++ +"  p.ix:"+p.ix+"    p.iy:"+p.iy);
    103         }
    104         
    105         //【4】 调用画图类 画图
    106         Drawlineforspline dlfs=new Drawlineforspline(pl); 
    107         Mypanel myp=dlfs.new Mypanel();
    108         dlfs.add(myp); 
    109 
    110     }
    111 }

    依赖类:

    PointStruct

     1 package com.yang.logic;
     2 
     3 public class PointStruct {
     4     
     5     double dx;
     6     double dy;
     7     
     8     int ix;
     9     int iy;
    10     
    11     public PointStruct(double dx, double dy) {
    12         this.dx = dx;
    13         this.dy = dy;
    14     }
    15 
    16     public PointStruct(int ix, int iy) {
    17         this.ix = ix;
    18         this.iy = iy;
    19     }
    20     
    21     public PointStruct(double dx, double dy,boolean round) {
    22         this.ix = RoundF(dx);
    23         this.iy = RoundF(dy);
    24     }
    25     
    26     public int RoundF(double a){
    27         return (int) Math.round(a);
    28     }
    29 }
    View Code

    Interpolation

     1 package com.yang.logic;
     2 
     3 import java.util.Arrays;
     4 
     5 public class Interpolation {
     6 
     7     private int n;
     8     private Double[] xs;
     9     private Double[] ys;
    10      
    11     private boolean sp_initialized;
    12     private double[] sp_y2s;
    13 
    14     public Interpolation(Double[] _xs, Double[] _ys) {
    15         
    16         this.n = _xs.length;
    17         this.xs = Arrays.copyOf(_xs, _xs.length);
    18         this.ys = Arrays.copyOf(_ys, _ys.length);
    19         
    20         this.sp_initialized = false;
    21     } 
    22     
    23     public double spline(double x)
    24     {
    25         if (!this.sp_initialized) {
    26             // Assume Natural Spline Interpolation
    27             double p, qn, sig, un;
    28             double[] us;
    29             
    30             us = new double[n-1];
    31             sp_y2s = new double[n];
    32             us[0] = sp_y2s[0] = 0.0;
    33             
    34             for (int i=1; i<=n-2; i++) {
    35                 sig = (xs[i] - xs[i-1]) / (xs[i+1] - xs[i-1]);
    36                 p = sig * sp_y2s[i-1] + 2.0;
    37                 sp_y2s[i] = (sig - 1.0) / p;
    38                 us[i] = (ys[i+1] - ys[i]) / (xs[i+1] - xs[i]) - (ys[i] - ys[i-1]) / (xs[i] - xs[i-1]);
    39                 us[i] = (6.0 * us[i] / (xs[i+1] - xs[i-1]) - sig * us[i-1]) / p;
    40             }
    41             qn = un = 0.0;
    42             
    43             sp_y2s[n-1] = (un - qn * us[n-2]) / (qn * sp_y2s[n-2] + 1.0);
    44             for (int k=n-2; k>=0; k--) {
    45                 sp_y2s[k] = sp_y2s[k] * sp_y2s[k+1] + us[k];
    46             }
    47 
    48             this.sp_initialized = true;
    49         }
    50         
    51         int klo, khi, k;
    52         double h, b, a;
    53         
    54         klo = 0;
    55         khi = n-1;
    56         while (khi-klo > 1) {
    57             k = (khi+klo) >> 1;
    58             if (xs[k] > x)
    59                 khi = k;
    60             else
    61                 klo = k;
    62         }
    63         h = xs[khi] - xs[klo];
    64         if (h == 0.0) {
    65             throw new ArithmeticException();
    66         }
    67         a = (xs[khi] - x) / h;
    68         b = (x - xs[klo]) / h;
    69         return a*ys[klo] + b*ys[khi] + ((a*a*a-a)*sp_y2s[klo]+(b*b*b-b)*sp_y2s[khi])*(h*h)/6.0;
    70     }
    71 
    72 }
    View Code

    Drawlineforspline

     1 package com.yang.logic;
     2 
     3 import java.awt.Color;
     4 import java.awt.Graphics;
     5 import java.util.List;
     6 
     7 import javax.swing.JFrame;
     8 import javax.swing.JPanel;
     9 
    10 public class Drawlineforspline extends JFrame{
    11     
    12     private static final long serialVersionUID = 1L;
    13     List <PointStruct>plist;
    14      
    15     public Drawlineforspline(){
    16         init();
    17     }
    18     public Drawlineforspline(List<PointStruct> plist){
    19         init();
    20         this.plist=plist;
    21     }    
    22     
    23     private void init(){
    24         this.setTitle("drawline");
    25         this.setBounds(200, 200, 500, 400);
    26         this.setBackground(Color.white);
    27         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    28         this.setLocationRelativeTo(null);
    29         this.setVisible(true); 
    30     }
    31     
    32     public class Mypanel extends JPanel{     
    33         public void paint(Graphics g){
    34             g.setColor(Color.red);
    35             //System.out.println(plist.size());
    36             for(int i=0;i<plist.size()-1;i++){
    37                 g.drawLine(plist.get(i).ix, plist.get(i).iy, plist.get(i+1).ix, plist.get(i+1).iy);
    38             }         
    39         }
    40     }
    41 }
    View Code

    代码下载 地址

     转载请注明 http://www.cnblogs.com/rojas/p/4595509.html

  • 相关阅读:
    vector向量容器的一些基本操作
    OpenCV鼠标画图例程,鼠标绘制矩形
    网络安全学习笔记--《暗战强人:黑客攻防入门全程图解》
    遗传算法解决TSP问题实现以及与最小生成树的对比
    基于opencv的手写数字字符识别
    最小生成树
    opencv基本图像操作
    使用vs2010 opencv2.4.4编译release版本程序
    【machine translate】deep learning seq2seq
    【DL】物体识别与定位
  • 原文地址:https://www.cnblogs.com/rojas/p/4595509.html
Copyright © 2020-2023  润新知