p5.js绘制椭圆内随机点:移植原生Canvas代码后缩放异常求助
问题根源:椭圆参数定义差异
原生Canvas的ctx.ellipse(x, y, radiusX, radiusY, ...)直接接受半长轴、半短轴作为参数;而p5.js的ellipse(x, y, width, height)接受的是椭圆的完整宽度、高度(即半长轴=width/2,半短轴=height/2)。如果移植时没注意这个差异,直接把p5.js里的width/height当作半轴来计算随机点,就会出现缩放比例异常。
修正步骤
1. 统一椭圆参数逻辑
在p5.js中,先明确椭圆的半轴长度:
const cx = 200; // 椭圆中心x const cy = 200; // 椭圆中心y const ellipseWidth = 300; // p5.js椭圆宽度 const ellipseHeight = 150; // p5.js椭圆高度 const rx = ellipseWidth / 2; // 半长轴 const ry = ellipseHeight / 2; // 半短轴
2. 正确生成椭圆内随机点
沿用原生的极坐标方法(避免点聚集在中心),用半轴长度计算点坐标:
function generateEllipsePoint(cx, cy, rx, ry) { const r = sqrt(random()); // 关键:用sqrt避免点集中在中心 const theta = random(TWO_PI); // p5.js的TWO_PI等价于2*Math.PI const x = cx + r * rx * cos(theta); const y = cy + r * ry * sin(theta); return createVector(x, y); }
3. 完整p5.js示例
let cx, cy, ellipseWidth, ellipseHeight, rx, ry; function setup() { createCanvas(400, 400); cx = width / 2; cy = height / 2; ellipseWidth = 300; ellipseHeight = 150; rx = ellipseWidth / 2; ry = ellipseHeight / 2; noLoop(); } function draw() { background(240); // 绘制椭圆 stroke(0); noFill(); ellipse(cx, cy, ellipseWidth, ellipseHeight); // 生成并绘制随机点 fill(255, 0, 0); noStroke(); for (let i = 0; i < 1000; i++) { let p = generateEllipsePoint(cx, cy, rx, ry); ellipse(p.x, p.y, 3, 3); } } function generateEllipsePoint(cx, cy, rx, ry) { const r = sqrt(random()); const theta = random(TWO_PI); const x = cx + r * rx * cos(theta); const y = cy + r * ry * sin(theta); return createVector(x, y); }
额外注意点
- 优先用极坐标方法生成点,不要用「矩形内随机点再筛选」的方式(效率低且易因椭圆方程写错导致异常)
- 确保p5.js的
ellipseMode为默认的CENTER,如果改成CORNER,需重新计算椭圆中心坐标
内容的提问来源于stack exchange,提问作者Daveh0
相关产品推荐
相关产品推荐

