Branch Corners
A branch is drawn on a sheet as a route from node 1 to node 2. BranchPresentation.between() builds that drawing from the two nodes and the corners the route passes through. This page shows how to use it, and how the stored corner lists work when you read them from a file.
Full Example
View the complete code: 11_branch_corners.py
Drawing a Branch with between()
from pyptp.elements.mv.presentations import BranchPresentation
presentation = BranchPresentation.between(node1, node2, sheet_guid, via=[(100, 250), (300, 250)])| Argument | Meaning |
|---|---|
node1, node2 | The branch's nodes. Both need a presentation on the sheet, otherwise ValueError |
sheet_guid | The sheet to draw on |
via | The corners of the route, in order from node 1 to node 2. Leave it out for a straight line |
symbol_segment | The segment that gets the branch symbol and the middle text (see below) |
The ends are placed on the node symbols, so you never repeat the node positions. For a busbar drawn as a line, the end lands on the nearest point of the line (see Clamping Branch Corners).
between() exists on the LV and the MV BranchPresentation. polyline() returns the drawn route as one list, from node 1 to node 2:
presentation.polyline() # [(100, 200), (100, 250), (300, 250), (300, 300)]Example 1: Straight Line
straight = link("straight", node("A", 100, 100), node("B", 300, 100), via=[])link() and node() are small functions in the sample that add a LinkMV with between() and a NodeMV on the sheet. The route is (100,100) → (300,100).
Example 2: A Z with Two Bends
Node C at (100, 200), node D at (300, 300):
bend = link("bend", node("C", 100, 200), node("D", 300, 300), via=[(100, 250), (300, 250)])Path: (100,200) → (100,250) ════ (300,250) ← (300,300)
first_corners: [(100,200), (100,250)] (down from C)second_corners: [(300,300), (300,250)] (up from D)Example 3: Zig-Zag
Node E at (100, 400), node F at (450, 450):
start = node("E", 100, 400)
end = node("F", 450, 450)
zigzag_via = [(150, 400), (200, 350), (250, 350), (300, 400), (350, 400), (375, 410), (400, 420)]
zigzag = link("zigzag", start, end, via=zigzag_via)The branch symbol goes on the segment at the halfway point of the route, here from (250, 350) to (300, 400):
Example 4: Choosing the Symbol Segment
from pyptp.elements.enums import SymbolSegment
on_longest = BranchPresentation.between(start, end, sheet_guid, via=zigzag_via, symbol_segment=SymbolSegment.LONGEST)symbol_segment takes:
| Value | Segment |
|---|---|
SymbolSegment.MIDDLE (default) | The segment at the halfway point of the route |
SymbolSegment.LONGEST | The longest segment, or the first of them on a tie |
An int | The segment with that index, counted from node 1. A negative index counts from node 2, so -1 is the segment that ends at node 2 |
An index outside the route raises ValueError. A bool or any other type raises TypeError.
How the Corners Are Stored
A branch presentation keeps its route as two lists, and these are what you see when you load a file:
| List | Direction | Description |
|---|---|---|
first_corners | From Node1 outward | Polyline starting at Node1 |
second_corners | From Node2 outward | Polyline starting at Node2 |
A connection line joins the last point of each list. That line is the segment with the branch symbol and the middle text, which is why symbol_segment decides where between() splits the route.
Critical Concept
second_corners must start at Node2, not end at it. between() takes care of this for you.
first_corners: polyline starting from Node1, traveling outwardsecond_corners: polyline starting from Node2 (not ending!)The corner lists can also be written by hand. This is Example 1 again:
by_hand = BranchPresentation(
sheet=sheet_guid,
first_corners=[(100, 100)],
second_corners=[(300, 100)],
)Validation
PyPtP validates that corner coordinates align with node positions. See Branch Corner Validation for details on the grid-based tolerance system.
Next Steps
- Clamping Branch Corners for routes whose end points are a few pixels off the nodes
- 12_clamp_branch_corners.py for the sample behind it