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
相关产品推荐
相关产品推荐

