贝塞尔曲线算法之JS获取点

什么是贝塞尔曲线?

贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。

图片描述
这个一阶贝塞尔曲线绘制过程,黑点按百分比t从P0->P1移动,看不出什么呢~ 那继续看后面的图

图片描述
这个是二阶贝塞尔曲线,从P0->P1有个小绿点按百分比t运动,从P1->P2也有个小绿点按百分比t运动,两个绿点之间也有个小黑点按百分比t运动,这个黑点产生的轨迹就是一个二阶贝塞尔曲线。

图片描述
这个是三阶贝塞尔曲线,同理,绿点有3个,点与点之间都是按百分比t运动,最终得到一个小黑点。这个小黑点的运动轨迹就是三阶贝塞尔。

图片描述
同理,还有四阶贝塞尔。

图片描述
同理,六阶贝塞尔,N阶贝塞尔。

实际上,我们的运用中,3阶贝塞尔就已经足够满足我们的业务需求了,生活中,多个三阶贝塞尔曲线可以组合成任意一条曲线,我们的photoshop里面的钢笔工具就是3阶贝塞尔曲线实现的。

贝塞尔曲线方程解析

数学家已经给了我们公式:

图片描述

不好意思,高数还给了老师,这尼玛公式看不懂啊~ 没关系,我们简化下就能看懂了。

// t是百分比,a是参数

// 1阶贝塞尔曲线公式
function onebsr(t, a1, a2) {
    return a1 + (a2 - a1) * t;
}

// 2阶贝塞尔曲线公式
function twobsr(t, a1, a2, a3) {
    return ((1 - t) * (1 - t)) * a1 + 2 * t * (1 - t) * a2 + t * t * a3;
}

// 3阶贝塞尔曲线公式
function threebsr(t, a1, a2, a3, a4) {
    return a1 * (1 - t) * (1 - t) * (1 - t) + 3 * a2 * t * (1 - t) * (1 - t) + 3 * a3 * t * t * (1 - t) + a4 * t * t * t;
}

根据公式,我们可以带入坐标进行计算

/**
     * @desc 一阶贝塞尔
     * @param {number} t 当前百分比
     * @param {Array} p1 起点坐标
     * @param {Array} p2 终点坐标
     */
    oneBezier(t, p1, p2) {
        const [x1, y1] = p1;
        const [x2, y2] = p2;
        let x = x1 + (x2 - x1) * t;
        let y = y1 + (y2 - y1) * t;
        return [x, y];
    }

    /**
     * @desc 二阶贝塞尔
     * @param {number} t 当前百分比
     * @param {Array} p1 起点坐标
     * @param {Array} p2 终点坐标
     * @param {Array} cp 控制点
     */
    twoBezier(t, p1, cp, p2) {
        const [x1, y1] = p1;
        const [cx, cy] = cp;
        const [x2, y2] = p2;
        let x = (1 - t) * (1 - t) * x1 + 2 * t * (1 - t) * cx + t * t * x2;
        let y = (1 - t) * (1 - t) * y1 + 2 * t * (1 - t) * cy + t * t * y2;
        return [x, y];
    }

    /**
     * @desc 三阶贝塞尔
     * @param {number} t 当前百分比
     * @param {Array} p1 起点坐标
     * @param {Array} p2 终点坐标
     * @param {Array} cp1 控制点1
     * @param {Array} cp2 控制点2
     */
    threeBezier(t, p1, cp1, cp2, p2) {
        const [x1, y1] = p1;
        const [x2, y2] = p2;
        const [cx1, cy1] = cp1;
        const [cx2, cy2] = cp2;
        let x =
            x1 * (1 - t) * (1 - t) * (1 - t) +
            3 * cx1 * t * (1 - t) * (1 - t) +
            3 * cx2 * t * t * (1 - t) +
            x2 * t * t * t;
        let y =
            y1 * (1 - t) * (1 - t) * (1 - t) +
            3 * cy1 * t * (1 - t) * (1 - t) +
            3 * cy2 * t * t * (1 - t) +
            y2 * t * t * t;
        return [x, y];
    }

算法封装

我把贝塞尔曲线封装了下,添加了一个获取路径点的方法,然后使用span标签绘制到页面上的效果。

我们看看DEMO中1~3阶贝塞尔曲线上获取点的效果
图片描述
图片描述
图片描述

demo的github地址:https://github.com/mtsee/Bezier


前端问题总结
总结一些前端的问题~
1.3k 声望
78 粉丝
0 条评论
推荐阅读
推荐一款在线共享云桌面
项目多?文件多?团队成员难管理?为了解决这些问题,给大家推荐一款非常方便的在线共享云桌面:希尔桌面。可以创建多个桌面空间,把常用的文件、网址、视频、图片等资源存放到希尔桌面。

馒头阅读 474

从零搭建 Node.js 企业级 Web 服务器(零):静态服务
过去 5 年,我前后在菜鸟网络和蚂蚁金服做开发工作,一方面支撑业务团队开发各类业务系统,另一方面在自己的技术团队做基础技术建设。期间借着 Node.js 的锋芒做了不少 Web 系统,有的至今生气蓬勃、有的早已夭折...

乌柏木150阅读 12.4k评论 10

正则表达式实例
收集在业务中经常使用的正则表达式实例,方便以后进行查找,减少工作量。常用正则表达式实例1. 校验基本日期格式 {代码...} {代码...} 2. 校验密码强度密码的强度必须是包含大小写字母和数字的组合,不能使用特殊...

寒青56阅读 7.9k评论 11

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy46阅读 6.1k评论 12

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木66阅读 6.2k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs40阅读 6.4k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木44阅读 7.5k评论 6

1.3k 声望
78 粉丝
宣传栏