Bezier曲线的公式推导及代码实现

2023-11-05

本文仅简述Bezier曲线的公式推导,并给出了一种代码实现。在阅读本文之前,请确保你已经对Bezier曲线的背景知识有所了解。相关知识可以通过以下课程进行学习:MOOC-计算机图形学-中国农业大学-赵明或者观看B站搬运版

算法原理

给定 n + 1 n+1 n+1个控制点 P i ( i = 0 , 1 , ⋯   , n ) P_i(i=0,1,\cdots,n) Pi(i=0,1,,n),构造多项式函数
P ( u ) = ∑ i = 0 n P i ⋅ B E Z i , n ( u ) , 0 ⩽ u ⩽ 1   , (1) \mathcal{P}(u)=\sum_{i=0}^{n}P_i\cdot BEZ_{i,n}(u), \quad 0\leqslant u\leqslant 1 \thinspace, \tag{1} P(u)=i=0nPiBEZi,n(u),0u1(1)
来逼近曲线。其中 B E Z i , n ( u ) BEZ_{i,n}(u) BEZi,n(u)称为 n n n次Bernstein基函数,且有
B E Z i , n ( u ) = C n i u i ( 1 − u ) n − i , ( i = 0 , 1 , ⋯   , n u ∈ [ 0 , 1 ] )   。 (2) BEZ_{i,n}(u)=C_n^i u^i(1-u)^{n-i}, \quad \left(\begin{array}{l} i=0,1,\cdots,n \\ u\in[0,1] \end{array}\right) \thinspace。 \tag{2} BEZi,n(u)=Cniui(1u)ni,(i=0,1,,nu[0,1])(2)

对于公式(1),函数 P ( u ) \mathcal{P}(u) P(u)将实数区间 [ 0 , 1 ] [0,1] [0,1]映射到实数域上的点集,该点集里的点组成了所求的逼近曲线。 B E Z i , n ( u ) BEZ_{i,n}(u) BEZi,n(u)可以看作是控制点 P i P_i Pi u u u下的权值。因为 B E Z i , n ( u ) BEZ_{i,n}(u) BEZi,n(u)具有权性:
∑ i = 0 n B E Z i , n ( u ) ≡ 1 , ∀ u ∈ ( 0 , 1 )   。 (3) \sum_{i=0}^{n} BEZ_{i,n}(u) \equiv 1, \quad \forall u\in(0,1) \thinspace。\tag{3} i=0nBEZi,n(u)1,u(0,1)(3)

我们定义:
β i ( r ) = { P i , r = 0 ( 1 − u ) β i ( r − 1 ) + u β i + 1 ( r − 1 ) , r = 1 , 2 , ⋯   , n   , (4) \beta_{i}^{(r)} = \begin{cases} P_i, & r = 0 \\ (1-u)\beta_{i}^{(r-1)} + u\beta_{i+1}^{(r-1)}, & r = 1,2,\cdots,n \end{cases} \thinspace, \tag{4} βi(r)={Pi,(1u)βi(r1)+uβi+1(r1),r=0r=1,2,,n(4)
其中 i = 0 , 1 , ⋯   , n − r i=0,1,\cdots,n-r i=0,1,,nr

可以证明(证明过程参见维基百科De Casteljau算法):
P ( u ) = ∑ i = 0 n β i ( 0 ) ⋅ B E Z i , n ( u ) = β 0 ( n )   。 (5) \mathcal{P}(u) = \sum_{i=0}^{n} \beta_{i}^{(0)}\cdot BEZ_{i,n}(u) = \beta_{0}^{(n)} \thinspace。 \tag{5} P(u)=i=0nβi(0)BEZi,n(u)=β0(n)(5)

于是得到算法逻辑如下:

  • 在实数区间 [ 0 , 1 ] [0,1] [0,1]上大量采样。对于每个样本 u u u,计算 P ( u ) \mathcal{P}(u) P(u)
  • 根据公式(5),我们可以通过计算 β 0 ( n ) \beta_{0}^{(n)} β0(n)来计算 P ( u ) \mathcal{P}(u) P(u)
  • β 0 ( n ) \beta_{0}^{(n)} β0(n)可以通过公式(4)进行递归计算。

代码实现

def draw_curve(p_list):
	"""
    :param p_list: (list of list of int: [[x0, y0], [x1, y1], [x2, y2], ...]) 曲线的控制点坐标列表
    :return: (list of list of int: [[x_0, y_0], [x_1, y_1], [x_2, y_2], ...]) 绘制结果的像素点坐标列表
    """
    result = []
    n = len(p_list) - 1
    freq = 1000
    for u in range(freq + 1):
        u /= freq
        tmp = [[p[0], p[1]] for p in p_list]
        for r in range(1, n + 1):
            tmp = [
                [(1 - u) * tmp[i][0] + u * tmp[i + 1][0],
                 (1 - u) * tmp[i][1] + u * tmp[i + 1][1]
                 ] for i in range(n - r + 1)
            ]
        result.append([round(tmp[0][0]), round(tmp[0][1])])
    return result
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Bezier曲线的公式推导及代码实现 的相关文章

随机推荐

  • ajax二进制图片显示,ajax请求图片,二进制形式显示图片有问题

    我想通过ajax请求图片vm ajaxGet img logo png function data 这里data 就是图片本身的文件流 测试ajax没有问题 var img document createElement img img on
  • 数据库连接接口(驱动)

    基于go python C 语言实现的数据库驱动 数据库 类型 Go语言 Python语言 C C 语言 MySQL 多线程关系型 github com go sql driver mysql mysql connector和PyMySQL
  • kubernetes(k8s) quick start

    文章目录 安装 使用kubeadm 环境准备 1 设置主机名与时区 2 添加hosts网络主机配置 三台虚拟机都要设置 3 关闭 selinux 关闭防火墙 关闭 swap 4 安装kubeadm 5 配置网桥 6 通过镜像安装k8s 7
  • YouComplete问题汇总

    1 ycm的readme中给出推荐版本需要注意一下 2 clone这个ycm 需要翻墙 不然完成不了编译 3 编译手段 按照给出的python需求进行编译 python3 install py clang completer 4 编译期间会
  • Unit8Array 转 Unit16Array

    vat u8 new Unit8Array data const buf Buffer from u8 const u16 new Uint16Array buf buffer buf byteOffset buf byteLength U
  • android:基于http的get和post请求

    1 说在前面 初次接触android的网络编程 现在再一次被刷新了世界观 android程序往往扮演的是一个 客户端 的角色 和服务器之间进行沟通 从而获得服务器传来的数据 通过服务器传回的信息丰富程序的内容 2 Http协议 2 1 概念
  • ESP32 LVGL8.1 实现太空人显示(29)

    文章目录 一 ESP32 LVGL工程配置 1 1从库中下载LVGL代码 1 2配置适合ESP32 液晶屏 1 3编译下载测试 二 GIF图片处理 2 1下载gif图片 2 2将gif图片按照帧率导出成图片 2 3导出的图片背景处理 2 4
  • 以蛋白质功能研究为题写一篇综述论文

    我们现在知道蛋白质是生物体的基本结构和功能的基础 它不仅可以提供机体所需的能量 还可以参与其他重要的生理过程 蛋白质的结构和功能与其化学性质密切相关 本文将重点介绍蛋白质的功能 并研究一些如何利用蛋白质来探索它在生物体中的作用 通过研究 我
  • 模拟电路设计学习

    模拟电路设计 1 功能示意图 三个滑动变阻器可以对3路恒流源输出量进行调节 从而改变LED发光亮度 ADS1220芯片 需要使用SPI模式1 目前使用的是两线制接线方式 不需要校准 加热丝PID控温 在湿度变送器项目中有涉及 光电采集板不对
  • 第十四章 我的毕业之作—苏州大学过程化管理系统

    大四上学期忙活着考研 虽然考研不顺利 但是上学期着急忙慌的在所难免 没做什么事情 也没有找工作 所以去年6月份接的项目一直推迟到现在才算大功告成 这虽然不是我做的最后一个项目 但是这是我的毕业设计 导师就是我一直跟随的陈老师 这个系统在我所
  • Dubbo 在 K8s 下的思考

    作者 曹胜利 Apache Dubbo PMC 导读 Dubbo 作为高性能 Java RPC 框架的刻板印象早已深入人心 在 Cloud Native 的架构选型上 Spring Cloud 或许才是业界的优先选择 实际上 Dubbo 已
  • nodejs将rtsp视频流打上水印后通过websocket发送给前端

    网上有把rtsp流通过websocket发送到前端的方法 就是用rtspStream 具体代码如下 var stream require node rtsp stream stream new stream name name stream
  • mount nfs 共享 用户名和组更改及没有写的权限

    今天工作当中碰到了这个问题 etc exports home ict ict data NewsData 10 0 21 65 rw home ict ict data ForumData 10 0 21 75 rw 结果在客户端mount
  • 招聘专用「人才洞察工具」|One Model

    人力管理 Talent management 在企业运营中起着关键的作用 不仅有助于优化人力资源的配置 还可以提高员工绩效 满意度和忠诚度 推动企业实现可持续增长 在人工智能蓬勃发展的当下 借助 AI 进行人才洞察也成为了现实 One Mo
  • InputStream&FileOutputStream文件复制后文件变大

    InputStream is FileOutputStream fos new FileOutputStream 保存文件路径 名称 byte b new byte 1024 while is read b 1 fos write b 写入
  • 大数据运维存档(3)HDFS&ZooKeeper调优与排障

    一 HDFS篇 1 巡检 HDFS 为集群提供高可用性弹性存储服务 是集群的存储主体 每日早晚巡检HDFS 服务 包括HDFS 服务可用性 存储使用率 datanode 是否有故障盘等 1 1 HDFS 总体状态 HDFS 状态 如下的红色
  • WDK学习笔记_docker容器客户端_fabric-go-sdk

    文章目录 摘要 一 智能合约在区块链上的部署步骤 二 用docker容器创建的客户端在命令行上与区块链网络进行交互 2 1 容器内创建通道 2 2 加入通道 2 3 安装链码 2 4 初始化链码 2 5 调用链码 三 fabric go s
  • Openlayers 快速上手教程

    欢迎点赞 收藏 留言 如有错误敬请指正 1 Openlayers简介 Openlayers 是开源的前端地图框架 官网地址 https openlayers org 它的作用主要是用于展现数据并且提供相应的地图操作工具 1 1 官网首页 1
  • C语言经典100例题(33)--学习goto与clrscr()函数

    目录 题目 问题分析 代码 运行结果 题目 学习goto 与clrscr 函数 问题分析 goto关键字 goto关键字直接将控件传递给标签名称指定的语句 gotoxy 定位函数 clrscr函数 清屏函数 注意在VS2019中没有这个函数
  • Bezier曲线的公式推导及代码实现

    本文仅简述Bezier曲线的公式推导 并给出了一种代码实现 在阅读本文之前 请确保你已经对Bezier曲线的背景知识有所了解 相关知识可以通过以下课程进行学习 MOOC 计算机图形学 中国农业大学 赵明或者观看B站搬运版 算法原理 给定 n