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

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

  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. Struts之Token机制

    Struts的Token(令牌)机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配.在处理完该请求 ...

  2. 数据性能调校——查看最耗资源的各种SQL

    从计划高速缓存中清除查询计划 DBCC FREEPROCCACHE 清除缓存中的过程 DBCC DROPCLEANBUFFERS清除内存中的数据 SELECT DB_ID('你的数据库名') tota ...

  3. 创建spring boot 项目所遇到的问题

    1.添加完MySQL和jdbc约束后,在配置文件内spring.datasource.driver-class-name=com.mysql.jdbc.Driver 报错,显示找不到驱动包,原因是: ...

  4. LR controller 参数化

    我在这里写的是在controller设置了vuser后的运行结果. 对于select Next Row和Update Value On的理解都是个人根据运行结果分析得出的理解. 而且主要写的unuqu ...

  5. iOS 11 Xcode9开发 新特性学习 (警告篇)

    最新版本SDK优化了开发体验,编译过程会提供更多提示警告,建议你修改.这些功能也可以自主选择用或者不用,当然,苹果喜欢你用他推荐的东西... 1 . @avalibale 语法,同步判断当前iOS系统 ...

  6. IM协议

    四种协议英文全称与简称 1->IMPP(Instant Messaging And PresenceProtocol):即时信息和空间协议 2->PRIM(Presence and Ins ...

  7. VC引用动态库

    1. 程序所在目录 2. 进程当前目录 3. 系统目录(C:\WINDOWS\System32) 4. Windows目录(C:\WINDOWS) 5. PATH环境变量指向的目录

  8. des加密——补齐

    下面这个网址(英文)介绍的比较全面. http://www.di-mgt.com.au/cryptopad.html

  9. NAS、SAN、DAS 说明

    NAS 说明 1.NAS(Network Attached Storage:网络附属存储) 2.NAS 是一种采用直接与网络介质相连的特殊设备实现数据存储的机制. 3.NAS本身能够支持多种协议(如N ...

  10. B-树 C++模板类封装(有图有真相)

    定义: 一棵m阶B-树是拥有以下性质的多路查找树: 1.非叶子结点的根结点至少拥有两棵子树: 2.每一个非根且非叶子的结点含有k-1个关键字以及k个子树,其中⌈m/2⌉≤k≤m: 3.每一个叶子结点都 ...