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

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

  

代码:

执行类:

 package com.yang.logic;

 import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; import com.yang.logic.Drawlineforspline.Mypanel; public class Testspline { // 根据X排序
class SortByX implements Comparator {
public int compare(Object obj1, Object obj2) {
PointStruct point1 = (PointStruct) obj1;
PointStruct point2 = (PointStruct) obj2;
if (point1.dx > point2.dx)
return 1;
else
return 0;
}
}
//转化成数组
public static ArrayList<Double> getArrayfList(List<PointStruct> l, String type) {
ArrayList<Double> tmplist = new ArrayList<Double>();
for (PointStruct p : l) {
if (type == "ix") {
tmplist.add((double) p.ix);
} else if (type == "iy") {
tmplist.add((double) p.iy);
} else if (type == "dx") {
tmplist.add(p.dx);
} else if (type == "dy") {
tmplist.add(p.dy);
}
}
return tmplist;
} public static void main(String[] args) { //将来做插值的点列表
List <PointStruct> pl=new ArrayList<PointStruct>(); //【1】 模拟 sin函数值 做初始化特定点(插值点或样条), 曲线将来就穿过下面几点
// 0.1 1 2 3 4
// 0.099833417 0.841470985 0.909297427 0.141120008 0.61802 pl.add(new PointStruct(0.1,0.099833417));
pl.add(new PointStruct(1,0.841470985));
pl.add(new PointStruct(2,0.909297427));
pl.add(new PointStruct(3,0.141120008));
pl.add(new PointStruct(4,0.61802)); //【2】 添加 需要的未知点(新插值点), 为了使曲线光滑 采用小的步长 填充在已知点之间
List <PointStruct> target=new ArrayList<PointStruct>();
double step=0.1;
for(int k=0;k<pl.size();k++){ if((k+1)<pl.size()){
double tmpd=0;
while(tmpd<pl.get(k+1).dx){
tmpd=tmpd+step;
target.add(new PointStruct(tmpd,0.0));
}
}
} //把点集合转化成为 x,y 各自的坐标点 Double[]集合
ArrayList tmp_x = getArrayfList(pl,"dx");
ArrayList tmp_y = getArrayfList(pl,"dy");
Double[] xspline=new Double[tmp_x.size()];
Double[] yspline=new Double[tmp_x.size()];
for(int e=0;e<tmp_x.size();e++){
xspline[e]=(Double) tmp_x.get(e);
yspline[e]=(Double) tmp_y.get(e);
} //【3】根据 插值点初始化插值对象,并用spline样条函数进行计算(做三次样条插值运算)
Interpolation ip = new Interpolation(xspline, yspline);
for(int j=0;j<target.size();j++){
target.get(j).dy=ip.spline(target.get(j).dx);
} //把新生成的样条添加到点集合中 做以后画图用
pl.addAll(target); //根据x点的大小进行点集合的排序
Testspline t2=new Testspline();
Collections.sort(pl, t2.new SortByX()); //因为结果太小,所有必要放大一定度数,同时 Java画图最像是整数,所有把双精度转成整形
int intScale=100;
for(PointStruct p:pl){
p.ix=(int) (p.dx*intScale);
p.iy=(int) (p.dy*intScale);
} //查看中间结果 即画图所用到的所有点
int times=0;
for(PointStruct p:pl){
System.out.println(" order: :"+times++ +" p.ix:"+p.ix+" p.iy:"+p.iy);
} //【4】 调用画图类 画图
Drawlineforspline dlfs=new Drawlineforspline(pl);
Mypanel myp=dlfs.new Mypanel();
dlfs.add(myp); }
}

依赖类:

PointStruct

 package com.yang.logic;

 public class PointStruct {

     double dx;
double dy; int ix;
int iy; public PointStruct(double dx, double dy) {
this.dx = dx;
this.dy = dy;
} public PointStruct(int ix, int iy) {
this.ix = ix;
this.iy = iy;
} public PointStruct(double dx, double dy,boolean round) {
this.ix = RoundF(dx);
this.iy = RoundF(dy);
} public int RoundF(double a){
return (int) Math.round(a);
}
}

Interpolation

 package com.yang.logic;

 import java.util.Arrays;

 public class Interpolation {

     private int n;
private Double[] xs;
private Double[] ys; private boolean sp_initialized;
private double[] sp_y2s; public Interpolation(Double[] _xs, Double[] _ys) { this.n = _xs.length;
this.xs = Arrays.copyOf(_xs, _xs.length);
this.ys = Arrays.copyOf(_ys, _ys.length); this.sp_initialized = false;
} public double spline(double x)
{
if (!this.sp_initialized) {
// Assume Natural Spline Interpolation
double p, qn, sig, un;
double[] us; us = new double[n-1];
sp_y2s = new double[n];
us[0] = sp_y2s[0] = 0.0; for (int i=1; i<=n-2; i++) {
sig = (xs[i] - xs[i-1]) / (xs[i+1] - xs[i-1]);
p = sig * sp_y2s[i-1] + 2.0;
sp_y2s[i] = (sig - 1.0) / p;
us[i] = (ys[i+1] - ys[i]) / (xs[i+1] - xs[i]) - (ys[i] - ys[i-1]) / (xs[i] - xs[i-1]);
us[i] = (6.0 * us[i] / (xs[i+1] - xs[i-1]) - sig * us[i-1]) / p;
}
qn = un = 0.0; sp_y2s[n-1] = (un - qn * us[n-2]) / (qn * sp_y2s[n-2] + 1.0);
for (int k=n-2; k>=0; k--) {
sp_y2s[k] = sp_y2s[k] * sp_y2s[k+1] + us[k];
} this.sp_initialized = true;
} int klo, khi, k;
double h, b, a; klo = 0;
khi = n-1;
while (khi-klo > 1) {
k = (khi+klo) >> 1;
if (xs[k] > x)
khi = k;
else
klo = k;
}
h = xs[khi] - xs[klo];
if (h == 0.0) {
throw new ArithmeticException();
}
a = (xs[khi] - x) / h;
b = (x - xs[klo]) / h;
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;
} }

Drawlineforspline

 package com.yang.logic;

 import java.awt.Color;
import java.awt.Graphics;
import java.util.List; import javax.swing.JFrame;
import javax.swing.JPanel; public class Drawlineforspline extends JFrame{ private static final long serialVersionUID = 1L;
List <PointStruct>plist; public Drawlineforspline(){
init();
}
public Drawlineforspline(List<PointStruct> plist){
init();
this.plist=plist;
} private void init(){
this.setTitle("drawline");
this.setBounds(200, 200, 500, 400);
this.setBackground(Color.white);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
} public class Mypanel extends JPanel{
public void paint(Graphics g){
g.setColor(Color.red);
//System.out.println(plist.size());
for(int i=0;i<plist.size()-1;i++){
g.drawLine(plist.get(i).ix, plist.get(i).iy, plist.get(i+1).ix, plist.get(i+1).iy);
}
}
}
}

代码下载 地址

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

java 三次样条插值 画光滑曲线 例子的更多相关文章

  1. 三次样条插值 cubic spline interpolation

    什么是三次样条插值 插值(interpolation)是在已知部分数据节点(knots)的情况下,求解经过这些已知点的曲线, 然后根据得到的曲线进行未知位置点函数值预测的方法(未知点在上述已知点自变量 ...

  2. iOS-CGContextRef画各种图形例子

    iOS-CGContextRef画各种图形例子 绘制效果图 绘制代码 - (void)drawRect:(CGRect)rect { //一个不透明类型的Quartz 2D绘画环境,相当于一个画布,你 ...

  3. WPF将点列连接成光滑曲线——贝塞尔曲线

    原文:WPF将点列连接成光滑曲线--贝塞尔曲线 背景 最近在写一个游戏场景编辑器,虽然很水,但是还是遇到了不少问题.连接离散个点列成为光滑曲线就是一个问题.主要是为了通过关键点产生2D的赛道场景.总之 ...

  4. java 多线程——quartz 定时调度的例子

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  5. java 多线程——一个定时调度的例子

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  6. MATLAB画ROC曲线,及计算AUC值

    根据决策值和真实标签画ROC曲线,同时计算AUC的值 步骤: 根据决策值和真实标签画ROC曲线,同时计算AUC的值: 计算算法的决策函数值deci 根据决策函数值deci对真实标签y进行降序排序,得到 ...

  7. java操作xml的一个小例子

    最近两天公司事比较多,这两天自己主要跟xml打交道,今天更一下用java操作xml的一个小例子. 原来自己操作xml一直用这个包:xstream-1.4.2.jar.然后用注解的方式,很方便,自己只要 ...

  8. 用JAVA中BufferedImage画出漂亮的验证码点击变化

    如果我们想用JAVA中BufferedImage画出漂亮的验证码点击变化怎么实现呢,类似这样: 点击变化,以下是实现过程,直接上代码: 首先前台:<i><img style=&quo ...

  9. 用 Excel 画正态分布曲线

    用 Excel 画正态分布曲线 群里有小伙伴询问一道曲线题,有小伙伴看出来是正态分布曲线,刚好之前有大概了解一下正态分布. 可以在 Excel 很容易实现. 使用 NORMDIST 即可. 效果如下:

随机推荐

  1. 软件project总结

    软件project的文档完结了.在这里面学到了好多东西.也通过它分析了对机房收费系统进行了更加具体的分析.尽管早就明确了之间的联系,可是越温习越体会到逻辑的重要性和全心全意为人民服务的精神. 这些文档 ...

  2. Linux下FTPserver的实现(仿vsftpd)

    继上一篇博文实现Linux下的shell后,我们进一步利用网络编程和系统编程的知识实现Linux下的FTPserver.我们以vsftpd为原型并实现了其大部分的功能.因为篇幅和时间的关系,这里不再一 ...

  3. [Poi] Use Markdown as React Components by Adding a Webpack Loader to Poi

    Poi ships with many webpack loaders included, but you may run into scenarios where you'll need to cu ...

  4. [Recompose] Stream Props to React Children with RxJS

    You can decouple the parent stream Component from the mapped React Component by using props.children ...

  5. hdu 4324 Triangle LOVE(拓扑判环)

    Triangle LOVE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) To ...

  6. C++学习笔记11-面向对象2

     1.  仅仅能初始化直接基类 一个类仅仅能初始化自己的直接基类.直接就是在派生列表中指定的类.假设类C 从类B 派生,类B 从类A 派生,则B 是C 的直接基类.尽管每一个C 类对象包括一个A 类部 ...

  7. Spring MVC -- UEditor 编辑器整合入门

    仅作为入门测试...... 下载UEditor资源 使用maven项目 <!-- 上传文件的支持 --> <dependency> <groupId>commons ...

  8. HDU 5375 Gray Code 动归

    题意:给你一串不确定的二进制码,其对应的格雷码的每一位有对应的权值,问转换成的格雷码的能取到的最大权值是多少. 思路:没有思路,乱搞也AC #pragma comment(linker, " ...

  9. 开启Windows 7远程桌面功能的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 本设置方法同样适用用Vista和Windows Server 2008. 1.依次点击"开始"菜单 ...

  10. Cisco交换机端口安全

    Cisco交换机端口安全       通过端口设置,可以限制允许访问交换机上某个端口的MAC地址以及IP(可选)来实现严格控制对该端口的输入,最终确保网络接入安全.配置网络安全时应该注意如下问题: 1 ...