井眼轨迹的三次样条插值 (vs + QT + coin3d)
井眼轨迹数据的测量值是离散的,根据某些测斜公式,我们可以计算出离散的三维的井眼轨迹坐标,但是真实的井眼轨迹是一条平滑的曲线,这就需要我们对测斜数据进行插值,使井眼轨迹变得平滑,我暂时决定使用三次样条进行插值。(但是插值出来的点,并不是真实的测量值,并不能真实的反映经验轨迹的实际情况,仅供分析使用)
三次样条函数:(函数是在网上找到的,测试可用)
ThreeSpline.h
#pragma once
class ThreeSpline
{
public:
ThreeSpline(void);
~ThreeSpline(void);
// 利用求出的二阶导数求给定点值(结合Spline1,Spline2)
void Splint(double *xa,double *ya,double *m,int n,double &x,double &y);
//对一系列点求二阶偏导数,点横坐标单调递增(I型边界)(结合Spline)一阶偏导数
void Spline1(double *xa,double *ya,int n,double *&m,double bound1,double bound2);
//对一系列点求二阶偏导数,点横坐标单调递增(II型边界)(结合Spline)二阶偏导数
void Spline2(double *xa,double *ya,int n,double *&m,double bound1=,double bound2=); };
ThreeSpline.cpp
#include "ThreeSpline.h" ThreeSpline::ThreeSpline(void)
{
} ThreeSpline::~ThreeSpline(void)
{
}
//================================================================
// 函数功能: 利用求出的二阶导数求给定点值(结合Spline1,Spline2)
// 输入参数: *xa 为横坐标值,ya为纵坐标值,n为点个数,m为二阶偏导数
// x为给定点,y接收插出来的值
// 返回值: 无返回值
//================================================================
void ThreeSpline::Splint(double *xa,double *ya,double *m,int n,double &x,double &y)
{
int klo,khi,k;
klo=; khi=n-;
double hh,bb,aa; while(khi-klo>) // 二分法查找x所在区间段
{
k=(khi+klo)>>;
if(xa[k]>x) khi=k;
else klo=k;
}
hh=xa[khi]-xa[klo]; aa=(xa[khi]-x)/hh;
bb=(x-xa[klo])/hh; y=aa*ya[klo]+bb*ya[khi]+((aa*aa*aa-aa)*m[klo]+(bb*bb*bb-bb)*m[khi])*hh*hh/6.0;
}
//===========================================================================
// 函数功能: 对一系列点求二阶偏导数,点横坐标单调递增(I型边界)(结合Spline)
// 输入参数: *xa 为横坐标值,ya为纵坐标值,n为点个数,m为二阶偏导数(输出值)
// bound1、bound2为边界点一阶偏导数
// 返回值: 无返回值
//
//===========================================================================
void ThreeSpline::Spline1(double *xa,double *ya,int n,double *&m,double bound1,double bound2)
{
// 追赶法解方程求二阶偏导数
double f1=bound1,f2=bound2; double *a=new double[n]; // a:稀疏矩阵最下边一串数
double *b=new double[n]; // b:稀疏矩阵最中间一串数
double *c=new double[n]; // c:稀疏矩阵最上边一串数
double *d=new double[n]; double *f=new double[n]; double *bt=new double[n];
double *gm=new double[n]; double *h=new double[n];
m=new double[n]; for(int i=;i<n;i++) b[i]=; // 中间一串数为2
for(int i=;i<n-;i++) h[i]=xa[i+]-xa[i]; // 各段步长
for(int i=;i<n-;i++) a[i]=h[i-]/(h[i-]+h[i]);
a[n-]=; c[]=;
for(int i=;i<n-;i++) c[i]=h[i]/(h[i-]+h[i]); for(int i=;i<n-;i++)
f[i]=(ya[i+]-ya[i])/(xa[i+]-xa[i]); d[]=*(f[]-f1)/h[];
d[n-]=*(f2-f[n-])/h[n-]; for(int i=;i<n-;i++) d[i]=*(f[i]-f[i-])/(h[i-]+h[i]); bt[]=c[]/b[]; // 追赶法求解方程
for(int i=;i<n-;i++) bt[i]=c[i]/(b[i]-a[i]*bt[i-]); gm[]=d[]/b[];
for(int i=;i<=n-;i++) gm[i]=(d[i]-a[i]*gm[i-])/(b[i]-a[i]*bt[i-]); m[n-]=gm[n-];
for(int i=n-;i>=;i--) m[i]=gm[i]-bt[i]*m[i+]; delete a;
delete b;
delete c;
delete d;
delete gm;
delete bt;
delete f;
delete h;
}
//===========================================================================
// 函数功能: 对一系列点求二阶偏导数,点横坐标单调递增(II型边界)(结合Spline)
// 输入参数: *xa 为横坐标值,ya为纵坐标值,n为点个数,m为二阶偏导数(输出值)
// bound1、bound2为边界点二阶偏导数,当bound1和bound2不给值时则使用
// 默认值0,即自然边界
// 返回值: 无返回值
//
// 作者: 蒋锦朋 1034378054@qq.com
// 单位: 中国地质大学(武汉) 地球物理与空间信息学院
// 日期: 2014/12/03
//===========================================================================
void ThreeSpline::Spline2(double *xa,double *ya,int n,double *&m,double bound1,double bound2)
{
// 追赶法解方程求二阶偏导数
double f11=bound1,f22=bound2; double *a=new double[n]; // a:稀疏矩阵最下边一串数
double *b=new double[n]; // b:稀疏矩阵最中间一串数
double *c=new double[n]; // c:稀疏矩阵最上边一串数
double *d=new double[n]; double *f=new double[n]; double *bt=new double[n];
double *gm=new double[n]; double *h=new double[n];
m=new double[n]; for(int i=;i<n;i++) b[i]=;
for(int i=;i<n-;i++) h[i]=xa[i+]-xa[i];
for(int i=;i<n-;i++) a[i]=h[i-]/(h[i-]+h[i]);
a[n-]=; c[]=;
for(int i=;i<n-;i++) c[i]=h[i]/(h[i-]+h[i]); for(int i=;i<n-;i++)
f[i]=(ya[i+]-ya[i])/(xa[i+]-xa[i]); //d[0]=6*(f[0]-f1)/h[0];
//d[n-1]=6*(f2-f[n-2])/h[n-2]; for(int i=;i<n-;i++) d[i]=*(f[i]-f[i-])/(h[i-]+h[i]); d[]=d[]-a[]*f11;
d[n-]=d[n-]-c[n-]*f22;
//bt[0]=c[0]/b[0];
//for(int i=1;i<n-1;i++) bt[i]=c[i]/(b[i]-a[i]*bt[i-1]); //gm[0]=d[0]/b[0];
//for(int i=1;i<=n-1;i++) gm[i]=(d[i]-a[i]*gm[i-1])/(b[i]-a[i]*bt[i-1]); //m[n-1]=gm[n-1];
//for(int i=n-2;i>=0;i--) m[i]=gm[i]-bt[i]*m[i+1];
// 追赶法求解方程
bt[]=c[]/b[];
for(int i=;i<n-;i++) bt[i]=c[i]/(b[i]-a[i]*bt[i-]); gm[]=d[]/b[];
for(int i=;i<=n-;i++) gm[i]=(d[i]-a[i]*gm[i-])/(b[i]-a[i]*bt[i-]); m[n-]=gm[n-];
for(int i=n-;i>=;i--) m[i]=gm[i]-bt[i]*m[i+]; m[]=f11;
m[n-]=f22; delete a;
delete b;
delete c;
delete d;
delete gm;
delete bt;
delete f;
delete h;
}
调用方法
void CMathTestView::OnSpline()
{
// TODO: 在此添加命令处理程序代码
double x[]={0.52,,17.95,28.65,50.65,104.6,156.6,260.7,364.4,,,};
double y[]={5.28794,13.84,20.2,24.9,31.1,36.5,36.6,,20.9,7.8,1.5,0.2}; double xd[]={,,,,,,,};
double f1=1.86548,f2=-0.046115;
double f11=-0.279319,f22=0.0111560;
CSpline spline;
double *m;
spline.Spline2(x,y,,m,f11,f22); CString showstr;
showstr.Empty();
for(int i=;i<;i++)
{
double yd;
spline.Splint(x,y,m,,xd[i],yd);
CString s;
s.Format(_T("%lf %lf\n"),xd[i],yd);
showstr+=s;
}
delete m;
MessageBox(showstr);
}
仅仅记录测方法的使用过程
在使用过程中,要对横坐标进行从小到大的排序,还有去除重复点,否则结果出错
井眼轨迹的三次样条插值 (vs + QT + coin3d)的更多相关文章
- 三次样条插值matlab实现
三次样条插值matlab实现 %三次样条差值-matlab通用程序 - zhangxiaolu2015的专栏 - CSDN博客 https://blog.csdn.net/zhangxiaolu201 ...
- java 三次样条插值 画光滑曲线 例子
java 三次样条插值 画光滑曲线 例子 主要是做数值拟合,根据sin函数采点,取得数据后在java中插值并在swing中画出曲线,下面为截图 不光滑和光滑曲线前后对比: 代码: 执行类: p ...
- 三次样条插值 cubic spline interpolation
什么是三次样条插值 插值(interpolation)是在已知部分数据节点(knots)的情况下,求解经过这些已知点的曲线, 然后根据得到的曲线进行未知位置点函数值预测的方法(未知点在上述已知点自变量 ...
- 平滑算法:三次样条插值(Cubic Spline Interpolation)
https://blog.csdn.net/left_la/article/details/6347373 感谢强大的google翻译. 我从中认识到了航位推算dead reckoning,立方体样条 ...
- 数值计算方法实验之按照按三弯矩方程及追赶法的三次样条插值 (MATLAB 代码)
一.实验目的 在已知f(x),x∈[a,b]的表达式,但函数值不便计算,或不知f(x),x∈[a,b]而又需要给出其在[a,b]上的值时,按插值原则f(xi)= yi(i= 0,1…….,n)求出简单 ...
- VS2010 + QT 5 +open inventor 环境配置
本科毕业设计做的是 随钻测量的井眼轨迹和测井曲线的三维显示 要求的环境是 QT + Open Inventor 在寒假开学前,打算将环境配置好,开学后再正式编码实现,可是....环境也 ...
- 从零开始一起学习SLAM | 用四元数插值来对齐IMU和图像帧
视觉 Vs. IMU 小白:师兄,好久没见到你了啊,我最近在看IMU(Inertial Measurement Unit,惯性导航单元)相关的东西,正好有问题求助啊 师兄:又遇到啥问题啦? 小白:是这 ...
- 建模算法(八)——插值
插值:求过已知有限个数据点的近似函数 拟合:已知有限个数据点,求近似函数,不要求过已知数据点,只要求在某种意义下在这些点的误差最小 (一)插值方法 一.拉格朗日多项式插值 1.插值多项式 就是做出一个 ...
- Matlab学习第二天 利用插值
插入值一切手段: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDQ5MjI1Nw==/font/5a6L5L2T/fontsize/400/fi ...
随机推荐
- JavaScript数据结构与算法-链表练习
链表的实现 一. 单向链表 // Node类 function Node (element) { this.element = element; this.next = null; } // Link ...
- echarts系列之动态加载数据
1.echarts学习前言 最近接触到echarts,发现数据可视化真的是魅力无穷啊,各种变幻的曲线交错,以及‘曼妙’的动画效果真是让人如痴如醉! 下面就来一起欣赏她的美... “ ECharts是中 ...
- unity 人物描边锯齿
项目原来实现描边用了2个pass,一个pass cull back 渲染政策,一个cull front 渲染轮廓,但问题是锯齿特别明显 尝试了下边缘光实现描边,效果更不行,边线是断的
- golang接收get/post请求并返回json数据
// @router /d2 [post] func (c *MainController) D2() { // jsoninfo := c.GetString("ok") // ...
- shell方式切割tomcat日志
#!/bin/bash while true do cd /usr/local/tomcat/logs d=`date +%Y%m%d` d15=`date -d'15 day ago' +%Y%m% ...
- "export" in SHELL
在shell中,若某一变量需要在随后的子程序中运行,则需要以 export 来使变量变成环境变量: export var export的用法总结: 1:一个shell中用export定义的变量,只对当 ...
- Java 如何读取resources
Sample in Github 1.一般使用Maven创建Java工程,代码文件在src/main/java文件夹中,资源文件在src/main/resources文件夹中,Java代码为什么可以读 ...
- python中的关键字global和nonlocal
知识点: global将一个变量变为全局变量 nonlocal改变最近的变量,又不是全局作用. 1.global 在python中,当引用一个变量的时候,对这个变量的搜索按找本地作用域(Local). ...
- [笔记]如何将传统的回调函数转换为C#5.0支持的await格式
C#5.0引入了编译器支持的 async 和 await 关键字,这就为开发者提供了使用同步思想写异步代码的方便. 但是有些传统函数仅提供了异步回调实现,如何对其封装,使其可以享受await的便利呢? ...
- 利用onresize使得div可以随着屏幕大小而自适应的代码
原文:http://www.jb51.net/article/21831.htm 当我们让div居中时候,一般有两种方法,一种是固定左右宽度,也就是使用像素绝对定位:另一种是用百分比来相对定位,在这种 ...