在p5.js中计算圆/椭圆弦长时出现异常结果的问题
在p5.js中计算圆/椭圆的弦长
嘿,我来帮你梳理一下在p5.js里计算圆或椭圆范围内弦长的具体实现思路,刚好之前做图形相关项目时折腾过类似的需求!
核心参数与基础原理
先明确你提到的两个关键参数:
values:HSB颜色三元组,这个主要用来后续绘图上色,和弦长计算逻辑关联不大,咱们重点看sizesize:图形的宽高,如果是正圆,那宽高相等,半径r = size / 2;如果是椭圆,那size可以拆成[width, height],对应长半轴a = size[0]/2,短半轴b = size[1]/2
弦长的计算核心是几何定理:
- 对于正圆:已知当前纵坐标
y(相对于圆心的偏移量),半弦长halfChord = sqrt(r² - y²),完整弦长就是2 * halfChord - 对于椭圆:半弦长公式是
halfChord = (a/b) * sqrt(b² - y²),完整弦长同样是2 * halfChord
p5.js代码实现示例
下面给你写个可直接运行的示例,包含正圆和椭圆两种情况的弦长计算:
function setup() { createCanvas(600, 400); colorMode(HSB); // 示例参数:HSB颜色 + 圆/椭圆尺寸 const values = [200, 80, 70]; // 蓝紫色调 const circleSize = 300; // 正圆尺寸 const ellipseSize = [400, 200]; // 椭圆尺寸(宽,高) } function draw() { background(20); const values = [200, 80, 70]; const circleSize = 300; const ellipseSize = [400, 200]; // 绘制正圆并计算每一行的弦长 drawShapeWithChords('circle', circleSize, values, 100, 200); // 绘制椭圆并计算每一行的弦长 drawShapeWithChords('ellipse', ellipseSize, values, 400, 200); } // 通用绘制函数:根据图形类型计算弦长并可视化 function drawShapeWithChords(type, size, hsb, centerX, centerY) { fill(hsb[0], hsb[1], hsb[2], 30); stroke(hsb[0], hsb[1], hsb[2]); strokeWeight(1); // 绘制基础图形 if (type === 'circle') { ellipse(centerX, centerY, size, size); } else if (type === 'ellipse') { ellipse(centerX, centerY, size[0], size[1]); } // 遍历y轴方向的每个点,计算对应弦长 strokeWeight(2); const step = 5; // 遍历步长,越小越精细 let radius, a, b; if (type === 'circle') { radius = size / 2; } else { a = size[0] / 2; b = size[1] / 2; } for (let y = centerY - (type === 'circle' ? radius : b); y <= centerY + (type === 'circle' ? radius : b); y += step) { // 计算当前y相对于圆心的偏移量 const yOffset = y - centerY; let halfChord = 0; // 核心弦长计算逻辑,避免根号内出现负数 if (type === 'circle') { if (Math.abs(yOffset) <= radius) { halfChord = Math.sqrt(radius * radius - yOffset * yOffset); } } else { if (Math.abs(yOffset) <= b) { halfChord = (a / b) * Math.sqrt(b * b - yOffset * yOffset); } } // 绘制当前弦 stroke(hsb[0], hsb[1], hsb[2], 80); line(centerX - halfChord, y, centerX + halfChord, y); // 可选:在弦上标注弦长数值 fill(255); noStroke(); text(Math.round(halfChord * 2), centerX, y); stroke(hsb[0], hsb[1], hsb[2], 80); } }
关键细节提醒
- 边界判断:一定要加
Math.abs(yOffset) <= 半径/短半轴的判断,否则当y超出图形范围时,根号内会出现负数,导致NaN错误 - 椭圆适配:椭圆的弦长公式和圆不同,需要用长半轴和短半轴的比例来修正,别直接套用圆的公式
- 步长控制:
step参数决定了遍历的精细度,数值越小弦越多越密集,根据你的需求调整就行
内容的提问来源于stack exchange,提问作者Dreamy
相关产品推荐
相关产品推荐

