feat: 添加保护角可视化绘制

This commit is contained in:
dmy
2026-03-04 11:08:20 +08:00
parent fb3276d49d
commit 3498650f5f
2 changed files with 83 additions and 1 deletions

View File

@@ -157,7 +157,7 @@ def run_egm(para: Parameter, animation=None) -> dict:
* 180
/ math.pi
) # 挂点处保护角
logger.info(f"挂点处保护角{shield_angle_at_avg_height:.3f}°")
logger.info(f"地线保护角{shield_angle_at_avg_height:.2f}°")
logger.debug(f"最低相防护标识{rg_type}g表示地面c表示下导线")
rated_voltage = para.rated_voltage
logger.info(f"交、直流标识{para.ac_or_dc}")

View File

@@ -210,6 +210,9 @@ const draw = () => {
// 绘制导线和地线挂点
drawWirePoints(range)
// 绘制保护角
drawShieldingAngle(range)
}
// 绘制导线和地线挂点
@@ -295,6 +298,85 @@ const drawGround = (range: ReturnType<typeof calculateRange>) => {
ctx.stroke()
}
// 绘制保护角
const drawShieldingAngle = (range: ReturnType<typeof calculateRange>) => {
if (!ctx || props.hArm.length < 2) return
const actualHeights = calculateActualHeights()
const gwX = Number(props.gcX[0]) || 0
const gwY = actualHeights[0]
const cwX = Number(props.gcX[1]) || 0
const cwY = actualHeights[1]
const gwCanvasX = toCanvasX(gwX, range)
const gwCanvasY = toCanvasY(gwY, range)
const cwCanvasX = toCanvasX(cwX, range)
const cwCanvasY = toCanvasY(cwY, range)
// 计算保护角(地线与导线连线与垂直线的夹角)
const dx = cwX - gwX
const dy = gwY - cwY
const shieldingAngle = Math.atan2(dx, dy) * (180 / Math.PI)
// 绘制从地线到导线1的虚线
ctx.strokeStyle = '#9C27B0'
ctx.lineWidth = 2
ctx.setLineDash([6, 4])
ctx.beginPath()
ctx.moveTo(gwCanvasX, gwCanvasY)
ctx.lineTo(cwCanvasX, cwCanvasY)
ctx.stroke()
ctx.setLineDash([])
// // 绘制垂直参考线(从地线向下)
// ctx.strokeStyle = 'rgba(156, 39, 176, 0.3)'
// ctx.lineWidth = 1
// ctx.setLineDash([4, 4])
// ctx.beginPath()
// ctx.moveTo(gwCanvasX, gwCanvasY)
// ctx.lineTo(gwCanvasX, gwCanvasY + 80)
// ctx.stroke()
// ctx.setLineDash([])
// // 绘制角度弧
// const arcRadius = 30
// const verticalAngle = Math.PI / 2 // 向下
// const lineAngle = Math.atan2(cwCanvasY - gwCanvasY, cwCanvasX - gwCanvasX)
ctx.strokeStyle = '#9C27B0'
ctx.lineWidth = 1.5
ctx.beginPath()
// if (dx >= 0) {
// ctx.arc(gwCanvasX, gwCanvasY, arcRadius, Math.PI / 2, lineAngle, true)
// } else {
// ctx.arc(gwCanvasX, gwCanvasY, arcRadius, lineAngle, Math.PI / 2, false)
// }
// ctx.stroke()
// 计算标注位置(在线的右侧)
const midX = (gwCanvasX + cwCanvasX) / 2
const midY = (gwCanvasY + cwCanvasY) / 2
const labelOffsetX = dx >= 0 ? -45 : 45
const labelOffsetY = 0
// 绘制引线
ctx.strokeStyle = '#9C27B0'
ctx.lineWidth = 1
ctx.beginPath()
ctx.moveTo(midX, midY)
ctx.lineTo(midX + labelOffsetX, midY + labelOffsetY)
ctx.stroke()
// 绘制标注文字
const labelText = `保护角: ${Math.abs(shieldingAngle).toFixed(2)}°`
ctx.font = 'bold 12px Arial'
// 绘制标注文字
ctx.fillStyle = '#9C27B0'
ctx.textAlign = 'left'
ctx.fillText(labelText, midX + labelOffsetX, midY + labelOffsetY)
}
// 监听参数变化
watch(
() => [props.hArm, props.gcX, props.hCSag, props.hGSag, props.stringCLen, props.stringGLen, props.groundAngels],