已知两点及指定角度,求不等边三角形临时点C的JS实现问题
问题分析
已知点A、B的坐标及AB长度,需要在与B**同一X竖线(x坐标等于B的x)**上绘制临时点C,使得线段AC与指定角度相符。原代码错误地从B点出发按AB角度偏移计算C,不符合C的位置限制,导致角度超出±22度时失效。
几何推导(核心解法)
因为C必须在B的同一竖线(x=Bx)上,所以C的坐标固定为(Bx, Cy),只需求解Cy即可:
若指定角度为AC与X轴正方向的夹角θ(单位:弧度),AC的斜率满足:
tanθ = (Cy - Ay) / (Bx - Ax)
变形得:Cy = Ay + (Bx - Ax) * Math.tan(θ)若指定角度为AC与AB的夹角θ,则用向量夹角公式推导:
向量AB = (Bx - Ax, By - Ay),向量AC = (Bx - Ax, Cy - Ay)
夹角余弦公式:cosθ = [ (Bx-Ax)² + (By-Ay)(Cy-Ay) ] / ( AB_length * √[(Bx-Ax)² + (Cy-Ay)²] )整理后是关于Cy的一元二次方程,求解后会得到两个可能的Cy值(对应B点上下两个位置)。
修正后的代码实现
场景1:AC与X轴正方向夹角为指定角度
const plotTempPoint = (points, deg) => { const angle = deg * (Math.PI / 180); // 角度转弧度 const a = points[0].getBoundingClientRect(); const b = points[1].getBoundingClientRect(); // 强制C点x坐标与B一致,通过角度公式计算y const cX = b.x; const cY = a.y + (cX - a.x) * Math.tan(angle); // 创建并渲染临时点 const coords = document.querySelector('.coords'); const temp = document.createElement("div"); temp.className = 'center-point temp'; temp.style.top = `${cY}px`; temp.style.left = `${cX}px`; // 补全x坐标定位,原代码遗漏 coords.appendChild(temp); return cY; };
场景2:AC与AB的夹角为指定角度
const plotTempPoint = (points, deg, abLength) => { const angle = deg * (Math.PI / 180); const a = points[0].getBoundingClientRect(); const b = points[1].getBoundingClientRect(); const Ax = a.x, Ay = a.y; const Bx = b.x, By = b.y; const dx = Bx - Ax; const dyAB = By - Ay; const cosTheta = Math.cos(angle); // 构造一元二次方程:A*Cy² + B*Cy + C = 0 const A = 1 - (cosTheta ** 2); const B = 2 * (Ay * (cosTheta ** 2) - dyAB * cosTheta ** 2 - Ay); const C = (Ay ** 2) * cosTheta ** 2 + dx ** 2 + dyAB ** 2 * cosTheta ** 2 - 2 * Ay * dyAB * cosTheta ** 2 - abLength ** 2 * cosTheta ** 2; // 判别式判断是否有解 const discriminant = B ** 2 - 4 * A * C; if (discriminant < 0) { console.error('无解:该角度下不存在符合条件的点C'); return null; } // 计算两个解,对应B点上下两个位置 const Cy1 = (-B + Math.sqrt(discriminant)) / (2 * A); const Cy2 = (-B - Math.sqrt(discriminant)) / (2 * A); // 选择其中一个解(可根据需求切换为Cy2) const selectedCy = Cy1; // 渲染临时点 const coords = document.querySelector('.coords'); const temp = document.createElement("div"); temp.className = 'center-point temp'; temp.style.top = `${selectedCy}px`; temp.style.left = `${Bx}px`; coords.appendChild(temp); return selectedCy; };
关键修正点
- 强制C点x坐标与B一致,严格满足“同一竖线”的位置要求
- 用几何公式直接推导Cy,摆脱原代码的角度偏移逻辑限制
- 补全DOM元素的
left样式,修正原代码的定位缺失问题
内容的提问来源于stack exchange,提问作者Ty S
相关产品推荐
相关产品推荐

