Files
eletrtcity/experiment2/image_code/exp1_circuit.py
T
2026-04-27 14:51:49 +08:00

122 lines
3.8 KiB
Python

import os
from pathlib import Path
import sys
os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib")
import schemdraw
import schemdraw.elements as elm
from schemdraw.segments import SegmentText
FONT_NAME = "STIXGeneral"
BG_COLOR = "white"
DEFAULT_OUTPUT = Path(__file__).resolve().parent.parent / "image" / "target_circuit.svg"
def add_text(
drawing,
position,
text,
*,
fontsize=18,
rotation=0,
align=("center", "center"),
):
element = elm.Element().at(position).anchor("center").hold()
element.anchors["center"] = (0, 0)
element.segments.append(
SegmentText(
(0, 0),
text,
rotation=rotation,
align=align,
fontsize=fontsize,
font=FONT_NAME,
)
)
drawing.add(element)
def draw_circuit(save_path=DEFAULT_OUTPUT):
save_path = Path(save_path)
save_path.parent.mkdir(parents=True, exist_ok=True)
with schemdraw.Drawing(show=False) as d:
d.config(
unit=1.0,
fontsize=18,
font=FONT_NAME,
lw=2.2,
margin=0.2,
bgcolor=BG_COLOR,
)
# 关键节点,整体布局按参考图重排。
a_node = (1.4, 4.0)
top_node = (5.2, 6.6)
bottom_node = (5.2, 1.9)
right_node = (9.3, 4.0)
bottom_left = (1.4, 0.8)
top_term = (10.9, 4.0)
bottom_term = (10.9, 1.9)
source_start = (4.8, 0.8)
source_len = 1.6
source_end = (source_start[0] + source_len, source_start[1])
# 主电路元件
d.add(elm.ResistorIEC().at(a_node).to(top_node).hold())
d.add(elm.ResistorIEC().at(a_node).to(bottom_node).hold())
d.add(elm.ResistorIEC().at(top_node).to(right_node).hold())
d.add(elm.Source().at(bottom_node).up(top_node[1] - bottom_node[1]).hold())
d.add(elm.ResistorIEC().at(bottom_left).up(a_node[1] - bottom_left[1]).hold())
# 下方电压源支路
d.add(elm.Line().at(bottom_left).right(source_start[0] - bottom_left[0]).hold())
d.add(elm.Source().at(source_start).right(source_len).hold())
d.add(elm.Line().at(source_end).right(right_node[0] - source_end[0]).hold())
# 右侧导线与端子
d.add(elm.Line().at(right_node).right(top_term[0] - right_node[0]).hold())
d.add(elm.Line().at(right_node).down(right_node[1] - source_start[1]).hold())
d.add(elm.Line().at(bottom_node).right(bottom_term[0] - bottom_node[0]).hold())
# 电流源符号细节:空心圆、内部横线、外部向上箭头。
source_center_y = (top_node[1] + bottom_node[1]) / 2
d.add(elm.Line().at((4.74, source_center_y)).right(0.92).hold())
d.add(elm.Arrow().at((5.2, 4.9)).up(1.0).hold())
# 电压源符号细节:圆内水平线。
d.add(elm.Line().at(source_start).right(source_len).hold())
# 节点和开口端子
for point in [a_node, top_node, bottom_node, right_node]:
d.add(elm.Dot(radius=0.085).at(point).hold())
d.add(elm.Dot(open=True, radius=0.1).at(top_term).hold())
d.add(elm.Dot(open=True, radius=0.1).at(bottom_term).hold())
# 文本标注
add_text(d, (2.35, 5.18), r"$R_1$", fontsize=19)
add_text(d, (8.78, 5.12), r"$R_3$", fontsize=19)
add_text(d, (2.42, 2.62), r"$R_2$", fontsize=19)
add_text(d, (0.55, 1.28), r"$R_4$", fontsize=19)
add_text(d, (6.42, 4.82), r"$I_S$", fontsize=19)
add_text(d, (4.3, 0.36), "-", fontsize=21)
add_text(d, (6.98, 0.36), "+", fontsize=21)
add_text(d, (4.78, -0.05), r"$U_S$", fontsize=19)
d.save(str(save_path), transparent=False)
print(f"saved to: {save_path}")
if __name__ == "__main__":
output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
draw_circuit(output_path)