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 即可. 效果如下:
随机推荐
- STL 源代码剖析 算法 stl_algo.h -- search
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search --------------------------------------- ...
- 记一次struts2漏洞修复带来的问题
struts2作为万年漏洞王,感觉已经被弃如敝屣了,除了一些古老的项目,比如我手上的一个项目,以前每次出现漏洞就如临大敌,手忙脚乱的赶在公司红头文件发出来前修复它.然后改了一两次后毅然决然用别的框架代 ...
- AngularJS初接触
todo.json [ { "action": "Buy Flowers", "done": false }, { "action ...
- android文本排布
首先看一幅图,是简书App的一篇文章的截图,如下: 图1,图2 上面两个图片都是文本的显示,但是由于有多种格式,所以较为复杂,例如其中有普通文本,还有加粗的文本,还有图文混排的显示等等. 一.解析HT ...
- vue中剖析中的一些方法
1 判断属性 71 -81 var hasOwnProperty = Object.prototype.hasOwnProperty; /** * Check whether the object h ...
- AIX 系统补丁升级步骤
AIX 系统补丁升级步骤 1.升级之前建议备份 rootvg (推荐) # smit mksysb 2.检查系统版本号 # oslevel -r 3.找到补丁光盘或者下载补丁,上传到服务器 ...
- 在Ubuntu14.04中配置mysql远程连接教程
上一篇文章,小编带大家学会了在Ubuntu14.04中安装MySQL,没有来得及上课的小伙伴们可以戳这篇文章:如何在Ubuntu14.04中安装mysql,今天给大家分享一下,如何简单的配置MySQL ...
- [USACO07JAN]平衡的阵容Balanced Lineup RMQ模板题
Code: #include<cstdio> #include<algorithm> using namespace std; const int maxn = 50000 + ...
- 干货分享 -- Math
昼猫笔记 JavaScript -- Math Math也是JS的内置对象,但是它不是一个构造函数,它属于一个工具类不用创建对象,它封装了数学运算相关的属性和方法,今天就来写下常用的函数[API(ap ...
- 2D上下文
js中说明的上下文表示的意思为C++中作用域(个人理解),因此2D上下文说明的是这个2D的作用域 像素:用来描述图片清晰度的小矩阵 填充和描边 填充:context.fillStyle = " ...