当前位置: 首页 > news >正文

Bezier 曲线 2D

Bezier 曲线于 1962 年由法国雪铁龙汽车公司的工程师 Bezier 所发表,主要应用于汽车的外形设计。虽然 Bezier 曲线早在 1959 年便由法国雷诺汽车公司的 De Casteljau 运用递推算法开发成功,但是 Bezier 却给出了曲线的详细的曲线计算公式。所以,命名为 Bezier 曲线.
Bezier 曲线由控制多边形唯一定义。
控制多边形的第一个顶点和最后一个顶点位于曲线上,多边形的第一条边和最后一条边表示了曲线在起点和终点的切矢量方向,其顶点则用于定义曲线的导数,阶次和形状。曲线的形状趋近于控制多边形并位于多边形所构成的土包内,改变控制多边形的顶点位置就会改变曲线的形状。
Bezier 曲线的直观交互性使得对设计对象的逼近达到了直接的集合化程度,使得起来非常方便。

Bezier 曲线的定义

给定 n + 1 n+1 n+1 个控制点 P i ( i = 0 , 1 , 2 , ⋯ n ) P_i (i=0, 1, 2, \cdots n) Pi(i=0,1,2,n),则 n n n次Bezier 曲线的定义为
P ( t ) = ∑ i = 0 n P i B i , n ( t ) , t ∈ [ 0 , 1 ] P(t) = \sum_{i=0}{n}P_i B_{i, n}(t), t\in[0, 1] P(t)=i=0nPiBi,n(t),t[0,1]
P i ( i = 0 , 1 , 2 , ⋯ , n ) P_i(i=0, 1, 2, \cdots, n) Pi(i=0,1,2,,n) 是控制多边形的 n + 1 n+1 n+1 个控制点. B i , n ( t ) B_{i, n}(t) Bi,n(t)是 Bernstein 基函数,其表达式为

B i , n ( t ) = n ! i ! ( n − i ) ! t i ( 1 − t ) n − i = C n i t i ( 1 − t ) n − i , i = 0 , 1 , 2 , ⋯ n \begin{equation} B_{i, n}(t) = \frac{n!}{i!(n-i)!}t^{i}(1-t)^{n-i} = C_{n}^{i}t^{i}(1-t)^{n-i}, \quad i=0, 1, 2, \cdots n \end{equation} Bi,n(t)=i!(ni)!n!ti(1t)ni=Cniti(1t)ni,i=0,1,2,n

Bezier 函数是控制点关于 Bernstein 基函数的加权和,Bezier 曲线的次数为 n , 需要 n+1 个顶点来定义。
在工程项目中,最常见的是三次Bezier 曲线,其次数是二次Bezier 曲线,高次Bezier 曲线一般很少用

一次 Bezier 曲线, 当 n=1 时,Bezier 曲线的控制多边形有两个控制点 P 0 P_0 P0 P 1 P_1 P1, Bezier 曲线是一次多项式,称为一次 Bezier 曲线,

P ( t ) = ∑ i = 0 1 P i B i , 1 ( t ) = ( 1 − t ) P 0 + t P 1 P(t) = \sum_{i=0}^{1}P_i B_{i, 1}(t) = (1-t)P_0 + tP_{1} P(t)=i=01PiBi,1(t)=(1t)P0+tP1

二次 Bezier 曲线,当 n=2 时,Bezier 曲线的控制多边形有 3 个控制点, KaTeX parse error: Expected group after '_' at position 2: P_̲$ 、 P 1 P_1 P1 P 2 P_2 P2, Bezier 曲线是二次多项式,称为二次 Bezier 曲线,

P ( t ) = ∑ i = 0 2 P i B i , 2 ( t ) = ( 1 − t ) 2 P 0 + 2 t ( 1 − t ) P 1 + t 2 P 2 P(t) = \sum_{i=0}^{2}P_i B_{i, 2}(t) = (1-t)^2P_0 + 2t(1-t)P_{1} + t^2P_2 P(t)=i=02PiBi,2(t)=(1t)2P0+2t(1t)P1+t2P2
三次 Bezier 曲线,当 n=3 时,Bezier 曲线控制多边形有 4 个控制点, P 0 P_0 P0 P 1 P_1 P1 P 2 P_2 P2 P 3 P_3 P3, Bezier 曲线是三次多项式,称为三次 Bezier 曲线

P ( t ) = ∑ i = 0 3 P i B i , 3 ( t ) = ( 1 − t ) 3 P 0 + 3 t ( 1 − t ) 2 P 1 + 3 t 2 ( 1 − t ) P 2 + t 3 P 3 = ( − t 3 + 3 t 2 − 3 t + 1 ) P 0 + ( 3 t 3 − 6 t 2 + 3 t ) P 1 + ( − 3 t 3 + 3 t 2 ) P 2 + t 3 P 3 P(t) = \sum_{i=0}^{3}P_i B_{i, 3}(t) = (1-t)^3 P_0 + 3t(1-t)^2P_{1} + 3t^2(1-t)P_2 + t^3P_3 = (-t^3 + 3t^2 -3t+1)P_0 + (3t^3 -6t^2 + 3t)P_1 + (-3t^3+3t^2)P_2 + t^3P_3 P(t)=i=03PiBi,3(t)=(1t)3P0+3t(1t)2P1+3t2(1t)P2+t3P3=(t3+3t23t+1)P0+3t36t2+3tP1+(3t3+3t2)P2+t3P3

写成矩阵的形式为

P ( t ) = [ t 3 t 2 t 1 ] [ − 1 3 − 3 1 3 − 6 3 0 − 3 3 0 0 1 0 0 0 ] [ P 0 P 1 P 2 P 3 ] P(t) = \begin{bmatrix} t^3 & t^2 & t & 1 \end{bmatrix} \begin{bmatrix} -1 & 3 &-3 & 1\\ 3 & -6 &3 & 0\\ -3 & 3 &0 & 0\\ 1 & 0 & 0 & 0\\ \end{bmatrix} \begin{bmatrix} P_0 \\ P_1 \\ P_2 \\ P_3 \\ \end{bmatrix} P(t)=[t3t2t1] 1331363033001000 P0P1P2P3

B 0 , 3 ( t ) = ( 1 − t ) 3 B 1 , 3 ( t ) = 3 t ( 1 − t ) 2 B 2 , 3 ( t ) = 3 t 2 ( 1 − t ) B 3 , 3 ( t ) = t 3 B_{0, 3}(t) = (1-t)^3 \\ B_{1, 3}(t) = 3t(1-t)^2 \\ B_{2, 3}(t) = 3t^2(1-t) \\ B_{3, 3}(t) = t^3 B0,3(t)=(1t)3B1,3(t)=3t(1t)2B2,3(t)=3t2(1t)B3,3(t)=t3

下面给出 QT + OPENGL 的二次的代码

#include <QtWidgets>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>class BezierCurveWidget : public QOpenGLWidget, protected QOpenGLFunctions {
public:BezierCurveWidget(QWidget* parent = nullptr): QOpenGLWidget(parent) {}protected:void initializeGL() override {initializeOpenGLFunctions();glClearColor(1.0f, 1.0f, 1.0f, 1.0f);}void resizeGL(int w, int h) override {glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(0, w, h, 0, -1, 1);glMatrixMode(GL_MODELVIEW);}void paintGL() override {glClear(GL_COLOR_BUFFER_BIT);// 控制点坐标QPoint p0(100, 300);QPoint p1(300, 100);QPoint p2(500, 300);// 设置线的颜色glColor3f(0.0f, 0.0f, 1.0f); // Blue color for lines// 绘制Bezier曲线glBegin(GL_LINE_STRIP);for (float t = 0.0f; t <= 1.0f; t += 0.01f) {QPoint p = calculateBezierPoint(t, p0, p1, p2);glVertex2i(p.x(), p.y());}glEnd();// 绘制控制点glPointSize(5.0f);glColor3f(1.0f, 0.0f, 0.0f);glBegin(GL_POINTS);glVertex2i(p0.x(), p0.y());glVertex2i(p1.x(), p1.y());glVertex2i(p2.x(), p2.y());glEnd();// 绘制连接线glBegin(GL_LINES);glVertex2i(p0.x(), p0.y());glVertex2i(p1.x(), p1.y());glVertex2i(p1.x(), p1.y());glVertex2i(p2.x(), p2.y());glEnd();}QPoint calculateBezierPoint(float t, const QPoint& p0, const QPoint& p1, const QPoint& p2) {float u = 1 - t;float tt = t * t;float uu = u * u;float x = uu * p0.x() + 2 * u * t * p1.x() + tt * p2.x();float y = uu * p0.y() + 2 * u * t * p1.y() + tt * p2.y();return QPoint(x, y);}
};int main(int argc, char *argv[]) {QApplication a(argc, argv);QMainWindow window;BezierCurveWidget* bezierWidget = new BezierCurveWidget(&window);window.setCentralWidget(bezierWidget);window.resize(600, 400);window.show();return a.exec();
}

在这里插入图片描述

这里只需要替换一次和三次的计算部分即可。

相关文章:

Bezier 曲线 2D

Bezier 曲线于 1962 年由法国雪铁龙汽车公司的工程师 Bezier 所发表&#xff0c;主要应用于汽车的外形设计。虽然 Bezier 曲线早在 1959 年便由法国雷诺汽车公司的 De Casteljau 运用递推算法开发成功&#xff0c;但是 Bezier 却给出了曲线的详细的曲线计算公式。所以&#xff…...

Linux静态ip

Linux静态ip Ⅰ、修改静态ip Ⅰ、修改静态ip 修改静态ip必须是root用户 su root //切换root用户 ip a //查看修改前的动态ipvi /etc/sysconfig/network-scripts/ifcfg-ens33 //打开网卡配置文件&#xff0c;修改一处&#xff0c;新增四处 BOOTPROTO&quo…...

一种基于外观-运动语义表示一致性的视频异常检测框架 论文阅读

A VIDEO ANOMALY DETECTION FRAMEWORK BASED ON APPEARANCE-MOTION SEMANTICS REPRESENTATION CONSISTENCY 论文阅读 ABSTRACT1. INTRODUCTION2. PROPOSED METHOD3. EXPERIMENTAL RESULTS4. CONCLUSION阅读总结&#xff1a; 论文标题&#xff1a;A VIDEO ANOMALY DETECTION FRA…...

Netty—NIO万字详解

文章目录 NIO基本介绍同步、异步、阻塞、非阻塞IO的分类NIO 和 BIO 的比较NIO 三大核心原理示意图NIO的多路复用说明 核心一&#xff1a;缓存区 (Buffer)Buffer类及其子类Buffer缓冲区的分类MappedByteBuffer类说明&#xff1a; 核心二&#xff1a;通道 (Channel)Channel类及其…...

面试经典150题(32-37)

leetcode 150道题 计划花两个月时候刷完&#xff0c;今天&#xff08;第十五天&#xff09;完成了6道(32-37)150&#xff1a; 今天刚好有点没精神的感觉&#xff0c;然后碰到的题也不难。。天意&#xff01;&#xff01;&#xff01; 32.&#xff08;289. 生命游戏&#xff0…...

手撕分布式缓存---HTTP Client搭建

经过上个章节的学习&#xff0c;我们已经实现了一致性哈希算法&#xff0c;这个算法保证我们可以在节点发生变动时&#xff0c;最少的key请求受到影响&#xff0c;并返回这个节点的名称&#xff1b;这很大程度上避免了哈希雪崩和哈希穿透的问题。这个章节我们要基于此实现完整的…...

word如何快速制作简易代码块

先上解决方案。 方式一&#xff08;全自动&#xff09;&#xff1a; typora编辑&#xff0c;导出选择word文档即可。内网环境&#xff0c;故放弃。 方式二&#xff08;全手动&#xff09;&#xff1a; 在修改文档时&#xff0c;左侧会有“段落布局”按钮&#xff0c;点击该按…...

Linux常用网络指令

网络参数设定使用的指令 手动/自动设定与启动/关闭 IP 参数&#xff1a;ifconfig, ifup, ifdown ifconfig ifconfig常用于修改网络配置以及查看网络参数的指令 [rootwww ~]# ifconfig {interface} {up|down} < 观察与启动接口 [rootwww ~]# ifconfig interface {options…...

Spark on Yarn 安装配置实验(3.1.1)

子任务二: Spark on Yarn 安装配置 本任务需要使用 root 用户完成相关配置, 已安装 Hadoop 及需要配置前置环境,具体要求如下: 1 、从宿主机 /opt 目录下将文件 spark-3.1.1-bin-hadoop3.2.tgz 复制到容器 Master 中的 /opt/software (若 路径不存在,则需新…...

详解YOLOv5网络结构/数据集获取/环境搭建/训练/推理/验证/导出/部署

一、本文介绍 本文给大家带来的教程是利用YOLOv5训练自己的数据集&#xff0c;以及有关YOLOv5的网络结构讲解/数据集获取/环境搭建/训练/推理/验证/导出/部署相关的教程&#xff0c;同时通过示例的方式让大家来了解具体的操作流程&#xff0c;过程中还分享给大家一些好用的资源…...

ansible(不能交互)

1、定义 基于python开发的一个配置管理和应用部署工具&#xff0c;在自动化运维中异军突起&#xff0c;类似于xshell一键输入的工具&#xff0c;不需要每次都切换主机进行操作&#xff0c;只要有一台ansible的固定主机&#xff0c;就可以实现所有节点的操作。不需要agent客户端…...

黑马点评06分布式锁 2Redisson

实战篇-17.分布式锁-Redisson功能介绍_哔哩哔哩_bilibili 1.还存在的问题 直接实现很麻烦&#xff0c;借鉴已有的框架。 2.Redisson用法 3.Redisson可重入原理 在获取锁的时候&#xff0c;看看申请的线程和拿锁的线程是否一致&#xff0c;然后计算该线程获取锁的次数。一个方法…...

深度剖析知识图谱:方法、工具与实战案例

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 知识图谱作为一种强大的知识表示和关联技术&am…...

Oracle中的dblink简介

Oracle中的dblink简介 是一种用于在不同数据库之间进行通信和数据传输的工具。它允许用户在一个数据库中访问另一个数据库中的对象&#xff0c;而无需在本地数据库中创建这些对象。 使用dblink&#xff0c;用户可以在一个数据库中执行SQL语句&#xff0c;然后访问另一个数据库中…...

ubuntu安装显卡驱动过程中遇到的错误,及解决办法!

ubuntu安装显卡驱动的过程中&#xff0c;可能会遇到以下问题&#xff0c;可以参考解决办法&#xff01; 问题1&#xff1a; ​ ERROR: An error occurred while performing the step: "Building kernel modules". See /var/log/nvidia-installer.log for details. …...

【程序】STM32 读取光栅_编码器_光栅传感器_7针OLED

文章目录 源代码工程编码器基础程序参考资料 源代码工程 源代码工程打开获取&#xff1a; http://dt2.8tupian.net/2/28880a55b6666.pg3这里做了四倍细分&#xff0c;在屏幕上显示 速度、路程、方向。 接线方法&#xff1a; 单片机--------------串口模块 单片机的5V-------…...

TestSSLServer4.exe工具使用方法简单介绍(查SSL的加密版本SSL3或是TLS1.2)

一、工具使用方法介绍 工具使用方法参照&#xff1a;http://www.bolet.org/TestSSLServer/ 全篇英文看不懂&#xff0c;翻译了下&#xff0c;能用到的简单介绍如下&#xff1a; 将下载的TestSSLServer4.exe工具放到桌面上&#xff0c;CMD命令行进入到桌面目录&#xff0c;执…...

新年跨年烟花超酷炫合集【内含十八个烟花酷炫效果源码】

❤️以下展示为全部烟花特效效果 ❤️下方仅展示部分代码 ❤️源码获取见文末 🎀HTML5烟花喷泉 <style> * {padding:0;margin:0; } html,body {positi...

计算机网络考研辨析(后续整理入笔记)

文章目录 体系结构物理层速率辨析交换方式辨析编码调制辨析 链路层链路层功能介质访问控制&#xff08;MAC&#xff09;信道划分控制之——CDMA随机访问控制轮询访问控制 扩展以太网交换机 网络层网络层功能IPv4协议IP地址IP数据报分析ICMP 网络拓扑与转发分析&#xff08;重点…...

JMESPath语言

JMESPath&#xff08;JSON Matching Expression Path&#xff09; 一种查询语言。 主要用于从JSON文档中检索和过滤数据。 通过写表达式提取和处理JSON数据&#xff0c;而无需编写复杂的代码。 功能&#xff1a;数据提取、过滤、转换、排序。 场景&#xff1a;处理API响应…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...