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

Canvas绘制Deltoid曲线失败求排查:公式与维基一致却无法运行

问题分析与修复方案

嘿,我一眼就揪出问题所在啦——你把Deltoid曲线参数方程里的余弦/正弦函数和反余弦/反正弦函数搞混了!维基百科上的Deltoid参数方程用的是cos()和sin(),但你写成了acos()和asin(),这完全不是一回事儿,这就是代码跑不起来的核心原因。

先给你明确Deltoid(三尖瓣线)的正确参数方程(当a > b时):

x(t) = (a - b)cos(t) + bcos( ((a/b) - 1)t )
y(t) = (a - b)sin(t) - bsin( ((a/b) - 1)t )

再拆解下你代码里的其他小问题:

  • 初始的nx和ny设为0,会导致第一次绘制从(0,0)开始,留下多余的线条,应该初始化为t=0时的坐标
  • 没有限制t的范围,Deltoid是周期性曲线,超过周期后会重复绘制,建议添加终止条件
  • 步长0.1偏大,绘制出来的曲线会有明显锯齿

下面是修正后的完整代码:

const ctx = document.getElementById("myCanvas").getContext("2d");
ctx.translate(150, 75); // 把原点移到画布中心区域,方便观察曲线
const a = 100;
const b = 80;
let t = 0;

// 修正后的Deltoid参数方程
function x(t) {
  const ratio = (a / b) - 1;
  return (a - b) * Math.cos(t) + b * Math.cos(ratio * t);
}
function y(t) {
  const ratio = (a / b) - 1;
  return (a - b) * Math.sin(t) - b * Math.sin(ratio * t);
}

// 初始化起点为t=0时的坐标,避免多余线条
let nx = x(t);
let ny = y(t);

function animate() {
  t += 0.01; // 减小步长让曲线更平滑
  const newX = x(t);
  const newY = y(t);
  
  ctx.beginPath();
  ctx.moveTo(nx, ny);
  ctx.lineTo(newX, newY);
  ctx.stroke();
  
  nx = newX;
  ny = newY;
  
  // 计算Deltoid的周期,达到周期后停止动画避免重复绘制
  const gcd = (num1, num2) => num2 === 0 ? num1 : gcd(num2, num1 % num2);
  const period = 2 * Math.PI * (b / gcd(a, b));
  if (t < period) {
    requestAnimationFrame(animate);
  }
}
animate();

替换后运行代码,就能看到标准的Deltoid曲线啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:33:49