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. CKEditor高级编辑器

    是否感觉后台分类描写叙述信息.商品描写叙述信息以及文章描写叙述信息 编写时很的不方便?有时候会将word的格式也复制过来了?那这个插件就比較适合了. 本插件使用CKEditor最新版本号,复制过来的内 ...

  2. CentOS 搭建 Mysql MMM 高可用架构

    环境 CentOS Mysql 5.1 前提 安装了EPEL,详细安装步骤请參照 http://blog.csdn.net/robinsonmhj/article/details/36184863 机 ...

  3. How to test Heat (by quqi99)

    作者:张华  发表于:2015-12-19版权声明:能够随意转载.转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 (http://blog.csdn.net/quqi99 ) Heat ...

  4. Python str 与 bytes 类型(Python2/3 对 str 的处理)

    本文均在 Python 3 下测试通过,python 2.x 会略有不同. 1. str/bytes >> s = '123' >> type(s) str >> ...

  5. installp 软件的4种状态

    安装和维护LPP软件     installp 对包提供了如下四种主要的操作: Apply Commit Reject Remove   webes.4.0.0.1 commited webes.4. ...

  6. Linux常用视频播放器

    1.SMplayer是一款跨平台的视频播放工具,可以支持大部分的视频和音频文件.它支持音频轨道切换.允许调节亮度.对比度.色调.饱和度.伽玛值,按照倍速.4倍速等多种速度回放.还可以进行音频和字幕延迟 ...

  7. php,javascript设置和读取cookie

    1.php设置cookie setcookie($name,$value,expire,path,domain,secrue); //$name:指的是cookie的名字:$value指的是cooki ...

  8. Mysql学习总结(19)——Mysql无法创建外键的原因

    在MySQL中创建外键时,经常会遇到问题而失败,这是因为Mysql中还有很多细节需要我们去留意,我自己总结并查阅资料后列出了以下几种常见原因. 1.  两个字段的类型或者大小不严格匹配.例如,如果一个 ...

  9. UVa 10101 - Bangla Numbers

    题目:将数字数转化成数字加单词的表示形式输出. 分析:数论.简单题.直接分成两部分除10000000的商和余数,分别输出就可以. 说明:注意输入为数字0的情况,还有long long类型防止溢出. # ...

  10. OJ刷题---猜算式

    题目要求: 输入代码: #include<iostream> using namespace std; void Calc(); int main() { Calc(); return 0 ...