当前位置: 首页 > news >正文

p5.js 圆弧的用法

点赞 + 关注 + 收藏 = 学会了

在 p5.js 中,arc() 函数用于绘制圆弧,它是创建各种圆形图形和动画的基础。圆弧本质上是椭圆的一部分,由中心点、宽度、高度、起始角度和结束角度等参数定义。通过灵活运用 arc() 函数可以轻松创建饼图、仪表盘、时钟等常见 UI 组件,以及各种创意图形效果。

arc() 的基础语法

基础语法

arc() 函数的完整语法如下:

arc(x, y, w, h, start, stop, [mode], [detail])

核心参数解释:

  • x, y:圆弧所在椭圆的中心点坐标

  • w, h:椭圆的宽度和高度,如果两者相等,则绘制的是圆形的一部分

  • start, stop:圆弧的起始角度和结束角度,默认以弧度(radians)为单位

可选参数:

  • mode:定义圆弧的填充样式,可选值为OPEN(开放式半圆)、CHORD(封闭式半圆)或PIE(闭合饼图)

  • detail:仅在 WebGL 模式下使用,指定组成圆弧周长的顶点数量,默认值为 25

角度单位与转换

在 p5.js 中,角度可以使用弧度或角度两种单位表示:

  • 默认单位是弧度:0 弧度指向正右方(3 点钟方向),正角度按顺时针方向增加

  • 使用角度单位:可以通过 angleMode(DEGREES) 函数将角度单位设置为角度

两种单位之间的转换关系:

  • 360 度 = 2π 弧度

  • 180 度 = π 弧度

  • 90 度 = π/2 弧度

p5.js 提供了两个辅助函数用于单位转换:

  • radians(degrees):将角度转换为弧度

  • degrees(radians):将弧度转换为角度

举个例子(基础示例)

举个例子讲解一下如何使用 arc() 函数绘制不同角度的圆弧。

在这里插入图片描述

function setup() {createCanvas(400, 400);angleMode(DEGREES); // 使用角度单位
}function draw() {background(220);// 绘制不同角度的圆弧arc(100, 100, 100, 100, 0, 90); // 90度圆弧arc(250, 100, 100, 100, 0, 180); // 180度圆弧arc(100, 250, 100, 100, 0, 270); // 270度圆弧arc(250, 250, 100, 100, 0, 360); // 360度圆弧(整圆)
}

这段代码会在画布上绘制四个不同角度的圆弧,从 90 度到 360 度不等。注意,当角度为 360 度时,实际上绘制的是一个完整的圆形。

三种圆弧模式:OPEN、CHORD 与 PIE

arc() 函数的第七个参数mode决定了圆弧的填充方式,有三种可选值:

  • OPEN(默认值):仅绘制圆弧本身,不填充任何区域

  • CHORD:绘制圆弧并连接两端点形成闭合的半圆形区域

  • PIE:绘制圆弧并连接两端点与中心点形成闭合的扇形区域

这三种模式不需要手动定义,p5.js 已经在全局范围内定义好了这些常量。

举个例子:

在这里插入图片描述

function setup() {createCanvas(400, 200);angleMode(DEGREES);
}function draw() {background(220);// 绘制不同模式的圆弧arc(100, 100, 100, 100, 0, 270, OPEN);arc(220, 100, 100, 100, 0, 270, CHORD);arc(340, 100, 100, 100, 0, 270, PIE);
}

这段代码会在画布上绘制三个 270 度的圆弧,分别展示 OPENCHORDPIE 三种模式的效果。可以明显看到,OPEN 模式只绘制弧线,CHORD 模式连接两端点形成闭合区域,而 PIE 模式则从两端点连接到中心点形成扇形。

如何选择合适的模式

选择圆弧模式时,应考虑以下因素:

  • 视觉效果需求:需要纯弧线效果时选择 OPEN,需要闭合区域时选择 CHORDPIE

  • 应用场景:饼图通常使用 PIE 模式,仪表盘可能使用 CHORD 模式,而简单装饰线条可能使用 OPEN 模式

  • 填充与描边需求:不同模式对填充和描边的处理方式不同,需要根据设计需求选择

值得注意的是,arc() 函数绘制的默认是填充的扇形区域。如果想要获取纯圆弧(没有填充区域),可以使用 noFill() 函数拒绝 arc() 函数的填充。

做几个小demo玩玩

简易数字时钟

在这个示例中,我将使用 arc() 函数创建一个简单的数字时钟,显示当前的小时、分钟和秒数。

在这里插入图片描述

let hours, minutes, seconds;function setup() {createCanvas(400, 400);angleMode(DEGREES); // 使用角度单位
}function draw() {background(220);// 获取当前时间let now = new Date();hours = now.getHours();minutes = now.getMinutes();seconds = now.getSeconds();// 绘制时钟边框stroke(0);strokeWeight(2);noFill();arc(width/2, height/2, 300, 300, 0, 360);// 绘制小时刻度strokeWeight(2);for (let i = 0; i < 12; i++) {let angle = 90 - i * 30;let x1 = width/2 + 140 * cos(radians(angle));let y1 = height/2 + 140 * sin(radians(angle));let x2 = width/2 + 160 * cos(radians(angle));let y2 = height/2 + 160 * sin(radians(angle));line(x1, y1, x2, y2);}// 绘制分钟刻度strokeWeight(1);for (let i = 0; i < 60; i++) {let angle = 90 - i * 6;let x1 = width/2 + 150 * cos(radians(angle));let y1 = height/2 + 150 * sin(radians(angle));let x2 = width/2 + 160 * cos(radians(angle));let y2 = height/2 + 160 * sin(radians(angle));line(x1, y1, x2, y2);}// 绘制小时指针let hourAngle = 90 - (hours % 12) * 30 - minutes * 0.5;let hourLength = 80;let hx = width/2 + hourLength * cos(radians(hourAngle));let hy = height/2 + hourLength * sin(radians(hourAngle));line(width/2, height/2, hx, hy);// 绘制分钟指针let minuteAngle = 90 - minutes * 6;let minuteLength = 120;let mx = width/2 + minuteLength * cos(radians(minuteAngle));let my = height/2 + minuteLength * sin(radians(minuteAngle));line(width/2, height/2, mx, my);// 绘制秒针stroke(255, 0, 0);let secondAngle = 90 - seconds * 6;let secondLength = 140;let sx = width/2 + secondLength * cos(radians(secondAngle));let sy = height/2 + secondLength * sin(radians(secondAngle));line(width/2, height/2, sx, sy);// 显示当前时间文本noStroke();fill(0);textSize(24);text(hours + ":" + nf(minutes, 2, 0) + ":" + nf(seconds, 2, 0), 50, 50);
}

关键点解析:

  1. 获取当前时间:使用Date()对象获取当前的小时、分钟和秒数

  2. 角度计算:根据时间值计算指针的旋转角度,注意将角度转换为 p5.js 使用的坐标系(0 度指向正上方)

  3. 刻度绘制:使用循环绘制小时和分钟刻度,每个小时刻度间隔 30 度,每个分钟刻度间隔 6 度

  4. 指针绘制:根据计算的角度和长度绘制小时、分钟和秒针,注意秒针使用红色以区分

  5. 时间文本显示:使用text()函数在画布左上角显示当前时间

饼图

在这个示例中,我将创建一个简单的饼图,展示不同类别数据的比例。

在这里插入图片描述

let data = [30, 10, 45, 35, 60, 38, 75, 67]; // 示例数据
let total = 0;
let lastAngle = 0;function setup() {createCanvas(720, 400);angleMode(DEGREES); // 使用角度单位noStroke(); // 不绘制边框total = data.reduce((a, b) => a + b, 0); // 计算数据总和
}function draw() {background(100);pieChart(300, data); // 调用饼图绘制函数
}function pieChart(diameter, data) {lastAngle = 0; // 重置起始角度for (let i = 0; i < data.length; i++) {// 设置圆弧的灰度值,map函数将数据映射到0-255的灰度范围let gray = map(i, 0, data.length, 0, 255);fill(gray);// 计算当前数据点的角度范围let startAngle = lastAngle;let endAngle = lastAngle + (data[i] / total) * 360;// 绘制圆弧arc(width / 2,height / 2,diameter,diameter,startAngle,endAngle,PIE // 使用PIE模式创建扇形);lastAngle = endAngle; // 更新起始角度为下一个数据点做准备}
}

关键点解析:

  1. 数据准备:定义示例数据数组data,并计算数据总和total

  2. 颜色设置:使用map()函数将数据索引映射到 0-255 的灰度范围,实现渐变效果

  3. 角度计算:根据每个数据点的值与总和的比例计算对应的角度范围

  4. 圆弧绘制:使用PIE模式绘制每个数据点对应的扇形,形成完整的饼图

这个饼图示例可以通过添加标签、交互效果或动态数据更新来进一步增强功能。

描边效果

在 p5.js 中,我们可以通过以下函数定制圆弧的描边效果:

  • stroke(color):设置描边颜色

  • strokeWeight(weight):设置描边宽度

  • strokeCap(cap):设置描边端点样式(可选值:BUTT, ROUND, SQUARE)

  • strokeJoin(join):设置描边转角样式(可选值:MITER, ROUND, BEVEL)

以下示例展示了如何定制圆弧的描边效果:

在这里插入图片描述

function setup() {createCanvas(400, 200);angleMode(DEGREES);
}function draw() {background(220);// 示例1:粗红色描边stroke(255, 0, 0);strokeWeight(10);arc(100, 100, 100, 100, 0, 270);// 示例2:带圆角端点的描边stroke(0, 255, 0);strokeWeight(10);strokeCap(ROUND);arc(220, 100, 100, 100, 0, 270);// 示例3:带阴影效果的描边stroke(0, 0, 255);strokeWeight(15);strokeCap(SQUARE);arc(340, 100, 100, 100, 0, 270);// 恢复默认设置noStroke();
}

关键点解析:

  1. 颜色设置:使用stroke()函数设置不同颜色的描边

  2. 宽度设置:使用strokeWeight()函数调整描边粗细

  3. 端点样式:使用strokeCap()函数设置描边端点的样式(圆角效果特别适合圆弧)

  4. 阴影效果:通过增加描边宽度并偏移绘制位置可以创建简单的阴影效果

填充效果

在 p5.js 中,我们可以通过以下函数定制圆弧的填充效果:

  • fill(color):设置填充颜色

  • noFill():禁用填充效果

  • colorMode(mode):设置颜色模式(RGB、HSB 等)

  • alpha():设置颜色透明度

以下示例展示了如何定制圆弧的填充效果:

在这里插入图片描述

function setup() {createCanvas(400, 200);angleMode(DEGREES);colorMode(HSB, 360, 100, 100); // 使用HSB颜色模式
}function draw() {background(220);// 示例1:单色填充fill(120, 100, 100); // 绿色arc(100, 100, 100, 100, 0, 270);// 示例2:渐变填充noFill();stroke(0, 0, 100);strokeWeight(10);for (let i = 0; i < 360; i += 10) {fill(i, 100, 100);arc(220, 100, 100, 100, i, i+10);}// 示例3:透明填充fill(240, 100, 100, 50); // 半透明蓝色arc(340, 100, 100, 100, 0, 270);// 恢复默认设置noFill();stroke();
}

关键点解析:

  1. 颜色模式:使用colorMode()函数切换到 HSB 模式,方便创建渐变效果

  2. 单色填充:直接使用fill()函数设置单一填充颜色

  3. 渐变填充:通过循环绘制多个小角度的圆弧,每个使用不同的色相值实现渐变效果

  4. 透明度设置:在fill()函数中添加第四个参数(0-100)设置透明度

旋转圆弧

在 p5.js 中创建圆弧动画非常简单,主要通过以下方法实现:

  • **draw()**函数:每秒自动执行约 60 次,用于更新动画帧

  • 变量控制:使用变量控制圆弧的参数(如位置、大小、角度等)

  • frameRate(fps):设置动画帧率(可选)

  • millis():获取当前时间(毫秒),用于精确控制动画时间

圆弧动画效果示例:

在这里插入图片描述

let angle = 0;function setup() {createCanvas(400, 400);angleMode(DEGREES);
}function draw() {background(220);// 绘制旋转的红色圆弧stroke(255, 0, 0);strokeWeight(10);arc(width/2, height/2, 300, 300, angle, angle + 90);// 更新角度值,实现旋转效果angle += 2; // 调整这个值可以改变旋转速度// 恢复默认设置noStroke();
}

关键点解析:

  1. 角度变量:使用 angle 变量控制圆弧的起始角度

  2. 角度更新:在每次 draw() 调用时增加angle值,实现旋转效果

  3. 速度控制:通过调整每次增加的角度值(这里是 2 度)控制旋转速度

弧度与角度的转换技巧

在 p5.js 中,arc()函数默认使用弧度作为角度单位,但我们通常更习惯使用角度。以下是一些转换技巧:

  • 角度转弧度:使用 radians(degrees) 函数将角度转换为弧度

  • 弧度转角度:使用 degrees(radians) 函数将弧度转换为角度

  • 设置角度单位:使用 angleMode(DEGREES) 函数将全局角度单位设置为角度,这样 arc() 函数就可以直接使用角度值

  • 常见角度值:记住一些常用角度的弧度值,如 90 度 = PI/2,180 度 = PI,270 度 = 3PI/2,360 度 = 2PI

圆弧绘制的常见问题与解决方案

在使用 arc() 函数时,可能会遇到以下问题:

  1. arc () 函数中的 bug:当 start_angle == end_angle 时,可能会出现意外绘制效果。例如,当 start_angle == end_angle == -PI/2 时会绘制一个半圆,这不符合预期。解决方案是避免 start_angleend_angle 相等。

  2. 起始角度的位置:在 p5.js 中,0 弧度(或 0 度,如果使用 angleMode(DEGREES))指向正右方(3 点钟方向),而不是数学上的正上方。这可能导致方向与预期不符。

  3. 描边宽度的影响:较宽的描边会使圆弧看起来比实际大。这是因为描边会向路径的两侧扩展。如果需要精确控制大小,可以考虑将arc()的尺寸适当减小,或者使用 shapeMode() 函数调整坐标系。

  4. 浮点精度问题:在进行角度计算时,尤其是涉及到除法和循环时,可能会遇到浮点精度问题。建议使用 nf() 函数(如 nf(value, 2, 0) )来格式化显示的数值,避免显示过多的小数位。


以上就是本文的全部内容啦,如果想了解更多 p5.js 的玩法可以关注 《P5.js中文教程》

点赞 + 关注 + 收藏 = 学会了

http://www.lryc.cn/news/596746.html

相关文章:

  • Git GitHub精通:前端协作开发的“瑞士军刀“!
  • ubuntu22.04 录视屏软件推荐
  • Vercel AI SDK 3.0 学习入门指南
  • Android-API调用学习总结
  • javaSE(从0开始)day14
  • 数据交换---JSON格式
  • C语言:第11天笔记
  • JavaScript 02 数据类型和运算符数组对象
  • numpy库 降维,矩阵创建与元素的选取,修改
  • 生成式人工智能展望报告-欧盟-01-引言
  • Vue开发常用
  • 2025 年最新 AI 技术:全景洞察与深度解析​
  • 操作系统:系统调用(System Calls)
  • 深入理解程序链接机制:静态链接、ELF加载与动态库实现原理
  • 计算机底层入门 05 汇编学习环境通用寄存器内存
  • [LLM]Synthetic Visual Genome
  • gflags使用
  • 【锁】MySQL中有哪几种锁?
  • 【C语言进阶】动态内存管理(1)
  • Claude Code Kimi K2 环境配置指南 (Windows/macOS/Ubuntu)
  • NumPy库使用教学,简单详细。
  • 一些Avalonia与WPF内容的对应关系和不同用法
  • numpy的详细知识点,简单易懂
  • 【Linux系统】基础IO
  • HTTP 协议常见字段(请求头/响应头)
  • 【初识数据结构】CS61B 中的堆以及堆排序算法
  • 数据库设计mysql篇
  • 第六章 工具调用
  • linux辅助知识(Shell 脚本编程)
  • 基于LangGraph的Open Deep Research架构全解析:从多Agent协作到企业级落地