计算几何02_三次样条曲线

2023-11-08

在这里插入图片描述

一、样条

样条(Spline)函数是由舍恩伯格于1946年提出的。样条是富有弹性的细木条或有机玻璃条,它的作用相当于“万能”曲线板。早期船舶、汽车、飞机放样时用铅压铁压住样条,使其通过一系列型值点,调整压铁达到设计要求后绘制其曲线,称为样条曲线。这样设计曲线的方法在20世纪六七十年代得到了广泛应用。
在这里插入图片描述

二、几何连续性

2.1 连续性条件

通常单一的曲线段或曲面片难以表达复杂的形状,必须将一些曲线段拼接成组合曲线,或将一些曲面片拼接成组合曲面,才能表达复杂的形状。为了保证在结合点处光滑过渡,需要满足连续性条件。连续性条件有两种:参数连续性(Parametric Continuity)与几何连续性(Geometric Continuity)。

2.2 参数连续性

  • 零阶参数连续性,记为C0,指相邻两段曲线在结合点处具有相同的坐标。
    在这里插入图片描述

  • 一阶参数连续性,记为C1,指相邻两段曲线在结合点处具有相同的一阶导数
    在这里插入图片描述

  • 二阶参数连续性,记为C2,指相邻两段曲线在结合点处具有相同的一阶导数和二阶导数。
    在这里插入图片描述

2.3 几何连续性

与参数连续性不同的是,几何连续性只要求参数成比例而非相等。

  • 零阶几何连续性,记为G0,与零阶参数连续性相同,即相邻两段曲线在结合点处有相同的坐标。
  • 一阶几何连续性,记为G1,指相邻两段曲线在结合点处的一阶导数成比例,但大小不一定相等。
  • 二阶几何连续性,记为G2,指相邻两段曲线在结合点处的一阶导数和二阶导数成比例,即曲率一致,但大小不一定相等。

三、三次样条曲线

  • 三次样条曲线是组合曲线,它在相邻的两型值点之间,使用三次函数进行插值。如果把n段三次曲线连接起来,使两相邻曲线在连接点(称为节点)的斜率和曲率相等,就获得n段三次函数组合成的曲线,即三次样条曲线。
  • 三次样条曲线是插值曲线,它通过所有型值点。
  • 样条函数的理论和运用是从三次样条函数发展起来的。
  • 在计算几何中,应用得最早、研究得最详细的也是三次样条函数,因为 三次样条函数在节点处具有C2连续性,而二阶连续性是大多数工程问题所需要的。
  • 样条函数也是放样工艺中绘制曲线用的细木条的数学模型的线性近似,符合传统的光顺要求。

3.1 三次样条函数的定义

已知n个型值点Pi(xi, yi), i = 1, 2,…, n且a = x1 < x2 <…< xn = b。若 y=s(x)满足下列条件:
(1)型值点Pi在函数 y=s(x) 上。
(2) s(x) 在整个区间[a, b]上二阶连续可导。
(3)在每个子区间[xi, xi+1], i = 1, 2,…, n-1上,分段函数 都是参数x的三次多项式。则称函数 是过型值点的三次样条函数,由三次样条函数构成的曲线称为三次样条曲线。

3.2 三次样条函数的表达式

在这里插入图片描述

第i段的 si(x) 表示为:
在这里插入图片描述
式中,ai,bi,ci,di为待定系数,i=1,2 … ,n-1。

第i段曲线的首端通过Pi(xi,yi),末端通过Pi+1(xi+1,yi+1)
Pi处的二阶导数为Mi。
其中各型值点的弯矩Mi的力学解释如下:
在这里插入图片描述

在这里插入图片描述在这里插入图片描述
子区间示意图如下:
在这里插入图片描述
用型值点处的二阶导数Mi表示的三次B样条函数为:
在这里插入图片描述

3.3 求解思路

在这里插入图片描述

3.4 函数推导

在这里插入图片描述

3.5 边界条件

在这里插入图片描述

3.5 推导过程

见个人资源:三次样条插值函数求解过程.pdf

四、算法实现

4.1 思路

(1)读入n个型值点且满足其x坐标递增。
(2)根据实际情况确定三次样条曲线的边界条件。
(3)计算曲线的系数,将其表达为型值点二阶导数的函数。
(4)用追赶法求解三弯矩方程。
(5)将求解出的参数代入三次样条函数的表达式中,构造三次样条曲线。
(6)循环访问每个节点。在每个子区间内,按照精度要求,使用直线段连接各段内的若干等分点,即可绘制出三次样条曲线。

4.2 代码

4.2.1 读取型值点

首先定义数据结构p2.cpp与头文件(主要如下):

CP2::CP2(double x, double y)
{
	this->x = x;
	this->y = y;
}

之后在主函数中定义读取函数:

// CGeometricfiguretestViewmessage handlers
void CGeometricfiguretestView::ReadPoint()
{
	P[1].x = -340, P[1].y = -200;
	P[2].x = -150, P[2].y =  0;
	P[3].x =  0,   P[3].y =  -50;
	P[4].x =  100, P[4].y =  -100;
	P[5].x =  250, P[5].y =  -100;
	P[6].x =  350, P[6].y =  -50;
}

4.2.2 绘制型值点

void CGeometricfiguretestView::DrawDataPoint(CDC* pDC)//绘制型值点
{
	CBrush NewBrush, *pOldBrush;
	NewBrush.CreateSolidBrush(RGB(0, 0, 0));
	pOldBrush = pDC->SelectObject(&NewBrush);
	for( int i = 1; i < 7; i++)
		pDC->Ellipse(ROUND(P[i].x - 5), ROUND(P[i].y - 5), ROUND(P[i].x + 5), ROUND(P[i].y + 5));
	pDC->SelectObject(pOldBrush);
}

4.2.3 三次样条曲线绘制

具体过程见注释:

void CGeometricfiguretestView::DrawCubicSpline(CDC* pDC)//三次样条曲线
{
	int n = 6;
	const int dim = 7;//二维数组维数
	double b1 = 10, bn = 10;//边界条件:"夹持端",给出起点和终点的一阶导数
	double h[dim], lambda[dim], mu[dim], D[dim];
    double l[dim], m[dim], u[dim]; 
    double M[dim], K[dim];
    double a[dim], b[dim], c[dim], d[dim];
	for(int i = 1; i < n; i++)//计算hi=xi+1-xi
    	h[i] = P[i+1].x - P[i].x;
	for(int i = 2; i < n; i++)
	{
		lambda[i] = h[i-1]/(h[i-1]+h[i]);//计算λ
		mu[i] = h[i]/(h[i-1]+h[i]);//计算μ
		D[i] = 6/(h[i-1]+h[i])*((P[i+1].y-P[i].y)/h[i]-(P[i].y-P[i-1].y)/h[i-1]);//计算D
    }
	D[1]=6*((P[2].y-P[1].y)/h[1]-b1)/h[1];//夹持端的D[1]
    D[n]=6*(bn-(P[n].y-P[n-1].y)/h[n-1])/h[n-1];//夹持端的D[n]
    mu[1]=1;//夹持端的μ[1],
	lambda[n]=1;//夹持端的λ[n]
	//追赶法求解三弯矩方程
    l[1]=2;
	u[1]=mu[1]/l[1];
    for(int i=2; i <= n; i++)
    {
		m[i]=lambda[i];
        l[i]=2-m[i]*u[i-1];
        u[i]=mu[i]/l[i];
    }
    K[1] = D[1]/l[1];//解LK=D
    for(int i = 2; i <= n;i++)
    {
		K[i]=(D[i]-m[i]*K[i-1])/l[i];
	}
	M[n] = K[n];//解UM=K
	for(int i = n-1; i >= 1;i--)
	{
		M[i]=K[i]-u[i]*M[i+1];
	}
	//计算三次样条函数的系数
	for(int i = 1; i < n; i++)
    {
		a[i] = P[i].y;
        b[i] = (P[i+1].y-P[i].y)/h[i] - h[i]*(M[i]/3+M[i+1]/6);
        c[i] = M[i]/2;
        d[i] = (M[i+1]-M[i])/(6*h[i]);
    }
	pDC->MoveTo(ROUND(P[1].x), ROUND(P[1].y));
	double xStep = 0.5;//x的步长
	double x, y;//当前点
	for(int i = 1; i < n; i++)//循环访问每个节点
    {
		for(x = P[i].x; x < P[i+1].x; x += xStep)//循环访问每个节点
		{
			y=a[i]+b[i]*(x-P[i].x)+c[i]*(x-P[i].x)*(x-P[i].x)+d[i]*(x-P[i].x)*(x-P[i].x)*(x-P[i].x);
			pDC->LineTo(ROUND(x), ROUND(y));//绘制样条曲线
        }
    }
}

4.2.4 主函数调用

void CGeometricfiguretestView::OnDraw(CDC* pDC)
{
	CTestDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	// TODO: add draw code for native data here
	CRect rect;//定义客户区矩形
	GetClientRect(&rect);//获得客户区矩形的信息
	pDC->SetMapMode(MM_ANISOTROPIC);//自定义二维坐标系
	pDC->SetWindowExt(rect.Width(), rect.Height());//设置窗口范围
	pDC->SetViewportExt(rect.Width(), -rect.Height());//设置视区范围,且x轴水平向右为正,y轴垂直向上为正
	pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);//设置客户区中心为二维坐标系原点
	rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);//rect矩形与客户区重合
	ReadPoint();
	DrawDataPoint(pDC);
	DrawCubicSpline(pDC);
}

编译运行,可见如下:
在这里插入图片描述
我们也可以改变其中一个边界约束条件:

double b1 = 10, bn = -5;//边界条件:"夹持端",给出起点和终点的一阶导数

运行可以看到如下:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算几何02_三次样条曲线 的相关文章

  • 计算几何 (POJ1127 、 )

    计算几何 1 判断线段是否相交 1 判断线段是否相交 在不需求出交点 xff0c 只需判断两条线段是否相交 xff0c 可以使用 1 快 速 排 斥 实
  • 一,凸包---3,极边

    极边就是组成凸包的边的集合 时间复杂度是o n3 比判断极点快 时间复杂度O n4 快 为什么呢 试想 不论极边也好 极点也好 判断的依据是三角形的方向 无论是海伦公式 还是向量叉乘 极边是需要三个点组成一个三角形 是一个三重循环 即可用t
  • 关于叉积

    学过计算几何以后 我发现几乎每一道题都用到了叉积这个东西 叉积是什么呢 在这个图中 以原点为中心 叉积就是x1 y2 x2 y1 记得话就记1221 x前y后 但是这并不是完全正确 比如说这个图 在这个图中 点1和点2是以点0为中心 不是原
  • vtk vs2015 win10 64bit 编译注意事项

    记录几个凌乱的关键点 事先安装Qt 我得是5 8版本 需要官网注册之类的 1 关于Python 编译带tcl java python的 vtk 需要很多繁琐的步骤 记录整个过程太恐怖了 vtk暂时不支持python3 支持的还是python
  • 关于使用2d照片进行3d建模

    转载感言 作者一句业余 搞得弟兄们面红耳赤了 感谢作者的可行性分析 Autodesk 的 123D Catch 让我们能够很简单的根据一组照片构建3D物体 你只需要从各个角度拍摄希望建模的物体 然后通过 123D Catch 将照片上传到
  • hihoCoder 1582 Territorial Dispute

    Problem hihocoder com problemset problem 1582 vjudge net problem HihoCoder 1582 Reference hihocoder 1582 Territorial Dis
  • hdu 6127 Hard challenge

    Problem acm hdu edu cn showproblem php pid 6127 Meaning 平面上有 n 个不重合的点 任意三点不共线 任意两点所在直线不经原点 每个点有个 value 任意两个点连出的线段的 value
  • 能通过一张照片(2D)得到3D的模型吗?

    如下内容已经整理成 PDF 很好奇其实如果将人眼所看到的画面保存下来 拍照 人类是可以感知照片内的各个物体 是不是可以理解成这是一种2D到3D认知的转换 作者 知乎用户 链接 https www zhihu com question 529
  • Points Within

    http acm zju edu cn onlinejudge showProblem do problemId 81 Statement of the Problem Several drawing applications allow
  • codeforces 851 #432 div2 C Five Dimensional Points

    Problem codeforces com contest 851 problem C Preference Codeforces Round 432 editorial Codeforces Round 432 Div 2 C Five
  • 3D扫描技术概览

    3D扫描技术概览 复制链接 楼主 eseedo 发表于 2016 11 22 17 14 26 408 0 只看该作者 内容概要 1 使
  • CGAL计算几何算法库安装和使用(一)

    CGAL是使用C 开发的计算几何算法库 提供Delaunay三角网 网格生成 多边形 以及各种几何处理算法 应用领域 计算机图形学 科学可视化 计算机辅助设计与建模 地理信息系统 分子生物学 医学影像学 机器人学和运动规划 和数值方法 1
  • Surround the Trees

    http acm zju edu cn onlinejudge showProblem do problemId 453 There are a lot of trees in an area A peasant wants to buy
  • Kattis Doors

    Problem open kattis com problems doors vjudge net contest 183886 problem B Reference 点到线段的最短距离算法 Meaning 有两个球 Alex 和 Bob
  • 我的第一个半平面交(1007: [HNOI2008]水平可见直线)

    点击打开链接 Description Input 第一行为N 0 lt N lt 50000 接下来的N行输入Ai Bi Output 从小到大输出可见直线的编号 两两中间用空格隔开 Sample Input 3 1 0 1 0 0 0 S
  • 【SSL_1232】雷达覆盖

    思路 以一个点作为平角 计算几何统计 c o d e code code include
  • The centre of polygon (多边形重心)

    描述 Given a polygon your task is to find the centre of gravity for the given polygon 输入 The input consists of T test case
  • 豪斯多夫距离-- Hausdorff distance of convex polygons

    蒙特利尔的麦吉尔大学的计算几何课程资料 原文链接 http cgm cs mcgill ca godfried teaching cg projects 98 normand main html 1 Introduction When ta
  • 火星探险 (Mars)

    暂无链接 题目描述 在2051年 若干火星探险队探索了这颗红色行星的不同区域并且制作了这些区域的地图 现在 Baltic空间机构有一个雄心勃勃的计划 他们想制作一张整个行星的地图 为了考虑必要的工作 他们需要知道地图上已经存在的全部区域的大
  • 判断一个点是否在圆内(三点确定一个圆)

    三角形的外接圆圆心是任意两边的垂直平分线的交点 三角形外接圆圆心叫外心

随机推荐

  • windows里的vscode 通过ssh远程到Linux服务器,显示matplotlib图形

    本地vscode安装插件 PYQT Integration 右键 py 选择 Run Current File in interactive Window 一些使用PyQt的步骤 conda activate py38 在自己的conda环
  • 用虚拟机安装linux程序

    其实这是一个很简单的工作 大牛不要嘲笑 这里只是写一个简单的流程 首先 是使用的软件 虚拟机程序Oracle VM VirtualBox http www oracle com technetwork server storage virt
  • IP地址的分类及子网掩码的计算

    目录 一 什么是IP地址 IP地址的作用及其种类 二 分类的IP地址 三 无分类编址 四 网络号 主机号和子网掩码的计算 一 1 IP地址 整个互联网中 分配给每一个主机在全世界范围内唯一的32位二进制码 2 IP地址的表示方法 为了可读性
  • Mybatis-Plus的详细使用

    一 MyBatisPlus概述 需要的基础 MyBatis Spring SpringMVC学完 为什么要学习呢 它可以节省我们大量的工作时间 所有的JDBC都可以自动化完成 JPA tk mapper MyBatisPlus 简介 是什么
  • 线上流量特训营:暴力引流10W+中小卖家流量破局技巧等

    新标题 突破流量瓶颈 线上流量特训营助力中小卖家引爆10W 流量的破局技巧 文章 引言 100字 线上流量特训营是一项旨在帮助中小卖家突破流量瓶颈的破局技巧 通过学习特训营提供的精选流量引爆策略 中小卖家可以迅速吸引超过10W的流量 实现业
  • L1-5 试试手气 (15 分)

    我们知道一个骰子有 6 个面 分别刻了 1 到 6 个点 下面给你 6 个骰子的初始状态 即它们朝上一面的点数 让你一把抓起摇出另一套结果 假设你摇骰子的手段特别精妙 每次摇出的结果都满足以下两个条件 1 每个骰子摇出的点数都跟它之前任何一
  • FWT 详解 知识点

    前言 扯淡 可以跳过 其实去年清华集训之后就想写这篇文章了 但是写了一会发现有点说不明白话 于是受限于语文水平一直没有写 前几天给人当面讲了一遍 感觉大概可以BB明白些了 picks的博客里就写着fwt怎么做 然而他并没有写为什么这样是对的
  • 【微服务架构】面向故障设计微服务架构

    微服务架构可以通过定义明确的服务边界隔离故障 但就像在每个分布式系统中一样 网络 硬件或应用程序级别问题的可能性更高 由于服务依赖关系 任何组件都可能对其消费者暂时不可用 为了最大限度地减少部分中断的影响 我们需要构建可以优雅地响应某些类型
  • 爬取上交所和深交所的年报问询函到Excel

    注意事项 需要安装一些包 如pdfminer pdfminer3k pdfplumber等 pdfminer不能解析上交所问询函 使用解析功能更为强大的pdfplumber可以解析 但是内容上可能会出现个别字重复的现象 pdfminer3k
  • 区间预测

    区间预测 MATLAB实现基于QRCNN BiGRU Multihead Attention多头注意力卷积双向门控循环单元多变量时间序列区间预测 目录 区间预测 MATLAB实现基于QRCNN BiGRU Multihead Attenti
  • Spring Boot 学习笔记整理

    spring boot 笔记 1 配置文件 1 application properties 2 application yml 作用 修改spring boot的默认设置 YAML 比XML和JSON更适合做配置文件 以数据为中心 2 Y
  • 解决鼠标右键没有文本

    解决鼠标右键没有文本文档 打开注册表 win r 输入 regedit 2 找到 txt 将默认值改为 txtfile 查看shellNew项是否存在 不存在新建 存在则改变 这个字符串值为空 F5刷新一下 或者
  • OLE接口详解

    所有 OLE Api 和接口的目的 本页 摘要 详细信息 常规 初始化和内存管理 远程处理 自定义服务 服务注册 DLL 服务器管理 杂项 COM 函数 命名 名字对象 结构化的存储 永久对象 每个事件的通知 统一数据传输 可查看对象 标准
  • HarmonyOS 自定义页面请求与前端页面调试

    一 自定义页面请求响应 Web 组件支持在应用拦截到页面请求后自定义响应请求能力 开发者通过onInterceptRequest 接口来实现自定义资源请求响应 自定义请求能力可以用于开发者自定义 Web 页面响应 自定义文件资源响应等场景
  • 每日一题:走路

    走路 题目 Daimayuan Online Judge f i j 表示第i步能否走到第j阶 include
  • uniapp打包微信小程序主包过大问题

    问题 在用uniapp打包微信小程序时提示文件超过了2M不让上传 主包中的vendor js太大1 7M有的甚至更大 解决 在HbuildX中运行时勾选上运行压缩 在微信开发者工具中上传时勾选上上传压缩 在manifest json中检查分
  • C语言 .c文件 到 .exe文件过程

    预处理 预处理相当于根据预处理命令组装成新的 C 程序 不过常以 i 为扩展名 编 译 将得到的 i 文件翻译成汇编代码 s 文件 汇 编 将汇编文件翻译成机器指令 并打包成可重定位目标程序的 o 文件 该文件是二进制文件 字节编码是机器指
  • OculusRiftS与Unity.UI的交互(1)-总览

    使用OculusIntegration包 VRTK还没有测试过 OculusIntegration提供的场景 包含了 键盘交互 VR摄像机 画布 凝视位置 光标 等节点 总览 这是默认的OVR UI场景的节点设置 之后 根据自身场景的需要
  • ARouter解析五:IoC与依赖注入

    终于来到了ARouter解析的第五篇了 前面陆陆续续分享了四篇ARouter框架的使用和源码内容 ARouter解析一 基本使用及页面注册源码解析ARouter解析二 页面跳转源码分析ARouter解析三 URL跳转本地页面源码分析ARou
  • 计算几何02_三次样条曲线

    一 样条 样条 Spline 函数是由舍恩伯格于1946年提出的 样条是富有弹性的细木条或有机玻璃条 它的作用相当于 万能 曲线板 早期船舶 汽车 飞机放样时用铅压铁压住样条 使其通过一系列型值点 调整压铁达到设计要求后绘制其曲线 称为样条