You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

p5.js中使用bezier()与curve()填充凹形时出现填充异常求助

p5.js中贝塞尔/曲线绘制凹形的填充异常问题及解决思路

问题描述

在p5.js里用bezier()或curve()绘制凹多边形时,会出现填充异常的情况。试过手动添加第四条边闭合形状但无效,而且已知endShape(CLOSE)应该能完成闭合操作,问题仍未解决。

核心原因

p5.js默认的填充算法(非零环绕/奇偶规则)处理曲线构成的凹形时,容易因为曲线走向、控制点设置不合理,导致填充区域的判断出错。尤其是曲线弯曲方向和凹面方向冲突时,异常表现会更明显。

解决思路与替代方案

  • 统一控制点顺序:不管是基础顶点还是贝塞尔/曲线的控制点,都保持顺时针或逆时针一致的顺序,乱序会干扰填充算法的区域判断逻辑。
  • 用beginContour()定义嵌套轮廓:对于复杂凹形,先绘制外轮廓,再用beginContour()绘制凹进去的部分(注意反向绘制),endContour()结束后闭合外轮廓,这样填充时能正确识别凹面区域。
  • 曲线转分段直线近似:如果对精度要求不高,把贝塞尔/曲线拆分成多段短直线,用vertex()连接后调用endShape(CLOSE)闭合,直线构成的凹形填充稳定性更高。
  • 切换填充规则:通过fillRule()切换"evenodd"和"nonzero"两种规则,有时候能直接修正填充异常。

代码示例

问题代码(bezier绘制凹形)

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  fill(255, 0, 0);
  beginShape();
  vertex(50, 50);
  bezier(50, 50, 150, 100, 250, 50, 350, 150);
  vertex(350, 350);
  bezier(350, 350, 250, 300, 150, 350, 50, 250);
  endShape(CLOSE);
}

修复示例(用contour处理凹形)

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  fill(255, 0, 0);
  beginShape();
  // 绘制外轮廓
  vertex(50, 50);
  bezier(50, 50, 150, 100, 250, 50, 350, 150);
  vertex(350, 350);
  bezier(350, 350, 250, 300, 150, 350, 50, 250);
  
  // 定义凹面的嵌套轮廓(反向绘制)
  beginContour();
  vertex(200, 100);
  bezier(200, 100, 250, 150, 200, 200, 150, 150);
  endContour();
  
  endShape(CLOSE);
}

内容的提问来源于stack exchange,提问作者Brendan Threewitt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:55:15