Canvas基础篇:二次贝塞尔曲线

前言

在我的上一篇文章中 Canvas基础篇:图形绘制,讲述了如何使用Canvas绘制直线和圆弧,本篇文章将讲解如何使用Canvas绘制二次贝塞尔曲线。

二次贝塞尔曲线

定义与概念

二次贝塞尔曲线:通过三个点来定义的一条曲线,这三个点分别代表起始点P1、控制点C1 和终点P2,其本质是一个二元一次方程。二次贝塞尔曲线从起始点开始,逐渐向控制点靠近,然后再从控制点向终点延伸,其形状由这三个点的位置共同决定。

数学表达式

给定起始点P1(x1, y1)、控制点C1(cx1, cy1) 和终点P2(x2, y2),二次贝塞尔曲线的参数方程如下:

B ( t ) = ( 1 − t ) 2 P 1 + 2 t ( 1 − t ) C 1 ​ + t 2 P 2 ​​,其中 t ∈ [ 0 , 1 ] 。 B(t)=(1−t)^2 P_1 + 2t(1−t) C_1​ + t^2 P_2​​,其中t∈[0,1]。 B(t)=(1t)2P1+2t(1t)C1+t2P2​​,其中t[0,1]
将其展开为极坐标形式如下:
x ( t ) = ( 1 − t ) 2 x 1 ​ + 2 t ( 1 − t ) c x 1 ​ + t 2 x 2 x(t) = (1−t)^2 x_1​ + 2t(1−t) cx_1 ​+ t^2 x_2 x(t)=(1t)2x1+2t(1t)cx1+t2x2
y ( t ) = ( 1 − t ) 2 y 1 ​ + 2 t ( 1 − t ) c y 1 ​ + t 2 y 2 y(t) = (1−t)^2 y_1 ​+ 2t(1−t) cy_1 ​+ t^2 y_2 y(t)=(1t)2y1+2t(1t)cy1+t2y2
随着t从0变化到1,(x(t),y(t))就会描绘出二次贝塞尔曲线。当t=0时,B(0)=P1,即曲线的起始点;当t=1时,B(1)=P2,即曲线的终点。

语法说明

在Canvas中,我们可以使用quadraticCurveTo() 方法绘制二次贝塞尔曲线,其语法如下:

quadraticCurveTo(cx1, cy1, x2, y2)

其中(cx1, cy1)代表控制点坐标,(x2, y2)代表终点坐标;对于起点坐标,一般通过moveTo() 方法定义。

二次贝塞尔曲线示例

效果预览

二次贝塞尔曲线示例

代码实现

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二次贝塞尔曲线</title>
  </head>
  <body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
      // 获取 canvas 元素和绘图上下文
      const canvas = document.getElementById('canvas');
      const ctx = canvas.getContext('2d');

      // 定义起始点、控制点和终点
      const startX = 50;
      const startY = 200;
      const controlX = 200;
      const controlY = 50;
      const endX = 350;
      const endY = 200;

      // 开始绘制路径
      ctx.beginPath();
      // 移动到起始点
      ctx.moveTo(startX, startY);
      // 绘制二次贝塞尔曲线
      ctx.quadraticCurveTo(controlX, controlY, endX, endY);
      // 设置线条样式
      ctx.strokeStyle = 'blue';
      ctx.lineWidth = 2;
      // 绘制路径
      ctx.stroke();
    </script>
  </body>
</html>

二次贝塞尔曲线图解

二次贝塞尔曲线静态图解

上述代码为我们直观的展示了如何在Canvas中绘制一条二次贝塞尔曲线,但是曲线中各个点的位置并没有标明,我们可以通过下面的图解示例为大家更好的理解二次贝塞尔曲线:
二次贝塞尔曲线图解
上图中,起始点P1到终点P2的曲线即为我们的目标曲线:二次贝塞尔曲线;起点P1到控制点C1和终点P2到控制点C1的两条线,为曲线的辅助线。
上述图示的源码,我放在了 二次贝塞尔曲线静态图解 HTML 代码资源 ,有兴趣可以下载预览!

二次贝塞尔曲线动态图解

当然,上面的二次贝塞尔曲线静态图解可能还是不够直观,在这里我们通过固定起点和终点,动态调整控制点的位置,来更直观地观察二次贝塞尔曲线的变化:
二次贝塞尔曲线动态图解

上述图示的源码,我放在了 二次贝塞尔曲线动态图解 HTML 代码资源 ,有兴趣可以下载预览!

二次贝塞尔曲线应用实例

官方实例

在Canvas官方文档中,使用了多个二次贝塞尔曲线来渲染对话气泡,其效果图如下所示:

效果预览

二次贝塞尔曲线官方实例

代码实现
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二次贝塞尔曲线官方实例</title>
  </head>
  <body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
      // 获取 canvas 元素和绘图上下文
      const canvas = document.getElementById('canvas');
      const ctx = canvas.getContext('2d');

      ctx.beginPath();
      ctx.moveTo(75, 25);
      ctx.quadraticCurveTo(25, 25, 25, 62.5);
      ctx.quadraticCurveTo(25, 100, 50, 100);
      ctx.quadraticCurveTo(50, 120, 30, 125);
      ctx.quadraticCurveTo(60, 120, 65, 100);
      ctx.quadraticCurveTo(125, 100, 125, 62.5);
      ctx.quadraticCurveTo(125, 25, 75, 25);
      ctx.stroke();
    </script>
  </body>
</html>

自定义实例:波浪线

上述我们引入了Canvas官方文档中的一个实例,这里我们自定义一个实例:使用二次贝塞尔曲线实现一个波浪线,其效果图如下所示:

效果预览

二次贝塞尔曲线自定义实例-波浪线

代码实现
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二次贝塞尔曲线自定义实例-波浪线</title>
  </head>
  <body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script>
      // 获取 canvas 元素和绘图上下文
      const canvas = document.getElementById('canvas');
      const ctx = canvas.getContext('2d');

      const startX = 0;
      const startY = canvas.height / 2;
      const waveHeight = 50;
      const waveLength = 100;
      const numWaves = Math.ceil(canvas.width / waveLength);

      ctx.beginPath();
      ctx.moveTo(startX, startY);
      for (let i = 0; i < numWaves; i++) {
        const controlX = startX + waveLength * (i + 0.5);
        const controlY = startY + (i % 2 === 0 ? waveHeight : -waveHeight);
        const endX = startX + waveLength * (i + 1);
        const endY = startY;
        ctx.quadraticCurveTo(controlX, controlY, endX, endY);
      }
      ctx.stroke();
    </script>
  </body>
</html>

结语

本文主要介绍了二次贝塞尔曲线的相关内容,包括曲线定义、语法、图形示例和图解,在文章最后给出了两个二次贝塞尔曲线的应用实例。对于文章中错误的地方或者有任何问题,欢迎在评论区留言分享!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值