feat: 添加保护角可视化绘制
This commit is contained in:
2
main.py
2
main.py
@@ -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}")
|
||||
|
||||
@@ -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],
|
||||
|
||||
Reference in New Issue
Block a user