井眼轨迹数据的测量值是离散的,根据某些测斜公式,我们可以计算出离散的三维的井眼轨迹坐标,但是真实的井眼轨迹是一条平滑的曲线,这就需要我们对测斜数据进行插值,使井眼轨迹变得平滑,我暂时决定使用三次样条进行插值。(但是插值出来的点,并不是真实的测量值,并不能真实的反映经验轨迹的实际情况,仅供分析使用)

  三次样条函数:(函数是在网上找到的,测试可用)

  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)的更多相关文章

  1. 三次样条插值matlab实现

    三次样条插值matlab实现 %三次样条差值-matlab通用程序 - zhangxiaolu2015的专栏 - CSDN博客 https://blog.csdn.net/zhangxiaolu201 ...

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

    java 三次样条插值 画光滑曲线 例子 主要是做数值拟合,根据sin函数采点,取得数据后在java中插值并在swing中画出曲线,下面为截图  不光滑和光滑曲线前后对比:    代码: 执行类: p ...

  3. 三次样条插值 cubic spline interpolation

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

  4. 平滑算法:三次样条插值(Cubic Spline Interpolation)

    https://blog.csdn.net/left_la/article/details/6347373 感谢强大的google翻译. 我从中认识到了航位推算dead reckoning,立方体样条 ...

  5. 数值计算方法实验之按照按三弯矩方程及追赶法的三次样条插值 (MATLAB 代码)

    一.实验目的 在已知f(x),x∈[a,b]的表达式,但函数值不便计算,或不知f(x),x∈[a,b]而又需要给出其在[a,b]上的值时,按插值原则f(xi)= yi(i= 0,1…….,n)求出简单 ...

  6. VS2010 + QT 5 +open inventor 环境配置

    本科毕业设计做的是   随钻测量的井眼轨迹和测井曲线的三维显示  要求的环境是  QT +  Open Inventor    在寒假开学前,打算将环境配置好,开学后再正式编码实现,可是....环境也 ...

  7. 从零开始一起学习SLAM | 用四元数插值来对齐IMU和图像帧

    视觉 Vs. IMU 小白:师兄,好久没见到你了啊,我最近在看IMU(Inertial Measurement Unit,惯性导航单元)相关的东西,正好有问题求助啊 师兄:又遇到啥问题啦? 小白:是这 ...

  8. 建模算法(八)——插值

    插值:求过已知有限个数据点的近似函数 拟合:已知有限个数据点,求近似函数,不要求过已知数据点,只要求在某种意义下在这些点的误差最小 (一)插值方法 一.拉格朗日多项式插值 1.插值多项式 就是做出一个 ...

  9. Matlab学习第二天 利用插值

    插入值一切手段: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDQ5MjI1Nw==/font/5a6L5L2T/fontsize/400/fi ...

随机推荐

  1. extract

    w http://php.net/manual/en/function.extract.php <?php /* Suppose that $var_array is an array retu ...

  2. jQuery获取input复选框的值

    var ipResolveValue =[]; //定义一个空数组$("input[name='ipResolve']:checked").each(function(){   / ...

  3. python作用域和JavaScript作用域

    JavaScript 一.JavaScript中无块级作用域 一个大括号一个作用域,就属于块级作用域,在Java和c#才存在块级作用域 function Main(){ if(1==1){ var n ...

  4. PopuWindow和软件盘共存时的设置

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/mingyue_1128/article/details/32316069 一.键盘不消失,popuw ...

  5. node.js及node-inspector的调试方法

    1.先运行 $ node --debug-brk test.js 2.再在新的窗口运行: $ node-inspector 3.再打开Chrome浏览器输入node-inspector提示的地址,就会 ...

  6. 每天一个Linux命令(46)ifconfig命令

    在windows系统中,ipconfig命令行工具被用来获取网络接口配置信息并对此进行修改.Linux系统拥有一个类似的工具,也就是ifconfig(interfaces config).     ( ...

  7. JSP笔记01——尝试

    JSP ————> servlet 我的第1个Java Web应用程序——index.jsp 我的第2个Java Web应用程序——welcome-file 我的第3个Java Web应用程序— ...

  8. Python编程-常用模块及方法

    常用模块介绍 一.time模块 在Python中,通常有这几种方式来表示时间: 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量.我们运行 ...

  9. start、run、join

    首先得了解什么是主线程,当Java程序启动时,一个线程立刻运行,该线程通常叫做程序的主线程(main thread).主线程的重要性体现在两方面:1. 它是产生其他子线程的线程:2. 通常它必须最后完 ...

  10. BYTE、HANDEL、DWORD等的定义

    有时候引入第三方库之后,可能会存在标题的这些变量没有定义,原来这些变量都定义在windows.h里面,包含进去就行了(Qt的MSVC编译器)