java 三次样条插值 画光滑曲线 例子
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 三次样条插值 画光滑曲线 例子的更多相关文章
- 三次样条插值 cubic spline interpolation
什么是三次样条插值 插值(interpolation)是在已知部分数据节点(knots)的情况下,求解经过这些已知点的曲线, 然后根据得到的曲线进行未知位置点函数值预测的方法(未知点在上述已知点自变量 ...
- iOS-CGContextRef画各种图形例子
iOS-CGContextRef画各种图形例子 绘制效果图 绘制代码 - (void)drawRect:(CGRect)rect { //一个不透明类型的Quartz 2D绘画环境,相当于一个画布,你 ...
- WPF将点列连接成光滑曲线——贝塞尔曲线
原文:WPF将点列连接成光滑曲线--贝塞尔曲线 背景 最近在写一个游戏场景编辑器,虽然很水,但是还是遇到了不少问题.连接离散个点列成为光滑曲线就是一个问题.主要是为了通过关键点产生2D的赛道场景.总之 ...
- java 多线程——quartz 定时调度的例子
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- java 多线程——一个定时调度的例子
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- MATLAB画ROC曲线,及计算AUC值
根据决策值和真实标签画ROC曲线,同时计算AUC的值 步骤: 根据决策值和真实标签画ROC曲线,同时计算AUC的值: 计算算法的决策函数值deci 根据决策函数值deci对真实标签y进行降序排序,得到 ...
- java操作xml的一个小例子
最近两天公司事比较多,这两天自己主要跟xml打交道,今天更一下用java操作xml的一个小例子. 原来自己操作xml一直用这个包:xstream-1.4.2.jar.然后用注解的方式,很方便,自己只要 ...
- 用JAVA中BufferedImage画出漂亮的验证码点击变化
如果我们想用JAVA中BufferedImage画出漂亮的验证码点击变化怎么实现呢,类似这样: 点击变化,以下是实现过程,直接上代码: 首先前台:<i><img style=&quo ...
- 用 Excel 画正态分布曲线
用 Excel 画正态分布曲线 群里有小伙伴询问一道曲线题,有小伙伴看出来是正态分布曲线,刚好之前有大概了解一下正态分布. 可以在 Excel 很容易实现. 使用 NORMDIST 即可. 效果如下:
随机推荐
- 软件project总结
软件project的文档完结了.在这里面学到了好多东西.也通过它分析了对机房收费系统进行了更加具体的分析.尽管早就明确了之间的联系,可是越温习越体会到逻辑的重要性和全心全意为人民服务的精神. 这些文档 ...
- Linux下FTPserver的实现(仿vsftpd)
继上一篇博文实现Linux下的shell后,我们进一步利用网络编程和系统编程的知识实现Linux下的FTPserver.我们以vsftpd为原型并实现了其大部分的功能.因为篇幅和时间的关系,这里不再一 ...
- [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 ...
- [Recompose] Stream Props to React Children with RxJS
You can decouple the parent stream Component from the mapped React Component by using props.children ...
- hdu 4324 Triangle LOVE(拓扑判环)
Triangle LOVE Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) To ...
- C++学习笔记11-面向对象2
1. 仅仅能初始化直接基类 一个类仅仅能初始化自己的直接基类.直接就是在派生列表中指定的类.假设类C 从类B 派生,类B 从类A 派生,则B 是C 的直接基类.尽管每一个C 类对象包括一个A 类部 ...
- Spring MVC -- UEditor 编辑器整合入门
仅作为入门测试...... 下载UEditor资源 使用maven项目 <!-- 上传文件的支持 --> <dependency> <groupId>commons ...
- HDU 5375 Gray Code 动归
题意:给你一串不确定的二进制码,其对应的格雷码的每一位有对应的权值,问转换成的格雷码的能取到的最大权值是多少. 思路:没有思路,乱搞也AC #pragma comment(linker, " ...
- 开启Windows 7远程桌面功能的做法
作者:朱金灿 来源:http://blog.csdn.net/clever101 本设置方法同样适用用Vista和Windows Server 2008. 1.依次点击"开始"菜单 ...
- Cisco交换机端口安全
Cisco交换机端口安全 通过端口设置,可以限制允许访问交换机上某个端口的MAC地址以及IP(可选)来实现严格控制对该端口的输入,最终确保网络接入安全.配置网络安全时应该注意如下问题: 1 ...