参考:
【使用教程】用傅立叶级数画一个比宇宙更远的地方_哔哩哔哩_bilibili
https://zhuanlan.zhihu.com/p/648064403
几何在线画图工具:GeoGebra [www.geogebra.org/classic]
推荐测试极坐标:
1.菊花图 r=2sin(4θ)
2.心形图 r = 2*(1 + cos(θ))
3. 阿基米德螺旋 r = θ
下面是用HTML写了一个简单的demo,用于观察了解傅立叶圆运行轨迹
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>傅立叶画图研究</title>
</head>
<body>
<h2>傅立叶封闭曲线一笔画</h2>
<!-- 定义画布 -->
<canvas id="myCanvas" width="800" height="800" style="border:1px solid #d3d3d3;"></canvas>
<script>
let draw_angle_curr = [0, 0, 0, 0, 0];
let draw_angle_adder = [0.1, 0.5, 0.2, -0.8, -0.1];
let draw_circle_radius = [150, 80, 30, 20, 12];
function draw_func() {
drawer.clearCanvas();
drawer.drawCircle(400, 400, draw_circle_radius[0], draw_angle_curr[0]);
draw_angle_curr[0] += draw_angle_adder[0];
for (let i = 1; i < draw_angle_curr.length; i++) {
drawer.drawCircle(drawer.x2, drawer.y2, draw_circle_radius[i], draw_angle_curr[i]);
draw_angle_curr[i] += draw_angle_adder[i];
}
drawer.arr.push({ x: drawer.x2, y: drawer.y2 });
drawer.drawTrace();
}
/**
* Canvas 绘图类
*/
class CanvasDrawer {
/**
* 构造函数
* @param {HTMLCanvasElement} canvasElement - 目标 Canvas 元素
*/
constructor(canvasElement) {
this.canvas = canvasElement;
this.ctx = this.canvas.getContext("2d"); // 获取 2D 绘图上下文
this.x2 = 0;
this.y2 = 0;
this.arr = [];
}
/**
* 清空画布
*/
clearCanvas() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
/**
* 绘制数据轨迹
*/
drawTrace() {
this.ctx.beginPath(); // 开始绘制路径
this.ctx.strokeStyle = "red"; // 设置圆的边框颜色
this.ctx.lineWidth = 2; // 设置线条宽度
this.ctx.moveTo(this.arr[0].x, this.arr[0].y); // 移动到起点
for (let i = 1; i < this.arr.length; i++) {
this.ctx.lineTo(this.arr[i].x, this.arr[i].y); // 移动到起点
}
this.ctx.stroke(); // 绘线段
}
/**
* 绘制圆+线段
* @param {number} x - 圆心的 x 坐标
* @param {number} y - 圆心的 y 坐标
* @param {number} radius - 圆的半径
* @param {number} angle - 线段角度
*/
drawCircle(x, y, radius, angle) {
this.ctx.beginPath(); // 开始绘制路径
this.ctx.arc(x, y, radius, 0, 2 * Math.PI); // 绘制圆
this.ctx.strokeStyle = "black"; // 设置圆的边框颜色
this.ctx.lineWidth = 2; // 设置线条宽度
this.ctx.stroke(); // 绘制圆
this.x2 = x + radius * Math.cos(angle); // 终点的 x 坐标
this.y2 = y + radius * Math.sin(angle); // 终点的 y 坐标
this.ctx.beginPath(); // 开始绘制路径
this.ctx.moveTo(x, y); // 移动到起点
this.ctx.lineTo(this.x2, this.y2); // 绘制到终点
this.ctx.strokeStyle = "blue"; // 设置线段颜色
this.ctx.lineWidth = 2; // 设置线条宽度
this.ctx.stroke(); // 绘线段
}
}
// 获取 Canvas 元素
const canvasElement = document.getElementById("myCanvas");
// 创建 CanvasDrawer 实例
const drawer = new CanvasDrawer(canvasElement);
setInterval(draw_func, 100);
</script>
</body>
</html>
运行效果:【只用了5个圆做测试】