besier打断和升阶,高阶性质

欢迎关注更多精彩
关注我,学习常用算法与数据结构,一题多解,降维打击。

问题描述

  1. 对besier曲线在u处打断,生成两条besier曲线
  2. 对besier曲线升阶处理

bezier高阶性质

求导推导

P ( t ) = ∑ i = 0 n B i n ( t ) b i \boldsymbol P(t) = \displaystyle \sum_{i=0}^nB_i^n(t)\boldsymbol b_i P(t)=i=0nBin(t)bi

B i n ( t ) = ( n i ) t i ( 1 − t ) n − i B_i^n(t)=\left (\begin{array}{l}n \\i \end{array} \right)t^i(1-t)^{n-i} Bin(t)=(ni)ti(1t)ni

矩阵表示

P ( t ) = [ B 0 n B 1 n ⋯ B n n ] [ b 0 b 1 ⋮ b n ] P(t) = \begin {bmatrix} B_0^n & B_1^n &\cdots& B_n^n \end{bmatrix} \begin {bmatrix} \boldsymbol b_0\\\boldsymbol b_1\\\vdots\\\boldsymbol b_n\end{bmatrix} P(t)=[B0nB1nBnn] b0b1bn

只要对每个系数求导即可

B i n ( t ) ′ = i ( n i ) t i − 1 ( 1 − t ) n − i − ( n − i ) ( n i ) t i ( 1 − t ) n − i − 1 ⋯ ( 1 ) B_i^n(t)'=i\left (\begin{array}{l}n \\i \end{array} \right)t^{i-1}(1-t)^{n-i}-(n-i)\left (\begin{array}{l}n \\i \end{array} \right)t^i(1-t)^{n-i-1} \cdots (1) Bin(t)=i(ni)ti1(1t)ni(ni)(ni)ti(1t)ni1(1)

对组合数展开可以发现

B i n ( t ) ′ = n ( n − 1 i − 1 ) t i − 1 ( 1 − t ) n − i − n ( n − 1 i ) t i ( 1 − t ) n − i − 1 = n B i − 1 n − 1 ( t ) − n B i n − 1 ( t ) B_i^n(t)'=n\left (\begin{array}{cl}n-1 \\i-1 \end{array} \right)t^{i-1}(1-t)^{n-i}-n\left (\begin{array}{cl}n-1 \\i \end{array} \right)t^i(1-t)^{n-i-1}=nB_{i-1}^{n-1}(t)-nB_i^{n-1}(t) Bin(t)=n(n1i1)ti1(1t)nin(n1i)ti(1t)ni1=nBi1n1(t)nBin1(t)

从(1)式可知,当i=0时, B i − 1 n − 1 ( t ) = 0 B_{i-1}^{n-1}(t)=0 Bi1n1(t)=0

设 q i = B i n − 1 ( t ) 设q_i = B_{i}^{n-1}(t) qi=Bin1(t)

P ′ ( t ) = n [ q 0 ⋯ q n − 1 ] [ b 1 ⋮ b n ] + n [ q 0 ⋯ q n − 1 ] [ − b 0 ⋮ − b n − 1 ] \boldsymbol P'(t)=n[q_0\ \cdots \ q_{n-1}] \begin {bmatrix} \boldsymbol b_1\\\vdots\\\boldsymbol b_n\end{bmatrix}+n[q_0\ \cdots \ q_{n-1}] \begin {bmatrix} -\boldsymbol b_0\\\vdots\\-\boldsymbol b_{n-1}\end{bmatrix} P(t)=n[q0  qn1] b1bn +n[q0  qn1] b0bn1

= ∑ i = 0 n − 1 B i n − 1 ( t ) ( b i + 1 − b i ) = \displaystyle \sum_{i=0}^{n-1}B_i^{n-1}(t)(\boldsymbol b_{i+1}-\boldsymbol b_i) =i=0n1Bin1(t)(bi+1bi)

上式一共是n项,所以n阶bezier曲线的导数可以由n-1阶bezier曲线得到

控制点如下

D i = n ( b i + 1 − b i ) , i ∈ [ 0 , n − 1 ] D_i = n(b_{i+1}-b_i), i\in[0, n-1] Di=n(bi+1bi),i[0,n1]

导数的计算也可以由De Casteljau algorithm 来算

端点导数

将t=0, t=1代入公式,发现首末端的导数刚好是初始两点和末端两点连线的n倍。

高阶导数

参数曲线的d阶导为在d-1阶导数基础上再求一次导。

P ′ ′ ( t ) = ∑ i = 0 n − 2 B i n − 2 ( t ) ( ( n − 1 ) ( D i + 1 − D i ) ) \boldsymbol P''(t)= \displaystyle \sum_{i=0}^{n-2}B_i^{n-2}(t)((n-1)(\boldsymbol D_{i+1}-\boldsymbol D_i)) P′′(t)=i=0n2Bin2(t)((n1)(Di+1Di))

= n ( n − 1 ) ∑ i = 0 n − 2 B i n − 2 ( t ) ( b i + 2 − 2 b i + 1 + b i ) =n(n-1) \displaystyle \sum_{i=0}^{n-2}B_i^{n-2}(t)(\boldsymbol b_{i+2} -2\boldsymbol b_{i+1}+\boldsymbol b_i) =n(n1)i=0n2Bin2(t)(bi+22bi+1+bi)

从u处打断

根据 De Casteljau algorithm 的过程可以观察到。

每次迭代后,数组中的第1个点和最后一个点,分别是左右子段的控制点。


/*!*\brief Bezier曲线的打断
*\ param const std::vector<Point> & A 控制点序列
*\ param double u 打断处的参数 (0,1)
*\ param std::vector<Point> & cv_left 打断后前半部分的控制点
*\ param std::vector<Point> & cv_right 打断后后半部分的控制点
*\ Returns:   std::pair<List2f, List2f>
*/
std::pair<List2f, List2f> subDevide(const std::vector<Eigen::Vector2f> &A, float u)
{List2f cv_left = A;List2f cv_right = A;if(A.size()<2)return {cv_left, cv_right};int p = A.size()-1;//p次迭代for (int i = 0;i<p;++i){for (int j = 0;j<p - i;++j)cv_right[j] = (1.0 - u)*cv_right[j] + u*cv_right[j + 1];//左侧控制点为每次迭代的首点cv_left[i + 1] = cv_right[0];}return {cv_left, cv_right};
}

升阶

设原来曲线控制点为b0, b1, … bn n+1个控制点,

升阶后的点为c0, c1, … cn, cn+1 n+2个控制点

c0=b0, cn+1=bn

中间控制点

c i = i n + 1 b i − 1 + ( 1 + i n + 1 ) b i , i ∈ [ 1 , n ] c_i = \frac {i}{n+1}b_{i-1} + (1+\frac{i}{n+1})b_i, i \in[1,n] ci=n+1ibi1+(1+n+1i)bi,i[1,n]


List2f degreeElevation(const std::vector<Eigen::Vector2f> &A)
{int n=A.size(); // 为公式中的n+1List2f res (n+1);res.front() = A[0];res.back() = A.back();for(int i=1;i<n;++i) {float ratio = 1.0*i/n;res[i] = ratio *A[i-1] + (1-ratio)*A[i];}return res;
}

实现

代码:
https://gitcode.com/chenbb1989/geometric_model/tree/master/gohw4-3

演示视频

besier 打断与升阶

打断
在这里插入图片描述

升阶

在这里插入图片描述


本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。创作不易,帮忙点击公众号的链接,帮忙转发,感激不尽。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/408052.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 爬虫入门(十二):正则表达式「详细介绍」

Python 爬虫入门&#xff08;十二&#xff09;&#xff1a;正则表达式 前言一、正则表达式的用途二、正则表达式的基本组成元素2.1 特殊字符2.2 量词2.3 位置锚点2.4 断言2.5 字符集2.6 字符类2.6.1 基本字符类2.6.2 常见字符类简写2.6.3 POSIX字符类2.6.4 组合使用 三、 正则表…

Datawhale X 李宏毅苹果书 AI夏令营 学习笔记(二)

自适应学习率 我们梯度下降在参数更新上&#xff0c;公式是 W t W t − 1 − η g t &#xff0c; η 是学习率&#xff0c; g t 是梯度 W_tW_{t-1}-\eta g_t&#xff0c;\eta是学习率&#xff0c;g_t是梯度 Wt​Wt−1​−ηgt​&#xff0c;η是学习率&#xff0c;gt​是梯度…

03_React 收集表单数据和 组件生命周期

React 收集表单数据和 组件生命周期 一、收集表单数据1、例子1.1 需求&#xff1a;定义一个包含表单的组件&#xff0c;输入用户名密码后&#xff0c;点击登录提示输入信息 2、理解&#xff1a;包含表单的组件分类2.1 受控组件2.2 非受控组件 二、高阶函数\_函数柯里化1、复习-…

9 正则表达式:Java爬虫和正则表达式、String中的正则表达式方法(基本语法7)

文章目录 前言一、正则表达式1 [ ] 语法(1)[ABC] 和 [^ABC](2)[A-Z]和[a-zA-Z]小总结2 特殊字符语法(\w 这些)3 数量符4 \ 、()、 |5 锚点 ^ 和 $,\b,\B6 (?i) : 忽略其后面的大小写 ---- 这个Java是可以的,其他语言我不知道(正则表达式虽然大多通用,但也有部分是…

zabbix5.0与7.0版本区别 切换建议

Zabbix5.0和Zabbix7.0的区别 1. 性能和扩展性优化 1.1 高效的数据处理和存储 优化的数据库性能&#xff1a; Zabbix 7.0 在数据库层面进行了多项优化&#xff0c;以减少查询延迟和提高数据处理速度。这包括对数据库结构的改进和索引优化&#xff0c;使得大规模数据的读取和写…

Spark-driver和executor启动过程

一、上下文 《Spark-SparkSubmit详细过程》详细分析了从脚本提交任务后driver是如何调用到自己编写的Spark代码的&#xff0c;而我们的Spark代码在运行前必须准备好分布式资源&#xff0c;接下来我们就分析下资源是如何分配的 二、Spark代码示例 我们以一个简单的WordCount程…

打卡学习Python爬虫第五天|Xpath解析的使用

什么是Xpath&#xff1f;是在XML文档中搜索内容的一门语言&#xff0c;HTML可以看作是xml的一个子集。 目录 1、安装lxml模块 2、导入lxml中的etree子模块 3、Xpath使用方法 3.1.选择节点 3.2.选择属性 3.3.选择文本内容 3.4.使用通配符*过滤节点 3.5.使用中括号[]索引…

Java学习_20_File以及IO流

文章目录 前言一、FileFile中常见的成员方法判断和获取创建和删除获取和遍历 二、IO流IO流体系结构字节流字节输出流&#xff1a;FileOutputStream字节输入流FileInputStrea文件拷贝try……catch异常处理中文乱码现象 字符流字符流读取FileReader字符流输出FileWriter底层原理 …

Linux 命令集合

1. linux 系统版本 1.1 linux系统的分类 linux系统&#xff0c;主要分Debian系和RedHat系&#xff0c;还有其它自由的发布版本。 1、Debian系主要有Debian&#xff0c;Ubuntu&#xff0c;Mint等及其衍生版本&#xff1b; 2、RedHat系主要有RedHat&#xff0c;Fedora&#xf…

Springsecurity 自定义AuthenticationManager

一、认证流程 1、当用户提交了一个他的凭证(用户名、密码) AbstractAuthenticationProcessingFilter 将会创建一个凭证信息&#xff0c;最终&#xff0c;该请求会被UsernamePasswordAuthenticationFilter 拦截将请求中用户名和密码&#xff0c;封装为 Authentication 对象&…

C++ | Leetcode C++题解之第365题水壶问题

题目&#xff1a; 题解&#xff1a; class Solution { public:bool canMeasureWater(int x, int y, int z) {if (x y < z) {return false;}if (x 0 || y 0) {return z 0 || x y z;}return z % gcd(x, y) 0;} };

AI大模型进化之路:机器学习九大算法画图详解

机器学习算法对于了解AI大模型的意义非常重要&#xff0c;它们是构建、训练和应用AI大模型的基础和关键。今天给大家整理了一份机器学习核心算法资料&#xff0c;建议收藏学习。 集成学习是一种机器学习算法&#xff0c;它通过构建多个模型并整合它们的预测结果来提高性能。常…

ST 表算法

ST 表 ST 表&#xff0c;主要思想是空间换时间&#xff0c;用于解决可重复贡献问题和 RMQ 问题。 可重复贡献问题 指某个运算 o p op op&#xff0c;有 x o p x x x\ op\ x\ \ x x op x x 。例如 m a x ( x , x ) x m i n ( x , x ) x g c d ( x , x ) x max(x,x)x\…

【Docker】Docker学习01 | 什么是docker?

本文首发于 ❄️慕雪的寒舍 因为本人没有学习过docker&#xff0c;虽然部署过很多镜像&#xff0c;但是对于docker底层的实现一概不知。趁学习一个新项目的契机&#xff0c;将docker的相关概念了解清楚。 安装docker的教程请查看 Linux主机安装docker。 如果你想和我一起学习do…

TCP的连接建立及报文段首部格式

粘包问题&#xff1a; 原因&#xff1a;TCP流式套接字&#xff1b;数据与数据之间没有边界&#xff1b;导致可能多次的数据粘到一起。 解决办法&#xff1a; 规定一些数据与数据之间的间隔符&#xff0c;如&#xff1a;"\aa\", "\r\n"。指定要发送的数据…

exec函数簇

一、main 函数的参数定义 在C语言中&#xff0c;main 函数是程序执行的入口点。main 函数可以接受参数&#xff0c;这些参数通常用于从命令行接收输入。main 函数的参数定义通常遵循以下形式&#xff1a; int main(int argc, char *argv[]) 或者等价地&#xff1a; int mai…

91. UE5 RPG 实现拖拽装配技能以及解除委托的绑定

在上一篇文章里&#xff0c;实现了通过选中技能&#xff0c;然后点击下方的装备技能插槽实现了技能的装配。为了丰富技能装配功能&#xff0c;在这一篇里&#xff0c;我们实现一下通过拖拽技能&#xff0c;实现拖拽功能&#xff0c;我们需要修改两个用户控件&#xff0c;一个就…

杰发科技AC7840——CAN通信简介(8)_通过波特率和时钟计算SEG_1/SEG_2/SJW/PRESC

通过公式计算 * 波特率和采样点计算公式&#xff1a;* tSeg1 (S_SEG_1 2); tSeg2 (S_SEG_2 1).* BandRate (SCR_CLK / (S_PRESC 1) / ((S_SEG_1 2) (S_SEG_2 1))), SCR_CLK 为CAN 模块源时钟* SamplePoint (tSeg1 / (tSeg1 tSeg2)). {0x0D, 0x04, 0x04, 0x3B},…

文件IO和多路复用IO

目录 前言 一、文件 I/O 1.基本文件 I/O 操作 1.1打开文件 1.2读取文件内容 (read) 1.3写入文件 (write) 1.4关闭文件 (close) 2.文件指针 二、多路复用 I/O 1.常用的多路复用 I/O 模型 1.1select 1.2poll 1.3epoll 2.使用 select、poll 和 epoll 进行简单的 I/O…

软件测试最全面试题,了解一下

一、前言 近期有不少同学&#xff0c;朋友问我什么是软件测试&#xff0c;它是干什么的&#xff0c;我适不适合做、这行发展前景、工资怎么样等等等…在这里我把问题总结一下&#xff0c;整理一篇文章出来。 我也看过很多贴吧、论坛&#xff0c;在入行之前对这块都是迷茫的&a…