上一集:前端canvas基础(一)

🥞贝塞尔曲线

那么首先我们先来看看维基百科-贝塞尔曲线对贝塞尔曲线的定义是什么样的:


在数学的数值分析领域中,贝塞尔曲线(英语:Bézier curve)是计算机图形学中相当重要的参数曲线。更高维度的广泛化贝塞尔曲线就称作贝兹曲面,其中贝兹三角是一种特殊的实例。

贝塞尔曲线于1962年,由法国工程师皮埃尔·贝兹(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由保尔·德·卡斯特里奥于1959年运用德卡斯特里奥算法开发,以稳定数值的方法求出贝塞尔曲线。


🌭建构贝塞尔曲线

🍪 一、线性曲线
线性贝塞尔曲线函数中的t会经过由P0至P1的B(t)所描述的曲线。例如当t=0.25时,B(t)即一条由点径的四分之一处。就像由0至1的连续t,B(t)描述一条由P0至P1的直线

android Path画出的贝塞尔曲线是几阶的 前端贝塞尔曲线_贝塞尔曲线


🍨 二、二次曲线

为建构二次贝塞尔曲线,可以中介点Q0和Q1作为由0至1的t:

由P0至P1的连续点Q0,描述一条线性贝塞尔曲线。

由P1至P2的连续点Q1,描述一条线性贝塞尔曲线。

由Q0至Q1的连续点B(t),描述一条二次贝塞尔曲线

android Path画出的贝塞尔曲线是几阶的 前端贝塞尔曲线_前端_02


android Path画出的贝塞尔曲线是几阶的 前端贝塞尔曲线_前端_03


🍯 三、高端曲线

为建构高端曲线,便需要相应更多的中介点。对于三次曲线,可由线性贝塞尔曲线描述的中介点Q0、Q1、Q2,和由二次曲线描述的点R0、R1所建构:

android Path画出的贝塞尔曲线是几阶的 前端贝塞尔曲线_前端_04


android Path画出的贝塞尔曲线是几阶的 前端贝塞尔曲线_html_05


对于四次曲线,可由线性贝塞尔曲线描述的中介点Q0、Q1、Q2、Q3,由二次贝塞尔曲线描述的点R0、R1、R2,和由三次贝塞尔曲线描述的点S0、S1所建构:

android Path画出的贝塞尔曲线是几阶的 前端贝塞尔曲线_前端_06


android Path画出的贝塞尔曲线是几阶的 前端贝塞尔曲线_Math_07


五阶贝塞尔曲线

android Path画出的贝塞尔曲线是几阶的 前端贝塞尔曲线_Math_08


  • 看过了维基百科相信你对贝塞尔曲线已经有个大概的认识了,当然,如果还想知道更多一点,你也可以去贝塞尔曲线-百度百科看看。那接下来我们看看在canvas中是怎么应用各种贝塞尔曲线的

canvas应用贝塞尔曲线

主要的API:

  • context.quadraticCurveTo(cpx,cpy,x,y) // 创建二次贝塞尔曲线
    cpx 贝塞尔控制点的 x 坐标
    cpy 贝塞尔控制点的 y 坐标
    x 结束点的 x 坐标
    y 结束点的 y 坐标
  • context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y) // 创建三次贝塞尔曲线
    cp1x 第一个贝塞尔控制点的 x 坐标
    cp1y 第一个贝塞尔控制点的 y 坐标
    cp2x 第二个贝塞尔控制点的 x 坐标
    cp2y 第二个贝塞尔控制点的 y 坐标
    x 结束点的 x 坐标
    y 结束点的 y 坐标

🍧 实例说明

🍦基础
<!DOCTYPE html>
<html>
<head>
    <title>贝塞尔基础</title>
    <meta charset="utf-8" />
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");
            //绘制贝塞尔曲线
            cxt.moveTo(20, 80);
            cxt.quadraticCurveTo(100, 20, 160, 120);//创建二次贝塞尔曲线
            cxt.moveTo(200,80)
            var cx1 = 200;
            var cy1 = 80;
            var cx2 = 280;
            var cy2 = 150;
            var endX = 380;
            var endY = 30;
            cxt.bezierCurveTo(cx1, cy1, cx2, cy2, endX, endY); //创建三次贝塞尔曲线
            cxt.stroke()
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="400" height="150" style="border:1px dashed gray;"></canvas>
</body>
</html>

android Path画出的贝塞尔曲线是几阶的 前端贝塞尔曲线_html_09

🍩N叶草
<!DOCTYPE html>
<html>
<head>
    <title>N叶草</title>
    <meta charset="utf-8" />
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");

            createLeaf(cxt, 8, cnv.width / 2, cnv.height / 2, 10, 100);
            //定义填充颜色为浅绿色
            cxt.fillStyle = "#00FF99";
            cxt.fill();
        }
        /*
         * createLeaf()用于绘制N叶草
         * n:n片
         * dx、dy:花朵中心位置的坐标
         * size:控制花朵的大小
         * length:控制花瓣长度
         */
        function createLeaf(cxt, n, dx, dy, size, length) {
            cxt.beginPath();
            cxt.moveTo(dx, dy + size);
            var degree = 2 * Math.PI / n;
            for (var i = 1; i < n + 1; i++) {
                //计算控制点坐标
                var cx1 = Math.sin((i - 1) * degree) * length + dx;
                var cy1 = Math.cos((i - 1) * degree) * length + dy;
                var cx2 = Math.sin(i * degree) * length + dx;
                var cy2 = Math.cos(i * degree) * length + dy;
                //计算结束点的坐标
                var x = Math.sin(i * degree) * size + dx;
                var y = Math.cos(i * degree) * size + dy;
                cxt.bezierCurveTo(cx1, cy1, cx2, cy2, x, y);
            }
            cxt.closePath();
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="200" height="150" style="border:1px dashed gray;"></canvas>
</body>
</html>

android Path画出的贝塞尔曲线是几阶的 前端贝塞尔曲线_前端_10

  • 这里,我们在一条路径中连续定义首尾相连的多段贝塞尔曲线,其中每段三次贝塞尔曲线的起点和终点都落在圆心为(dx,dy)、半径为size的圆弧上,而每段圆弧的两个控制点落在圆心为(dx,dy)、半径为length的圆弧上,于是形成了N叶草的图形。其中,起点、终点和控制点坐标是使用正弦和余弦函数计算出来的。
    总的来说,使用二次或三次贝塞尔曲线来绘制一个图形是相当有挑战的,因为这不像在矢量绘图软件Adobe Illustrator(简称AI)里那样有即时的视觉反馈(所见即所得)。所以用它来画复杂图形比较麻烦。但是从理论上来说,任何复杂的图形都可以用贝塞尔曲线绘制出来!这也是贝塞尔曲线强大之处。

🍬最后

关于canvas中贝塞尔曲线的相关信息就先总结到这里,后面有时间会持续更新