使用canvas(2d)+js实现一个简单的傅里叶级数绘制方波图

先看效果#

查看页面右下角,嘿嘿

简要说明#

  1. 创建具有不同半径与角速度的圆集合;(截图中展现的效果为5个,代码是30个,运行后效果会不同)
Copy
const getCircles = (N = 10) => { const ret = []; for (let i = 0; i < N; i += 1) { ret.push({ r: 100 / (i * 2 + 1), ω: i * 2 + 1, φ: 0 }); } return ret; }; const circles = getCircles(30);
  1. 计算某时刻相应圆的位置与旋转角度,并记录"叶圆端点"坐标值(画出来的形状有点怪啊,卧槽)
Copy
let x = 0; let y = 0; circles.forEach((c) => { drawCircle(ctx, x, y, c); const st = { x, y }; x += c.r * Math.cos((c.ω * idx * Math.PI) / 180); y += c.r * Math.sin((c.ω * idx * Math.PI) / 180); const sp = { x, y }; drawVector(ctx, st, sp); }); points.push(x); points.push(y);

3.将"叶圆端点"坐标集合使用bezier曲线逼近绘制曲线()

Copy
function drawSolve(ctx, data, k = null, color = null) { if (k === null) k = 1; var size = data.length; var last = size - 4; ctx.strokeStyle = color || "#Fff0f0"; ctx.beginPath(); ctx.moveTo(data[0], data[1]); for (var i = 0; i < size - 2; i += 2) { var x0 = i ? data[i - 2] : data[0]; var y0 = i ? data[i - 1] : data[1]; var x1 = data[i + 0]; var y1 = data[i + 1]; var x2 = data[i + 2]; var y2 = data[i + 3]; var x3 = i !== last ? data[i + 4] : x2; var y3 = i !== last ? data[i + 5] : y2; var cp1x = x1 + ((x2 - x0) / 6) * k; var cp1y = y1 + ((y2 - y0) / 6) * k; var cp2x = x2 - ((x3 - x1) / 6) * k; var cp2y = y2 - ((y3 - y1) / 6) * k; ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x2, y2); } ctx.stroke(); }
  1. 方波y值取"叶圆端点"坐标,x值随意;绘制方波图(依旧使用bezier)
Copy
pssine.unshift(y); if (pssine.length > canvas.height * canvas.width) { pssine.pop(); } const pp = []; pssine.forEach((p, i) => { pp.push(i / 2 + 200); pp.push(p); }); drawSolve(ctx, pp, null, "#0000ff");

总结#

大概就实现了此功能;但许多细节没有深究;需要优化;源码:fourier

参考#

一组点怎么平滑地用曲线连接呢?
使用贝塞尔曲线绘制多点连接曲线
Catmull-Rom Spline

posted @   lenkaset  阅读(519)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
CONTENTS