计算机图形学入门16:曲线
1.曲线
曲线(Curves)在图形学中应用非常广泛,比如:相机的拍摄路径、物体的移动路径、动画曲线、矢量字体等。如下图所示,是使用曲线到矢量字体的应用,通过移动一些控制点来改变字体。
2.贝塞尔曲线
2.1 贝塞尔曲线定义
从上图中,如果无限的放大曲线的某一块区域,任何地方都是光滑的。这就是贝塞尔曲线(Bezier Curves)。
贝塞尔曲线是通过一系列控制点进行定义的曲线。而这些控制点满足一些性质,比如要满足从P0点开始,并且沿着P0P1方向,结束沿着P2P3方向,到P3点结束。曲线不必经过所有控制点,但必须经过起始点和结束点。这样就定义了一条贝塞尔曲线,如下图所示。
2.2 绘制贝塞尔曲线
那么,如何使用任意点绘制贝塞尔曲线呢?
贝塞尔曲线的绘制算法是 De Casteljau's Algorithm,算法的基本思想是利用线性插值的原理,将高阶贝塞尔曲线转化为一阶贝塞尔曲线的组合。
下面,我们以 3 个控制点绘制贝塞尔曲线的例子来进行介绍。
N 个控制点绘制的贝塞尔曲线,称为 N-1 阶贝塞尔曲线。如下图所示,我们定义了 3 个控制点,由此绘制的贝塞尔曲线称之为 二阶贝塞尔曲线(Quadratic Bezier)。对于这 3 个控制点,我们首先对相邻控制点进行连线。
定义一个变量 t
,其值的范围为 [0, 1]
,作为算法的输入值。当 t = 0
时,表示贝塞尔曲线起始点的输入值,当 t = 1
时,表示贝塞尔曲线结束点的输入值。所以算出 t
对应的所有点即可获得别塞尔曲线。
我们在控制点所构成的各个连线上定义一个点,这个点的位置取决于 t
的值,即一个比例值。如下图所示,在 b0b1 线段上定义一个 b10 点,并在 b1b2 线段上定义一个 b11 点。
然后,对 b10 点和 b11 点进行连线,按照上述规则,在 b10b11 线段上定义一个 b20 点,找到最后一个点就结束了。如下图所示。
当新定义的点只有一个时,我们可以将 t
的值逐步从 0
变到 1
。在这个过程中,b10、b20、b11 的位置都会随着 t
的变化而变化。对于最终的贝塞尔曲线,我们只需要关注最后定义的点 b20 的路径即可。
当我们扩展至更多控制点时,比如 4 个控制点时,我们仍然按照上述规则来处理,将高阶贝塞尔曲线转化为一阶贝塞尔曲线的组合,最终绘制曲线。如下图所示。
从上述可知,贝塞尔曲线也属于显式几何表示,因为显式几何表示通过直接定义或者参数定义,而这个 t
就是属于参数。
2.3 贝塞尔曲线代数公式
如上图所示,De Casteljau算法给出了一个系数金字塔,从中可知通过不断线性插值得到最后一个值的算法。那么,就可以写出这个关系式,以三个控制点为例,如下图所示。
由此,我们可以推导出 N 阶贝塞尔曲线的代数公式,如下图所示。其中,n 表示 N 阶贝塞尔曲线(n+1个控制点), 表示控制点,
为伯恩斯坦多项式(Bernstein Polynomials)。
举个例子,假设n=3,那么可以有四个控制点,点的位置不局限于平面上,甚至在三维空间中,展开公式如下。
对于伯恩斯坦多项式,也可得出如下关系。
2.4 贝塞尔曲线的性质
1.一定过起点和终点。在t=0的时候一定在起点,t=1的时候一定在终点。
2.起始的切线方向是由起始点和第二个点求出,结束的切线方向是由结束点和倒数第二个点求出。以四个控制举例如下,3倍只是代表4个控制点。
3.不受仿射变换影响,受投影变换影响。
对贝塞尔曲线上的每个控制点做仿射变换,绘制的新曲线于原曲线一样。
在空间中绘制一条贝塞尔曲线,将控制点投影到相机看到的平面上,然后重新绘制的新曲线与原曲线不同。
4.凸包(Convex Hull)性质:贝塞尔曲线在所有控制点的凸包范围内。如下图所示,蓝色线就是形成的凸包,凸包就是能够包围一系列几何形体的最小的凸多边形。简单理解就是一扇门上订满了钉子,然后用一块橡皮筋将外面一圈包起来,松手后橡皮筋会收缩,收缩后的外框就是凸包。
假设有一系列从走到右排列的点,排列在一条线上,这些是绘制贝塞尔曲线的控制点,那么绘制的贝塞尔曲线应该是什么形状?根据凸包性质,这条线就是凸包,而贝塞尔曲线不能超过凸包的范围,贝塞尔曲线被限制在这条线上,所以这条线就是贝塞尔曲线。
3.分段贝塞尔曲线
3.1 定义
如下图所示,给了11个点(n+1),绘制一条贝塞尔曲线(蓝色线)。可以看到这条贝塞尔曲线并不直观,非常平滑,说明当控制点多的时候,贝塞尔曲线很难得到想要的形状。
所以,当控制点比较多时,每次用很少的控制点绘制去绘制,然后将绘制的连接成一条贝塞尔曲线。于是就有了分段贝塞尔曲线(Piecewise Bezier Curves),即采用多条贝塞尔曲线进行串联。用4个常控制点来绘制一条贝塞尔曲线,也就是三阶贝塞尔曲线(Cubic Bezier)。如下图所示。
在PS里钢笔工具画曲线就是这个应用。
3.2 平滑处理
如下图所示,是一条分段贝塞尔曲线,而且每4个点绘制一条三次贝塞尔曲线。
可以发现有连接点的曲线出现了转折,不够平滑,那么如何保证连起来的曲线是平滑的呢?只要保证曲线结束的切线方向与相连曲线起始的切线相同即可(方向大小都相同),也就是导数要连续。
根据贝塞尔曲线的性质:三次贝塞尔曲线的起始切线的方向由第一个点和第二个点求得,结束切线的方向由第三个点和第四个点求出,并且前面有系数3。而相连的两条曲线,前一条曲线的结束点就是后一条曲线的起始点,所以需要调整前一条曲线的第三个点与后一条曲线的第二个点位置,使其切线相同。
3.3 连续性
如下图所示,在几何上两条三次贝塞尔曲线相连通过一个控制点,这是一种最简单的连续。像这种第一段的终点等于第二段的起点叫做连续(Continuity)。
连续关系式:
。
表示上一段曲线终点,
表示下一段曲线起点。
那么,在几何连续外,还需要切线的连续(切线相同,方向和大小都相同)。这叫做连续,也就是一阶导数的连续。如下图所示。
连续关系式:
。
除了一阶导数连续,还有2阶导数连续,也叫做曲率连续(连续)。
综上, 连续为两个函数在值上连续,
连续为导数上的连续,
为二阶导数连续,以此类推。
4.样条曲线
4.1 定义
样条(Spline)曲线一种连续的曲线,通过一系列的控制点控制,在任意位置满足一定的连续性,也就是一定数量的连续导数(任意阶)。
简而言之,这是一条可控的曲线。
4.2 B样条曲线
B样条(B-Splines)是基础样条(Basis Splines)的缩写,就是基函数样条。可以理解成用伯恩斯坦多项式在时间 t 里几个不同项对不同的控制点做一个加权平均,也可以理解成不同控制点位置对伯恩斯坦多项式进行加权求和。那么,这个伯恩斯坦多项式就可以理解为基函数。基函数就是由不同函数通过不同方式组合起来可以形成别的函数。
B样条曲线相当于是贝塞尔曲线的一个扩展。贝塞尔曲线在控制点很多的情况下,移动其中任何一个点,整个曲线在任何位置都会发生变化。假如只需要移动一个控制点改变一小段曲线的形状,也就是局部性,而B样条曲线能够满足这个功能,比分段贝塞尔曲线更方便。
B样条需要比贝塞尔曲线更多的信息。比贝塞尔曲线更加复杂,这里不做详细介绍。
相关文章:

计算机图形学入门16:曲线
1.曲线 曲线(Curves)在图形学中应用非常广泛,比如:相机的拍摄路径、物体的移动路径、动画曲线、矢量字体等。如下图所示,是使用曲线到矢量字体的应用,通过移动一些控制点来改变字体。 2.贝塞尔曲线 2.1 贝…...

【Ruby基础01】windows和termux中搭建Ruby开发环境
windows下环境搭建 railsinstaller官方git地址 按照文档安装git、nodejs、yarn,安装教程百度一下。railsinstall可以从release页面下载最新版本4.1.0。 安装完成如下 安装RubyMine 下载RubyMine RubyMine下载地址 安装激活 下载文件,按照里面的流程…...
2406c++,iguana动态反射
原文 iguana是一个基于编译期反射的序化库,支持从结构序化到不同数据格式. iguana可序化一个C结构到json,xml,yaml和protobuf格式.这都是通过编译期反射实现的. 现在iguana也支持了动态反射,主要特征: 1,通过对象名创建对象实例 2,取对象所有字段名 3,根据字段名取字段值 4,根…...
干货分享——AB站帮你解决独立站收款难题
目前,国内已经有抖音、拼多多和淘宝平台推出“仅退款”售后服务,无疑是加剧了原本就在疯狂打价格战的国内电商的严峻现状,使得商家不得不担心被顾客“薅羊毛”。在国内电商环境严重“内卷”的情况下,拓宽海外市场不失为一大妙计。…...
C++继承与派生
1.基本知识 类的继承是新类从已有类那里获得特性,从已有的类产生新类的过程称为类的派生; 已有类称为基类或父类,派生出的新类则称为派生类或子类; 继承的功能: (1)使得基类与派生类之间建立…...

Survival Animations
一套生存游戏的动画集,包括采集、建造、捕鱼、剥皮/鞣制、篝火等更多内容。 总动画数:89 建造/制作 30 篝火 28 饮水 3 水壶 3 觅食 2 治疗 3 空闲 1 原始捕鱼 7 剥皮 1 矛捕鱼 4 伐木 5 下载:Unity资源商店链接资源下载链接 效果图:...
Cargo 教程
Cargo 教程 1. 引言 Cargo 是 Rust 编程语言的包管理器和构建工具。它为 Rust 项目提供了依赖管理、编译和打包等功能。本教程将详细介绍 Cargo 的基本用法,帮助您快速上手 Rust 项目开发。 2. 安装 Cargo 在开始使用 Cargo 之前,您需要确保已经安装了 Rust 编程语言。Ru…...

linux中“PXE高效批量装机”
在大规模的 Linux 应用环境中,如 Web 群集、分布式计算等,服务器往往并不配备光驱设备,在这种情况下,如何为数十乃至上百台服务器裸机快速安装系统呢?传统的 USB光驱、移动硬盘等安装方法显然已经难以满足需求。 PXE …...

emm, ComfyUI的作者从Stability.AI离职了
🍖背景 今天在更新ComfyUI的过程中,看到Manager中有这样一段描述: 嗯?做了新的官方网站?然后开始新篇章? 难道说ComfyUI的作者从Stability.AI离职了? 赶紧点开链接看了下,emm&…...

Redis-五种数据结构之列表(ziplist、quicklist)
列表 文章目录 列表压缩列表-ziplistziplist 定义级联更新 快速列表-quicklistquicklistNode 定义quicklist 定义quicklist常用操作其他操作quicklist 相对于普通链表优点quick应用场景在redis 中使用quicklist 列表数据类型可以存储一组按插入顺序排序的字符串,他很…...

记一次全设备通杀未授权RCE的挖掘经历
想来上一次挖洞还在一年前的大一下,然后就一直在忙活写论文,感觉挺枯燥的(可能是自己不太适合弄学术吧QAQ),所以年初1~2月的时候,有空的时候就又会挖一挖国内外各大知名厂商的设备,拿了几份思科…...

【数据库编程-SQLite3(一)】sqlite3数据库在Windows下的配置及测试
学习分析 1、资源准备2、环境配置2.1、将资源包下载解压缩保存。2.2、在QT中创建工程,配置环境 3、测试配置3.1、 sqlite3_open函数3.2、sqlite3_close函数3.3、代码测试 1、资源准备 资源包 2、环境配置 2.1、将资源包下载解压缩保存。 解压缩得到以下文件 2.2、在QT中创建…...

YOLOv10改进 | 主干篇 | YOLOv10引入华为VanillaNet替换Backbone
1. VanillaNet介绍 1.1 摘要: 基础模型的核心是“越多越好”的理念,计算机视觉和自然语言处理领域取得的惊人成功就是例证。 然而,优化的挑战和变压器模型固有的复杂性要求范式向简单性转变。 在这项研究中,我们介绍了 VanillaNet,一种设计优雅的神经网络架构。 通过避免…...
C++ 迷宫问题
描述 定义一个二维数组 N*M ,如 5 5 数组下所示: int maze[5][5] { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走…...
【Linux】Linux文件系统中主要文件夹列举_作用说明
在Linux系统中,文件夹(或称为目录)的组织结构是系统功能和用户数据的重要组成部分。以下是Linux系统中一些主要文件夹的列举及其作用说明: / (根目录): 是Linux文件系统的起点。通常只包含其他目录,不建议直接在其中存…...

移植案例与原理 - HDF驱动框架-驱动配置(1)
HCS(HDF Configuration Source)是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。应该,类似Linux DTS(Device Tree Source)设备树。 HC-GEN(HDF Configuration Generator)是…...

坚持刷题|反转链表
文章目录 题目思考实现1. 迭代方式实现链表翻转2. 递归方式实现链表翻转 Hello,大家好,我是阿月。坚持刷题,老年痴呆追不上我,今天继续链表:反转链表 题目 LCR 024. 反转链表 思考 翻转链表是一个常见的算法问题&a…...

升级和维护老旧LabVIEW程序
在升级老旧LabVIEW程序至64位环境时,需要解决兼容性、性能和稳定性等问题。本文从软件升级、硬件兼容性、程序优化、故障修复等多个角度详细分析。具体包括64位迁移注意事项、修复页面跳转崩溃、解决关闭程序后残留进程的问题,确保程序在新环境中的平稳运…...
sqlite数据库整体迁移进mysql整个流程并解决中文异常问题
咨询【QQ】 sqlite轻量数据还行,随着数据量增大,不得不迁移进mysql 首先 电脑执行 sqlite3 db.sqlite3 .dump > dump.sql 会把整个sqlite的数据导出进 dump.sql中 紧接着我们把sqlite的sql转换成mysql的sql语句,因为mysql语句和 sq…...

Hadoop3:MapReduce中的Partition原理及自定义Partition
一、默认Partition分区配置 以WC案例来进行验证。 1、设置setNumReduceTasks 修改的代码 这行代码,确定了reduceTask的数量,也确定了分区逻辑 在mapper文件中,打上断点 计算分区的代码 这里会对每一个kv进行计算,然后&#…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...