井眼轨迹的三次样条插值 (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 ...
随机推荐
- 【题解】Zap(莫比乌斯反演)
[题解]Zap(莫比乌斯反演) 裸题... 直接化吧 [P3455 POI2007]ZAP-Queries 所有除法默认向下取整 \[ \Sigma_{i=1}^x\Sigma_{j=1}^y[(i, ...
- LINUX 文件/组/帮助/权限/文件压缩/管道
Linux文件/目录详解 常用文件路径的作用 /var/log/messages 系统类的日志文件 /var/log/secure 登录日志文件 /var/spool/cron 定时任务目录 /etc ...
- 20171104 DOI Excel 导出
1. OAOR 创建模板, Class name:SOFFICEINTEGRATIONClass type: OTObject key: ZZCSDRP_0030 2.双击表模板创建Excel 模 ...
- 剑指offer 面试36题
面试36题: 题:二叉搜索树与双向链表 题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 解题思路一:由于输入的一个二叉搜索树, ...
- Django——Session源码分析
首先我们导入django.contrib.sessions.middleware这个中间件,查看里面的Session源码 from django.contrib.sessions.middleware ...
- Sourse Insight使用过程中的常使用功能简介
1.查找定义: 在编辑区内,选中任意一个变量.函数.宏等,点击右键->Jump Definition,或者直接Ctrl+左击 2.编辑区切换
- VMWare中安装windowsXP遇到的问题
XP系统安装 1.安装Windows和安装linux不一样,创建虚拟机完成后Linux自动根据硬盘进行系统安装,不需要提前分区.而windows必须进行提前分区,这个分区是在虚拟磁盘上完成的,就是你创 ...
- curl操作封装
<?php /** * Class Curl curl简单封装 get post */ class Curl { /** * @brief get请求 * @param $url 请求的url ...
- STP生成树协议原理与算法解析
转:https://wenku.baidu.com/view/2e52b91d866fb84ae45c8d34.html
- 【鸟哥的Linux私房菜】笔记
操作系统核心的功能! 驱动程序与操作系统的关系 2. [计算机组成之组件] 3.CPU实际要处理的数据完全来自于主存储器,这是一个很重要的概念! 4.CPU是整个计算机系统最重要的部分,那么目前世界上 ...