使用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

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYY87gHp' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片