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

来源:博客园 2023-08-14 12:44:58


(资料图片仅供参考)

先看效果

查看页面右下角,嘿嘿

简要说明创建具有不同半径与角速度的圆集合;(截图中展现的效果为5个,代码是30个,运行后效果会不同)
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);
计算某时刻相应圆的位置与旋转角度,并记录"叶圆端点"坐标值(画出来的形状有点怪啊,卧槽)
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曲线逼近绘制曲线()

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();}
方波y值取"叶圆端点"坐标,x值随意;绘制方波图(依旧使用bezier)
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

上一篇 : iphone有锁和无锁辨别(iphone有锁和无锁的区别)

下一篇 : 最后一页

相关推荐

推荐阅读