如何使用JavaScript计算圆弧的中点坐标?
计算圆弧中点M的坐标方法
要计算圆弧中点M的坐标,核心是利用圆心到A、B的向量的夹角平分线方向,结合半径推导M点位置,以下是正确的思路和实现:
问题分析
你的原代码存在几个关键错误:
- 角度计算时误用了
Math.atan且分子分母写错:Math.atan(a.y / a.y)完全错误,应该计算A相对于圆心C的向量角度,且必须用Math.atan2(y, x)来处理所有象限的角度,避免符号错误。 - 最后对x坐标的符号处理逻辑完全错误,中点坐标应该是圆心坐标加上“半径×中点方向向量”,不需要单独判断符号。
正确实现方法
方法一:向量法(推荐,无需处理角度象限)
通过向量的平均方向直接推导中点,避免角度计算的麻烦:
var a = {x: x1, y: y1}; var b = {x: x2, y: y2}; var c = {x: cx, y: cy}; var radius = r; // 计算A、B相对于圆心C的向量 const vecA = { x: a.x - c.x, y: a.y - c.y }; const vecB = { x: b.x - c.x, y: b.y - c.y }; // 将两个向量转换为单位向量(长度为1) const lenA = Math.sqrt(vecA.x ** 2 + vecA.y ** 2); const lenB = Math.sqrt(vecB.x ** 2 + vecB.y ** 2); const unitA = { x: vecA.x / lenA, y: vecA.y / lenA }; const unitB = { x: vecB.x / lenB, y: vecB.y / lenB }; // 计算两个单位向量的平均,再归一化得到中点方向的单位向量 const midVec = { x: unitA.x + unitB.x, y: unitA.y + unitB.y }; const midLen = Math.sqrt(midVec.x ** 2 + midVec.y ** 2); const unitMid = { x: midVec.x / midLen, y: midVec.y / midLen }; // 计算M点坐标:圆心 + 半径×中点方向向量 const m = { x: c.x + radius * unitMid.x, y: c.y + radius * unitMid.y }; writeBlock(c.x, c.y); writeBlock(m.x, m.y, x1, y1, x2, y2);
方法二:角度法(修正你的原思路)
如果坚持用角度计算,必须用Math.atan2处理象限,再计算平均角度:
var a = {x: x1, y: y1}; var b = {x: x2, y: y2}; var c = {x: cx, y: cy}; var radius = r; // 计算A、B相对于圆心C的向量的角度(atan2(y, x) 返回[-π, π]的角度) const theta1 = Math.atan2(a.y - c.y, a.x - c.x); const theta2 = Math.atan2(b.y - c.y, b.x - c.x); // 计算平均角度:默认取劣弧中点,若要取优弧中点,改为(theta1 + theta2 + 2*Math.PI)/2再取模2π let theta = (theta1 + theta2) / 2; // 确保角度在[0, 2π]范围内(可选) theta = theta < 0 ? theta + 2 * Math.PI : theta; // 计算M点相对于圆心的坐标,再加上圆心坐标得到最终位置 const m = { x: c.x + radius * Math.cos(theta), y: c.y + radius * Math.sin(theta) }; writeBlock(c.x, c.y); writeBlock(m.x, m.y, x1, y1, x2, y2);
关键说明
- 向量法无需考虑角度象限问题,更鲁棒,推荐使用。
- 角度法需要注意圆弧是劣弧还是优弧:默认代码计算的是劣弧中点,如果要计算优弧中点,需要调整角度计算方式。
内容的提问来源于stack exchange,提问作者piotkro
相关产品推荐
相关产品推荐

