【轨迹规划】贝塞尔曲线理解及C++实现n次贝塞尔曲线

2023-05-16

一、贝塞尔曲线

贝塞尔曲线(Bezier Curve)是一种基于多项式的曲线表示方法,由法国工程师Pierre Bézier在20世纪50年代提出。它是图形学中广泛应用的一种曲线类型,用于在二维或三维空间中描述平滑曲线和曲面。

原理:基于控制点的概念,通过控制点来定义曲线的形状,控制点的坐标决定了曲线的起始点、终止点以及曲线在这些点和它们之间的形状。

贝塞尔曲线可以由一组控制点和一组权重函数构成,其中每个控制点都有一个对应的权重函数,这个权重函数决定了控制点对曲线的影响程度。

一次直线:

Px=P0​+(P1​-P0)t = (1−t)P0​+tP1

二次抛物线:

Pi​=(1−t)P0​+tP1  ;  ​Pj​=(1−t)P1​+tP2​;         Px​=(1−t)Pi​+tPj​

三次贝塞尔:

 ...更高阶

 n阶贝塞尔公式:

6个控制点,五次贝塞尔曲线

 性质:曲线的端点和曲线相切,曲线不一定通过控制点,但是肯定通过端点。

把控制点作为节点,可以拼接多段曲线,且拼接处是光滑的。

感谢使用贝塞尔曲线绘制多点连接曲线 - 简书提供的gif图片,一图胜千言!

感谢 博主 详解样条曲线(上)天真的和感伤的想象家的博客-CSDN博客细节好文!

下面用C++实现n次贝塞尔曲线,贝塞尔曲线控制点的数量(即vector<point>的size)决定贝塞尔曲线的阶数(n=size-1);

C++实现n次贝塞尔曲线

#include <vector>
#include <cmath>
#include <iostream>
#include <fstream>

using namespace std;
struct Point {
    float x, y, z;
    Point(float x = 0, float y = 0 ,float z=0):x(x),y(y),z(z){}
};
// 计算组合数
int binomial(int n, int i) {
    int res = 1;
    for (int j = 1; j <= i; ++j) {
        res *= (n - j + 1) / (double)j; //(double)十分关键,不然j=i=n时,j为分数=0;
    }
    return res;
}
// 计算n次贝塞尔曲线上的点
Point bezier_curve(const vector<Point>& points, float t) {
    int n = points.size() - 1;
    Point res;
    for (int i = 0; i <= n; ++i) {
        cout << "p:" << points[i].x << "," << points[i].y << endl;
        float b =  binomial(n, i)* pow(t, i) * pow(1 - t, n - i);
        cout << "bino=" << binomial(n, i) << endl;
        res.x = res.x + points[i].x * b;
        res.y = res.y + points[i].y * b;
        res.z = res.z + points[i].z * b;
    }
    return res;
}
int main() {
    cout << "OK!" << endl;      
    ofstream fout("D:/data.txt"); // 打开或创建名为 data.txt 的文件
    if (!fout) { // 检查文件是否打开成功
        cerr << "File open failed!" << endl;
        return 1;
    }
    vector<Point> points = {{10,10,0}, {20, 80,70},{40,120,32}}; // 贝塞尔曲线控制点,给定控制点的数量决定贝塞尔曲线的阶数
    
    cout << "size:" << points.size() << endl;
    const float step = 0.02; // 步长
    for (float t = 0; t <= 1; t += step) {
        Point p = bezier_curve(points, t);
        fout << p.x << ", " << p.y <<", " <<p.z<< endl;
    }
    fout.close(); // 关闭文件
    return 0;
}

把导出的数据文件,使用Matlab画图


% 从文件中导入坐标点,dlmread函数用于从文件中读取数据,','表示分隔符,0表示读取文件的起始行数,0表示读取文件的起始列数。

points = dlmread('D:\data.txt', ',', 0, 0);
scatter3(points(:, 1), points(:, 2), points(:, 3), 'filled');

        二阶贝塞尔 points = {{10,10,0}, {20, 80,70},{40,120,32}}

 三阶贝塞尔 points = {{10,10,0}, {20, 80,70},{40,120,32},{70,0,90}}

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

【轨迹规划】贝塞尔曲线理解及C++实现n次贝塞尔曲线 的相关文章

  • ubuntu:安装cmake后查看版本报错:CMake Error: Could not find CMAKE_ROOT !!!

    问题描述 xff1a ubuntu18原来安装过cmake xff0c 想升级下版本 xff0c 在安装新版本的cmake完成后 xff0c 输入指令 xff1a cmake version 查看版本号时出现以下错误 xff1a CMake
  • g++ 编译选项

    返回主页 lsgxeva MyGitee https gitee com lsgx MyGithub https github com lsgxeva 博客园首页新随笔联系订阅管理 随笔 437 文章 0 评论 1 GCC 警告 优化以及调
  • STM32CubMx+FreeRTOS互斥锁和递归互斥锁(五)

    文章目录 FreeRTOS系统一 简绍二 STM32CubMx配置1 准备2 添加互斥锁2添加递归互斥锁 三 互斥锁1 代码2 测试 四 递归互斥锁1 代码2 测试 FreeRTOS系统 一 简绍 互斥锁 xff0c 谁获得的消息谁来释放
  • ESP8266-12F最小系统板程序烧录

    文章目录 ESP8266一 简介二 准备1 ESP8266 12F系统板2 转接板3 USB转串口模块4 烧录软件 三 连接烧录四 下载 ESP8266 一 简介 前一段时间一直用ESP8266 12F开发板来学习开发 xff0c 但是最近
  • ESP8266+0.96OLED驱动显示(I2C)

    文章目录 ESP8266一 简介二 管脚定义三 代码 ESP8266 一 简介 这篇我们说一下ESP8266来驱动OLED显示屏显示 xff0c 这里使用的是I2C的屏幕 xff0c 像Arduino中有好几个库可以驱动屏幕 xff0c 但
  • Node.js超详细指南(一)

    文章目录 一 概述二 Node js的特点1 异步I O2 事件驱动3 单线程4 支持微服务 三 Node js下载与安装安装步骤验证安装是否正确 一 概述 Node js的官方开发语言是JavaScript JavaScript是前端开发
  • Linux未设置root初始密码怎么办?

    问题描述 xff1a Linux未设置初始密码 xff0c 无法从用户状态切换到root状态怎么办 xff1f 是不是遇上下面的情况 xff1a 解决方案 xff1a 使用下列命令进行修改root密码 sudo passwd root
  • 计算机体系结构——功能部件

    一 功能部件 加法器 1 全加器 全加器 将两位本地二进制数和1位低位进位的数进行相加 xff0c 求的1位本地结果以及1位向高位进位的结果 简单来说就是3个input xff0c 2个output xff0c 这里的逻辑比较简单 xff0
  • Mac M1遇到更换清华源不成功问题解决办法(实测有效)

    遇到的问题 在使用如下命令更换为清华源后 xff0c update时出现了错误 xff1a bash span class token operator span c 39 echo span class token string 34 d
  • Ubuntu安装gcc遇到Depends依赖问题解决办法(XXX : Depends: gcc-12-base)

    gcc遇到依赖问题 libatomic1 Depends gcc 12 base 61 12 20220319 1ubuntu1 but 12 1 0 2ubuntu1 22 04 is to be installed libc6 dev
  • Tmux终端复用器下载安装及配置文件(超好用)

    1 Tmux简介 tmux是一款非常好用的终端复用软件 xff0c 曾经的你是不是还在为开n个终端而烦恼呢 xff0c 有了tmux就可以实现多终端显示在一个桌面上 xff0c 分屏丝滑 xff0c 当然还有其他功能 xff0c 比如保护现
  • make menuconfig遇到 warning:.config does not exists

    一生一芯PA0 xff1a PA0 xff1a make menuconfig 编译报错 问题描述 遇到的报错 xff1a 解决方案 xff1a 安装缺失的工具 xff1a 安装 bison 和 flex即可 xff0c flex和 bis
  • LibTorch1.7.1: error: ‘min_values’ is not a member of ‘at’

    错误描述 xff1a 原来用的libtorch的版本是1 5 0的 xff0c 今天换成了最新的1 7 1 xff0c 就报了这个错误 xff1a error min values is not a member of at 解决方法 xf
  • Github使用指南

    文章目录 注册成为用户GitHub功能及常用词汇板块说明Your profile使用仓库上传资源查找资源 注册成为用户 首次使用GitHub并准备长期使用需要先注册 xff0c 当然也可以以游客的方式进行浏览 登录官网GitHub Wher
  • 三孔插座接线方法(上地,左零,右火)

    三孔插座接线方法 一般三孔插座的线序 xff0c 如下图所示 xff1a 上 xff1a 地线 xff08 保护地 xff09 左 xff1a 零线 右 xff1a 火线 xff08 相线 xff09 正确的接接线方法 错误的接线方法 xf
  • CAN总线详解

    CAN总线协议 要了解报文数据帧的直接看第三点 1 CAN简介 CAN controller area network 控制器局域网是用于解决汽车众多控制部件之间的数据交换而开发的一种串行数据通信总线 其特点有 xff1a 总线上节点不分主
  • 【FreeRTOS】2. SVC系统调用

    SVC系统调用 问题 xff1a RTOS内核在何时去产生一个SVC系统调用 xff1f SVC中断服务里面使用的是MSP堆栈指针 xff0c 内核在何时切换为PSP指针 xff1f 1 产生SVC系统调用 FreeRTOS启动调度器的时候
  • 【FreeRTOS】3. PendSV异常

    PendSV异常 问题 xff1a 怎么触发PendSV异常 xff1f 何时使用MSP何时切换PSP xff1f PendSV如何实现上下文切换 xff1f 1 触发PendSV异常 在RTOS内核中 xff0c 任务切换的原理是 xff
  • PID控制器的介绍

    PID 控制算法介绍 在工程实际中 xff0c 应用最为广泛的调节器控制规律为比例 积分 微分控制 xff0c 简称 PID 控制 xff0c 又称 PID 调节 PID 控制器问世至今已有近 70 年历史 xff0c 它以其结构简单 稳定
  • 【智能车】图像二值化算法--大津法OTSU

    图像二值化算法 大津法OTSU 大津算法是一种图像二值化算法 xff0c 作用是确定将图像分成黑白两个部分的阈值 大津法是针对灰度值进行阈值分割二值化 xff0c 如果是彩色图像的话需要先转化成灰度图再进行计算 方差越大 xff0c 相关性

随机推荐